CMS 3D CMS Logo

BadCellDisplay.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
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     # Now calculate detID
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     # Need to changes these once HcalChannelStatus is updated (should be shifting 5 and 6 bits, respectively, not 4 and 5)
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): # only count runs where cell is present
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             # bit 1 is a disabled/not present bit
00113             if (self.status[i]&0x1==0): # only count urns where cell is present
00114                 count=count+1
00115                 if ((self.status[i]>>4)&0x1):
00116                     dead=dead+1
00117         #if (self.status[i]):
00118         #    print "count = ",count,"  DEAD = ",dead
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         # Set Main Frame
00183         if (parent==None):
00184             self.root=Tk()
00185         else:
00186             self.root=parent
00187 
00188         self.root.title("Bad Cell Checker")
00189 
00190         # Set Size of TCanvas plot based on monitor screen size
00191         self.screenwidth=self.root.winfo_screenwidth()
00192         self.screenheight=self.root.winfo_screenheight()
00193         # Speficy height, width of canvas here
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         # Set variables needed by GUI
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         # Now fill the frames
00245         self.makeCommentFrame() # start here so that comments can be added for other methods
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         # Reset values
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 # this is the header line
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                     #self.Print("ERROR -- Could not read line '%s'"%line)
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                     #print "DEAD: ",id
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                 #print newid
00567             except:
00568                 #print newid
00569                 self.Print("Could not find info for cell '%s'"%newid)
00570                 return
00571         if newid not in self.Cells:
00572             #print newid
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         #for i in self.Runs:
00598             if i in self.Cells[newid].status.keys():
00599                 # Need to check bit assignments here
00600                 if ((self.Cells[newid].status[i])&0x1):
00601                     gr.Fill(i,4)
00602                 # hot cells               
00603                 if ((self.Cells[newid].status[i]>>5)&0x1):
00604                     gr.Fill(i,2)
00605                 # dead cells
00606                 if ((self.Cells[newid].status[i]>>4)&0x1):
00607                     #print self.Cells[newid].status[i]
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         #gr=TGraph(len(Runs),Runs,values)
00614         #gr.SetTitle("Cell %s  (32 = dead, 16 = hot)"%newid)
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") # was "col" -- make configurable?
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     #print "%x"%calcDetID("HB (-16,2,1)")
00654     #print convertID("4200618D")
00655     x=RunStatusGui(debug=True)
00656     x.root.mainloop()

Generated on Tue Jun 9 17:32:56 2009 for CMSSW by  doxygen 1.5.4