00001
00002
00003 import sys
00004 try:
00005 from ROOT import *
00006 except:
00007 print "ERROR: Cannot import ROOT!"
00008 print "Make sure you are in a CMSSW release area, and have executed 'cmsenv'."
00009 sys.exit()
00010 from urllib import urlopen
00011 import sys
00012 from Tkinter import *
00013 import os
00014 import string
00015 from array import array
00016
00017
00018 def convertID(ID):
00019 try:
00020 id=int(ID,16)
00021 eta=(id>>7)&0x3f
00022 if (id&0x2000==0):
00023 eta=eta*-1
00024 phi=id&0x7f
00025 depth=(id>>14)&0x7
00026 subdet=(id>>25)&0x7
00027 subdetmap={1:"HB",2:"HE",3:"HO",4:"HF"}
00028 if (subdet in subdetmap.keys()):
00029 subdet=subdetmap[subdet]
00030 else:
00031 subdet="Unknown"
00032 name="%s(%i,%i,%i)"%(subdet,eta,phi,depth)
00033 except:
00034 name="???"
00035 return name
00036
00037 def calcDetID(ID):
00038 ''' expect ID in form <subdet> (eta,phi,depth) '''
00039 ID=string.replace(ID,","," ")
00040 ID=string.replace(ID,")"," ")
00041 ID=string.replace(ID,"("," ")
00042 ID=string.split(ID)
00043 subdetmap={"HB":1,"HE":2,"HO":3,"HF":4}
00044 subdet=ID[0]
00045 if subdet not in subdetmap.keys():
00046 print "ERROR in calcDetID -- can't ID subdet '%s'"%subdet
00047 return
00048 subdet=subdetmap[subdet]
00049 eta=string.atoi(ID[1])
00050 phi=string.atoi(ID[2])
00051 depth=string.atoi(ID[3])
00052 etaplus=True
00053 if (eta<0):
00054 eta=abs(eta)
00055 etaplus=False
00056
00057 detid=4<<28
00058 detid=detid|((subdet&0x7)<<25)
00059 detid=detid|((depth&0x7)<<14)
00060 detid=detid|((eta&0x3f)<<7)
00061 if (etaplus):
00062 detid=detid|(0x2000)
00063 detid=detid|(phi&0x7f)
00064 name="%x"%detid
00065 name=string.upper(name)
00066 return name
00067
00068
00069
00070 class CellStat:
00071
00072 def __init__(self,ID=None):
00073 self.ID=ID
00074 self.IDstring=None
00075 self.eta=None
00076 self.phi=None
00077 self.depth=None
00078 self.subdet=None
00079 self.subdetmap={1:"HB",2:"HE",3:"HO",4:"HF"}
00080 self.parseID()
00081
00082 self.Alwayshot=False
00083 self.Alwaysdead=False
00084
00085 self.status={}
00086 return
00087
00088
00089 def Dead(self,run):
00090 return ((self.status[run]>>4)&0x1)
00091
00092 def Hot(self,run):
00093 return ((self.status[run]>>5)&0x1)
00094
00095 def AlwaysHot(self):
00096 count=0
00097 hot=0
00098 for i in self.status.keys():
00099 if (self.status[i]&0x1==0):
00100 count=count+1
00101 if ((self.status[i]>>5)&0x1):
00102 hot=hot+1
00103
00104 if (count>0 and hot>=0.90*count):
00105 self.Alwayshot=True
00106 return self.Alwayshot
00107
00108 def AlwaysDead(self):
00109 count=0
00110 dead=0
00111 for i in self.status.keys():
00112
00113 if (self.status[i]&0x1==0):
00114 count=count+1
00115 if ((self.status[i]>>4)&0x1):
00116 dead=dead+1
00117
00118
00119 if (count>0 and dead>=0.90*count):
00120 self.Alwaysdead=True
00121 return self.Alwaysdead
00122
00123 def read(self,run,text,hot=False,dead=False):
00124 temp=string.split(text)
00125 try:
00126 value=string.atoi(temp[4])
00127 ID=temp[5]
00128
00129 except:
00130 print "Could not parse line '%s'"%text
00131 return
00132 if (self.ID==None):
00133 self.ID=ID
00134 self.parseID()
00135 elif (self.ID!=ID):
00136 print "Error, ID value mismatch"
00137 return
00138 if (hot):
00139 value=value*16
00140 elif (dead):
00141 value=value*32
00142 if run in self.status.keys():
00143 self.status[run]=(self.status[run]&value)
00144 else:
00145 self.status[run]=value
00146 return
00147
00148 def parseID(self):
00149 id=int(self.ID,16)
00150 eta=(id>>7)&0x3f
00151 if (id&0x2000==0):
00152 eta=eta*-1
00153 phi=id&0x7f
00154 depth=(id>>14)&0x7
00155 subdet=(id>>25)&0x7
00156 if (subdet in self.subdetmap.keys()):
00157 subdet=self.subdetmap[subdet]
00158 else:
00159 subdet="Unknown"
00160 name="%s(%i,%i,%i)"%(subdet,eta,phi,depth)
00161 self.eta=eta
00162 self.phi=phi
00163 self.depth=depth
00164 self.subdet=subdet
00165 self.IDstring=name
00166 return
00167
00168
00169
00170 class RunStatusGui:
00171
00172 def __init__(self,parent=None,debug=False):
00173
00174 self.debug=debug
00175 self.Cells={}
00176 self.Runs=[]
00177 self.HotCellList=[]
00178 self.DeadCellList=[]
00179 self.AlwaysHotList=[]
00180 self.AlwaysDeadList=[]
00181
00182
00183 if (parent==None):
00184 self.root=Tk()
00185 else:
00186 self.root=parent
00187
00188 self.root.title("Bad Cell Checker")
00189
00190
00191 self.screenwidth=self.root.winfo_screenwidth()
00192 self.screenheight=self.root.winfo_screenheight()
00193
00194 self.canwidth=700
00195 self.canheight=500
00196 if (self.screenwidth<1000):
00197 self.canwidth=500
00198 if (self.screenheight<800):
00199 self.canheight=350
00200
00201
00202 self.webname=StringVar()
00203 self.startrun=IntVar()
00204 self.endrun=IntVar()
00205 self.CellID=StringVar()
00206
00207 self.root.columnconfigure(0,weight=1)
00208 row=0
00209 self.bg="grey80"
00210 self.MenuFrame=Frame(self.root,
00211 bg=self.bg)
00212 self.MenuFrame.grid(row=row,
00213 column=0,
00214 sticky=EW)
00215
00216 row=row+1
00217 self.WebFrame=Frame(self.root,
00218 bg=self.bg)
00219 self.WebFrame.grid(row=row,
00220 column=0,
00221 sticky=EW)
00222 row=row+1
00223 self.RunRangeFrame=Frame(self.root,
00224 bg=self.bg)
00225 self.RunRangeFrame.grid(row=row,
00226 column=0,
00227 sticky=EW)
00228
00229 row=row+1
00230 self.MainFrame=Frame(self.root,
00231 bg=self.bg)
00232 self.MainFrame.grid(row=row,
00233 column=0,
00234 sticky=NSEW)
00235 self.root.rowconfigure(row,weight=1)
00236 row=row+1
00237 self.CommentFrame=Frame(self.root,
00238 bg=self.bg)
00239 self.CommentFrame.grid(row=row,
00240 column=0,
00241 sticky=EW)
00242
00243
00244
00245 self.makeCommentFrame()
00246 self.makeWebFrame()
00247 self.makeRunRangeFrame()
00248 self.makeMainFrame()
00249
00250 return
00251
00252 def makeWebFrame(self):
00253 ''' Creates labels and entries for setting web page where cell status is kept '''
00254
00255 self.webname.set('httpss://cms-project-hcal-dqm.web.cern.ch/cms-project-hcal-dqm/data/dqm/')
00256 Label(self.WebFrame,
00257 text="Web Address: ",
00258 bg=self.bg).grid(row=0,column=0)
00259
00260 self.WebFrame.columnconfigure(1,weight=1)
00261 self.webEntry=Entry(self.WebFrame,
00262 bg="black",
00263 foreground="white",
00264 textvar=self.webname)
00265 self.webEntry.grid(row=0,column=1,sticky=EW)
00266 return
00267
00268 def makeRunRangeFrame(self):
00269 ''' Creates labels and entries that allow user to search over given run ranges '''
00270
00271 self.startrun.set(70362)
00272 self.endrun.set(70363)
00273
00274 Label(self.RunRangeFrame,
00275 text="Search Runs From: ",
00276 bg=self.bg).grid(row=0,column=0)
00277 self.startEntry=Entry(self.RunRangeFrame,
00278 bg="black",
00279 foreground="white",
00280 textvar=self.startrun)
00281 self.RunRangeFrame.columnconfigure(1,weight=1)
00282 self.startEntry.grid(row=0,column=1,
00283 sticky=EW)
00284 Label(self.RunRangeFrame,
00285 text = "to ",
00286 width=10,
00287 bg=self.bg).grid(row=0, column=2)
00288 self.endEntry=Entry(self.RunRangeFrame,
00289 bg="black",
00290 foreground="white",
00291 textvar=self.endrun)
00292 self.RunRangeFrame.columnconfigure(3,weight=1)
00293 self.endEntry.grid(row=0,column=3,
00294 sticky=EW)
00295 runsubframe=Frame(self.RunRangeFrame,
00296 bg=self.bg)
00297 runsubframe.grid(row=1,column=0,columnspan=4,sticky=EW)
00298 self.TestButton = Button(runsubframe,
00299 height=2,
00300 bg="white",
00301 fg="black",
00302 text="Read Status from Web",
00303 command = lambda x=self:x.GetInfo())
00304 self.TestButton.grid(row=0,column=0,columnspan=3)
00305 return
00306
00307 def makeMainFrame(self):
00308 ''' Create subframes for main frame.'''
00309 self.ChooserFrame=Frame(self.MainFrame,bg=self.bg)
00310 self.PicFrame=Frame(self.MainFrame,bg=self.bg)
00311 self.DisplayFrame=Frame(self.MainFrame,bg=self.bg)
00312
00313 self.ChooserFrame.grid(row=0,column=0,sticky=NS)
00314 self.PicFrame.grid(row=0, column=1,sticky=NSEW)
00315 self.DisplayFrame.grid(row=0, column=2,sticky=NS)
00316 self.MainFrame.rowconfigure(0,weight=1)
00317 self.MainFrame.columnconfigure(1,weight=1)
00318
00319 self.makeChooserFrame()
00320 self.makePicFrame()
00321 self.makeDisplayFrame()
00322 return
00323
00324
00325 def makeChooserFrame(self):
00326 ''' Provide entries to choose a cell to display.'''
00327 self.ShowAll=Button(self.ChooserFrame,
00328 text="Back to\nCells vs. Time\n plot",
00329 bg="white",
00330 foreground="black",
00331 command=lambda x=self:x.DrawCells())
00332 self.ShowAll.grid(row=0,column=1,pady=50,sticky=EW)
00333 Label(self.ChooserFrame,
00334 text="Choose Cell:",
00335 bg=self.bg).grid(row=1,column=0,columnspan=2)
00336 Label(self.ChooserFrame,
00337 text="Cell ID:",
00338 bg=self.bg).grid(row=2,column=0)
00339 self.ChooseCells=Entry(self.ChooserFrame,
00340 textvar=self.CellID,
00341 bg="white",
00342 foreground="black"
00343 )
00344 self.ChooseCells.bind('<Return>',lambda event:self.DrawCellStatus())
00345
00346 self.ChooseCells.grid(row=2,column=1)
00347 return
00348
00349 def makePicFrame(self):
00350 self.PicLabel=Label(self.PicFrame)
00351 if os.path.isfile("badcelldisplay_file.gif"):
00352 GUIimage=PhotoImage(file="badcelldisplay_file.gif")
00353 else:
00354 GUIimage=PhotoImage(width=self.canwidth, height=self.canheight)
00355 self.PicLabel.image=GUIimage
00356 self.PicLabel.configure(image=GUIimage)
00357 self.PicLabel.update()
00358
00359 print self.PicLabel['width']
00360 self.PicFrame.rowconfigure(0,weight=1)
00361 self.PicFrame.columnconfigure(0,weight=1)
00362 self.PicLabel.grid(row=0,column=0,sticky=NSEW)
00363 return
00364
00365 def makeDisplayFrame(self):
00366 for i in range(0,4):
00367 self.DisplayFrame.rowconfigure(i,weight=1)
00368 self.HotButton=Button(self.DisplayFrame,
00369 text="List Hot Cells",
00370 height=2,
00371 width=20,
00372 bg="white",
00373 fg="black",
00374 command = lambda x=self:x.printCellList(x.HotCellList))
00375 self.HotButton.grid(row=0,column=0)
00376 self.AlwaysHotButton=Button(self.DisplayFrame,
00377 text="List Always\nHot Cells",
00378 height=2,
00379 width=20,
00380 bg="white",
00381 fg="black",
00382 command = lambda x=self:x.printCellList(x.AlwaysHotList))
00383 self.AlwaysHotButton.grid(row=1,column=0)
00384 self.DeadButton=Button(self.DisplayFrame,
00385 text="List Dead Cells",
00386 height=2,
00387 width=20,
00388 bg="white",
00389 fg="black",
00390 command = lambda x=self:x.printCellList(x.DeadCellList) )
00391 self.DeadButton.grid(row=2,column=0)
00392 self.AlwaysDeadButton=Button(self.DisplayFrame,
00393 text="List Always\nDead Cells",
00394 height=2,
00395 width=20,
00396 bg="white",
00397 fg="black",
00398 command = lambda x=self:x.printCellList(x.AlwaysDeadList) )
00399 self.AlwaysDeadButton.grid(row=3,column=0)
00400 return
00401
00402 def makeCommentFrame(self):
00403 ''' Creates comment label.'''
00404 self.commentLabel=Label(self.CommentFrame,
00405 text="Hcal Cell Status Checker",
00406 bg=self.bg)
00407 self.CommentFrame.columnconfigure(0,weight=1)
00408 self.commentLabel.grid(row=0,column=0,
00409 sticky=EW)
00410 return
00411
00412 def GetInfo(self):
00413
00414 self.Cells={}
00415 self.Runs=[]
00416 self.Print("Searching web page for files...")
00417 try:
00418 www=self.webname.get()
00419 out=urlopen(www).readlines()
00420 except IOError:
00421 if not (www.startswith("https://")):
00422 try:
00423 www="https://"+www
00424 self.webname.set(www)
00425 out=urlopen(www).readlines()
00426 except:
00427 self.Print("ERROR - Could not read web page '%s'"%www)
00428 return
00429
00430 self.Print("Reading from %s"%www)
00431 statfiles={}
00432
00433 for i in out:
00434 if string.find(i,".txt")>-1:
00435 try:
00436 temp=string.split(i,'"')
00437 for z in temp:
00438 if (string.strip(z)).endswith(".txt") and (string.upper(string.strip(z))).startswith("HCAL"):
00439 temp=z
00440 break
00441 if (string.find(string.upper(temp),"HCAL")>-1):
00442 run=string.split(temp,"_")[1]
00443 if (run.startswith("run")):
00444 run=run[3:]
00445 run=string.split(run,".txt")[0]
00446 run=string.atoi(run)
00447 if (run>=self.startrun.get() and run<=self.endrun.get()):
00448 print run
00449 if run not in self.Runs:
00450 self.Runs.append(run)
00451 statfiles[temp]=run
00452
00453 except:
00454 self.Print("ERROR -- Could not parse web line '%s'"%i)
00455
00456 for i in statfiles.keys():
00457 webname=self.webname.get()
00458 if (webname[-1]!="/"):
00459 webname=webname+"/"
00460 webname=webname+i
00461 run=statfiles[i]
00462 try:
00463 self.Print("Reading page '%s'"%webname)
00464 out=urlopen(webname).readlines()
00465 except:
00466 self.Print("ERROR -- Could not read '%s'"%webname)
00467 continue
00468 for line in out:
00469 try:
00470 temp=string.split(line)
00471 id=temp[5]
00472 if (id=="value"):
00473 continue
00474 if id not in self.Cells.keys():
00475 self.Cells[id]=CellStat(id)
00476 self.Cells[id].read(run,line)
00477 except:
00478 continue
00479
00480 self.Print("Finished reading files")
00481 self.DrawCells()
00482 return
00483
00484 def DrawCells(self):
00485 Runs=array('i')
00486 deadcells=array('i')
00487 hotcells=array('i')
00488 self.HotCellList=[]
00489 self.DeadCellList=[]
00490 self.AlwaysHotList=[]
00491 self.AlwaysDeadList=[]
00492
00493 if (len(self.Runs)==0):
00494 self.Print("No runs found so far")
00495 return
00496
00497 for i in self.Runs:
00498 Runs.append(i)
00499 deadcount=0
00500 hotcount=0
00501 for id in self.Cells.keys():
00502 if self.Cells[id].Dead(i):
00503
00504 deadcount=deadcount+1
00505 if (id not in self.DeadCellList):
00506 self.DeadCellList.append(id)
00507 if self.Cells[id].Hot(i):
00508 hotcount=hotcount+1
00509 if (id not in self.HotCellList):
00510 self.HotCellList.append(id)
00511 deadcells.append(deadcount)
00512 hotcells.append(hotcount)
00513 for id in self.Cells.keys():
00514 if self.Cells[id].AlwaysHot():
00515 if id not in self.AlwaysHotList:
00516 self.AlwaysHotList.append(id)
00517 for id in self.Cells.keys():
00518 if self.Cells[id].AlwaysDead():
00519 if id not in self.AlwaysDeadList:
00520 self.AlwaysDeadList.append(id)
00521
00522
00523 deadGraph=TGraph(len(Runs),Runs,deadcells)
00524 deadGraph.GetXaxis().SetTitle("Run #")
00525 deadGraph.SetMarkerColor(4)
00526 deadGraph.SetMarkerStyle(20)
00527 deadGraph.SetMinimum(0)
00528 hotGraph=TGraph(len(Runs),Runs,hotcells)
00529 hotGraph.GetXaxis().SetTitle("Run #")
00530 hotGraph.SetMarkerColor(2)
00531 hotGraph.SetMarkerStyle(20)
00532 hotGraph.SetMinimum(0)
00533 mg=TMultiGraph()
00534 mg.Add(deadGraph)
00535 mg.Add(hotGraph)
00536 c1 = TCanvas('c1','test',200, 10, self.canwidth, self.canheight )
00537
00538 gStyle.SetOptTitle(1)
00539 mg.Draw("ap")
00540 mg.GetYaxis().SetTitle("# of cells")
00541 mg.GetXaxis().SetTitle("Run #")
00542 mg.SetTitle("# of Bad Cells/Run (Red = Dead, Blue = Hot)")
00543 mg.Draw("ap")
00544 c1.Update()
00545 c1.Print("badcelldisplay_file.gif")
00546 c1.Close()
00547 GUIimage=PhotoImage(file="badcelldisplay_file.gif")
00548 self.PicLabel.image=GUIimage
00549 self.PicLabel.configure(image=GUIimage)
00550 self.PicLabel.update()
00551
00552 return
00553
00554 def DrawCellStatus(self):
00555 ''' Draws status value of individual cell'''
00556 if (len(self.Runs)==0):
00557 self.GetInfo()
00558 Runs=array('i',self.Runs)
00559 newid=self.CellID.get()
00560 newid=string.strip(newid)
00561 print newid
00562 if newid not in self.Cells:
00563 self.Print("Checking for info on cell '%s'"%self.CellID.get())
00564 try:
00565 newid=calcDetID(self.CellID.get())
00566
00567 except:
00568
00569 self.Print("Could not find info for cell '%s'"%newid)
00570 return
00571 if newid not in self.Cells:
00572
00573 self.Print("Could not find info for cell '%s'."%newid)
00574 return
00575 values=array('i')
00576 self.Runs.sort()
00577 if (len(self.Runs)>1):
00578 width=self.Runs[-1]-self.Runs[0]+1
00579 mymin=self.Runs[0]
00580 mymax=self.Runs[-1]+1
00581 else:
00582 width=1
00583 mymin=self.Runs[0]
00584 mymax=self.Runs[0]+1
00585 gStyle.SetOptStat(0)
00586 gStyle.SetPalette(1)
00587 gr=TH2F("gr","Single Cell Status",width,mymin,mymax,5,0,5)
00588 if (width==1):
00589 gr.GetXaxis().SetBinLabel(1,`self.Runs[0]`)
00590 gr.GetYaxis().SetBinLabel(1,"No Run")
00591 gr.GetYaxis().SetBinLabel(2,"Good")
00592 gr.GetYaxis().SetBinLabel(3,"Hot")
00593 gr.GetYaxis().SetBinLabel(4,"Dead")
00594 gr.GetYaxis().SetBinLabel(5,"Disabled")
00595
00596 for i in range(mymin,mymax+1):
00597
00598 if i in self.Cells[newid].status.keys():
00599
00600 if ((self.Cells[newid].status[i])&0x1):
00601 gr.Fill(i,4)
00602
00603 if ((self.Cells[newid].status[i]>>5)&0x1):
00604 gr.Fill(i,2)
00605
00606 if ((self.Cells[newid].status[i]>>4)&0x1):
00607
00608 gr.Fill(i,3)
00609 if (self.Cells[newid].status[i]==0):
00610 gr.Fill(i,1)
00611 else:
00612 gr.Fill(i,0)
00613
00614
00615 gr.GetXaxis().SetTitle("Run #")
00616 gr.SetMarkerColor(1)
00617 gr.SetMarkerStyle(20)
00618 gr.SetMinimum(0)
00619 c1 = TCanvas('c1','test',200, 10, self.canwidth, self.canheight )
00620
00621 gr.Draw("col")
00622 c1.Update()
00623
00624 c1.Print("badcelldisplay_file.gif")
00625 c1.Close()
00626 GUIimage=PhotoImage(file="badcelldisplay_file.gif")
00627 self.PicLabel.image=GUIimage
00628 self.PicLabel.configure(image=GUIimage)
00629 self.PicLabel.update()
00630 return
00631
00632 def printCellList(self,text):
00633 print "\nPrinting cells:"
00634 text.sort()
00635 for i in text:
00636 print "%s\t\t%s"%(i, convertID(i))
00637 print
00638 return
00639
00640 def Print(self,text):
00641 ''' Method to display text messages in comment frame.'''
00642 if (self.debug):
00643 print text
00644 self.commentLabel.configure(text=text)
00645 self.commentLabel.update()
00646 return
00647
00648
00649
00650 if __name__=="__main__":
00651 if (os.path.isfile("badcelldisplay_file.gif")):
00652 os.system("rm -f badcelldisplay_file.gif")
00653
00654
00655 x=RunStatusGui(debug=True)
00656 x.root.mainloop()