00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 import sys
00023 import os
00024 base=os.popen2("echo $CMSSW_BASE")
00025 base=base[1].read()
00026 if len(base)<2:
00027 print "No $CMSSW_BASE directory can be found."
00028 print "Are you sure you've set up your CMSSW release area?"
00029 sys.exit()
00030
00031
00032 try:
00033 from Tkinter import *
00034 except:
00035 print "Could not import Tkinter module!"
00036 print "Cannot display GUI!"
00037 print "(If you are running from FNAL, this is a known problem --\n"
00038 print " Tkinter isn't available in the SL4 release of python for some reason."
00039 print "This is being investigated.)"
00040 sys.exit()
00041
00042 import tkMessageBox
00043
00044 import thread
00045 import time
00046 import cPickle
00047 import python_dbs
00048 import string
00049 import helpfunctions
00050
00051
00052 from pyDBSRunClass import FileInfo, DBSRun
00053
00054 from pydbsAccessor import dbsAccessor
00055 import pyRunSummaryBaseClass
00056
00057
00058
00059 class dbsBaseGui:
00060 '''
00061 dbsBaseGui: Base Class for finding files in DBS, running analyses on them
00062
00063 '''
00064
00065 def __init__(self, parent=None, debug=False):
00066
00067 '''
00068 **self.__init__(parent=None, debug=False)**
00069 dbsBaseGui.__init__ sets up all class variables used by the GUI.
00070 '''
00071
00072
00073
00074 checkCMSSW=os.popen2("echo $CMSSW_BASE")
00075 self.basedir=checkCMSSW[1].read()
00076 if len(self.basedir)<2:
00077 print "No $CMSSW_BASE directory can be found."
00078 print "Are you sure you've set up your CMSSW release area?"
00079 sys.exit()
00080
00081
00082 self.cmsVersion=string.split(self.basedir,"/")[-1]
00083 self.cmsVersion=string.strip(self.cmsVersion)
00084 self.cmsVersion=string.split(self.cmsVersion,"_")[1:]
00085
00086
00087
00088 self.basedir=self.basedir.strip("\n")
00089 self.basedir=os.path.join(self.basedir,"src/DQM/HcalMonitorModule/python/dqmdbsGUI")
00090 if not os.path.exists(self.basedir):
00091 print "Unable to find directory '%s'"%self.basedir
00092 print "Have you checked out the appropriate package in your release area?"
00093 sys.exit()
00094
00095 os.chdir(self.basedir)
00096
00097
00098
00099 self.debug=debug
00100 if (self.debug):
00101 print self.__doc__
00102 print self.__init__.__doc__
00103
00104 self.parent=parent
00105
00106 if (self.parent==None):
00107 self.root=Tk()
00108 self.root.title("HCAL DQM from DBS GUI")
00109 self.root.geometry('+25+25')
00110 else:
00111 self.root=self.parent
00112
00113
00114
00115
00116 self.bg="#ffff73cb7"
00117 self.bg_alt="#b001d0180"
00118 self.fg="#180580410"
00119 self.alt_active="gold3"
00120
00121 self.enableSCP=BooleanVar()
00122
00123 self.enableSCP.set(False)
00124
00125
00126 self.updateTimes=(2,5,10,20,30,60,120)
00127
00128 self.lumiBlockRanges=("All",1,2,5,10,20,50,100,200,500,1000)
00129 self.lumiBlockRange=StringVar()
00130 self.lumiBlockRange.set("All")
00131
00132
00133 self.dbsRange=IntVar()
00134 self.lastFoundDBS=IntVar()
00135
00136
00137
00138 self.Automated=BooleanVar()
00139 self.Automated.set(False)
00140
00141 self.dbsAutoVar=BooleanVar()
00142 self.dbsAutoVar.set(False)
00143 self.dqmAutoVar=BooleanVar()
00144 self.dqmAutoVar.set(False)
00145
00146
00147
00148
00149 self.finalDir=StringVar()
00150
00151
00152 self.maxDQMEvents=IntVar()
00153 self.maxDQMEvents.set(1000)
00154
00155 self.prescaleOverRun=BooleanVar()
00156 self.prescaleOverRun.set(False)
00157 self.prescaleOverRunText="# prescale (unused) = "
00158
00159
00160 self.dbsRange.set(100)
00161
00162 self.lastFoundDBS.set(64042)
00163
00164 self.foundfiles=0
00165
00166 self.dbsSearchInProgress=False
00167 self.pickleFileOpen=False
00168 self.runningDQM=False
00169
00170
00171
00172 self.dbsAutoUpdateTime=IntVar()
00173 self.dbsAutoUpdateTime.set(20)
00174 self.dbsAutoCounter=0
00175
00176 self.dqmAutoUpdateTime=IntVar()
00177 self.dqmAutoUpdateTime.set(20)
00178
00179 self.dqmAutoCounter=0
00180 self.autoRunning=False
00181 self.hbcolor=self.bg
00182
00183 self.cfgFileName=StringVar()
00184 if (string.atoi(self.cmsVersion[0]) < 2 or (string.atoi(self.cmsVersion[0])==2 and string.atoi(self.cmsVersion[1])<1)):
00185 self.mycfg="hcal_dqm_dbsgui.cfg"
00186 else:
00187 self.mycfg="hcal_dqm_dbsgui_cfg.py"
00188
00189
00190 self.autoRunShift=True
00191
00192 self.cmsRunOutput=[]
00193 return
00194
00195
00196
00197
00198
00199
00200 def DrawGUI(self):
00201 '''
00202 ** self.DrawGUI() **
00203 Creates GUI window, grids all Tkinter objects within the window.
00204 This function should only contain calls to objects in the GUI display.
00205 Variables attached to those objects are created in the __init__ method.
00206 '''
00207
00208 if (self.debug):
00209 print self.DrawGUI.__doc__
00210
00211 self.root.configure(bg=self.bg)
00212 rootrow=0
00213
00214
00215 self.menubar=Frame(self.root,borderwidth=1,
00216 bg=self.bg,
00217 relief='raised')
00218 self.root.columnconfigure(0,weight=1)
00219 self.root.rowconfigure(1,weight=1)
00220
00221 self.menubar.grid(row=rootrow,column=0,sticky=EW)
00222
00223
00224
00225 rootrow=rootrow+1
00226 self.searchFrame=Frame(self.root,
00227 bg=self.bg)
00228
00229 self.searchFrame.grid(row=rootrow,
00230 sticky=EW,
00231 column=0)
00232
00233
00234
00235 rootrow=rootrow+1
00236 self.mainFrame=Frame(self.root,
00237 bg=self.bg)
00238 self.mainFrame.grid(row=rootrow,column=0,sticky=EW)
00239
00240
00241 rootrow=rootrow+1
00242 self.statusFrame=Frame(self.root,
00243 bg=self.bg
00244 )
00245 self.statusFrame.grid(row=rootrow,column=0,sticky=EW)
00246
00247
00248
00249
00250
00251
00252
00253
00254 mycol=0
00255
00256
00257 self.BFile=Menubutton(self.menubar,
00258 text = "File",
00259 font = ('Times',12,'bold italic'),
00260 activebackground=self.bg_alt,
00261 activeforeground=self.bg,
00262 bg=self.bg,
00263 fg=self.fg,
00264 padx=10, pady=8)
00265 self.BFile.grid(row=0,column=mycol,sticky=W)
00266
00267
00268 mycol=mycol+1
00269 self.Bdbs=Menubutton(self.menubar,
00270 text="DBS options",
00271 font= ('Times',12,'bold italic'),
00272 activebackground=self.bg_alt,
00273 activeforeground=self.bg,
00274 bg=self.bg,
00275 fg=self.fg,
00276 padx=10, pady=8)
00277 self.Bdbs.grid(row=0,column=mycol,sticky=W)
00278
00279
00280 mycol=mycol+1
00281 self.Bdqm=Menubutton(self.menubar,
00282 text="DQM options",
00283 font= ('Times',12,'bold italic'),
00284 activebackground=self.bg_alt,
00285 activeforeground=self.bg,
00286 bg=self.bg,
00287 fg=self.fg,
00288 padx=10, pady=8)
00289 self.Bdqm.grid(row=0,column=mycol,sticky=W)
00290
00291
00292 mycol=mycol+1
00293 self.Bprogress=Menubutton(self.menubar,
00294 text="Status",
00295 font=('Times',12,'bold italic'),
00296 activebackground=self.bg_alt,
00297 activeforeground=self.bg,
00298 bg=self.bg,
00299 fg=self.fg,
00300 padx=10, pady=8)
00301 self.Bprogress.grid(row=0,column=mycol)
00302
00303
00304
00305 mycol=mycol+1
00306 self.menubar.columnconfigure(mycol,weight=1)
00307 self.scpAutoButton=Checkbutton(self.menubar,
00308 bg=self.bg,
00309 fg=self.fg,
00310 text="scp copying enabled",
00311 activebackground=self.alt_active,
00312 variable=self.enableSCP,
00313 padx=10,
00314 command=self.toggleSCP)
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 mycol=mycol+1
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 self.copyLoc=Button(self.menubar,
00348 text="Copy Output\nto cmshcal01!",
00349 command=lambda x=self:x.tempSCP())
00350 self.copyLoc.configure(background=self.bg_alt,
00351 foreground=self.bg,
00352 activebackground=self.alt_active)
00353
00354
00355
00356
00357
00358 if os.getenv("USER")<>"cchcal":
00359 self.enableSCP.set(False)
00360 self.scpAutoButton.configure(text="scp copying disabled")
00361 self.copyLoc.configure(state=DISABLED)
00362
00363
00364
00365
00366 mycol=mycol+1
00367 self.HeartBeat=Label(self.menubar,
00368 text="Auto",
00369 bg=self.bg,
00370 fg=self.bg,
00371 padx=10,pady=8)
00372 self.HeartBeat.grid(row=0,column=mycol,sticky=W)
00373
00374
00375 self.BAbout=Menubutton(self.menubar,
00376 text="About",
00377 font= ('Times',12,'bold italic'),
00378 activebackground=self.bg_alt,
00379 activeforeground=self.bg,
00380 bg=self.bg,
00381 fg=self.fg,
00382 padx=10, pady=8)
00383 mycol=mycol+1
00384 self.BAbout.grid(row=0,column=mycol,sticky=W)
00385
00386
00387
00388 self.quitmenu=Menu(self.BFile, tearoff=0,
00389 bg="white")
00390
00391
00392 self.quitmenu.add_command(label="Clear all default files",
00393 command=lambda x=self:x.removeFiles(removeAll=False))
00394
00395 self.quitmenu.add_command(label="Clear ALL hidden files",
00396 command=lambda x=self:x.removeFiles(removeAll=True))
00397 self.quitmenu.add_separator()
00398
00399 self.quitmenu.add_command(label="Quit",
00400 command = lambda x=self: x.goodQuit())
00401 self.BFile['menu']=self.quitmenu
00402
00403
00404
00405
00406 self.statusmenu=Menu(self.Bprogress,
00407 bg="white")
00408 self.statusmenu.add_command(label="Show run status",
00409 command = lambda x=self:x.displayFiles())
00410 self.statusmenu.add_separator()
00411 self.statusmenu.add_command(label="Change run status",
00412 command = lambda x=self:x.changeFileSettings())
00413 self.statusmenu.add_separator()
00414 self.statusmenu.add_command(label="Clear run file",
00415 command = lambda x=self:x.clearPickle())
00416 self.statusmenu.add_command(label="Restore from backup run file",
00417 command = lambda x=self:x.restoreFromBackupPickle())
00418 self.Bprogress['menu']=self.statusmenu
00419
00420
00421
00422 self.aboutmenu=Menu(self.BAbout,
00423 bg="white")
00424 temptext="DQMfromDBS GUI\n\nv1.3 Beta\nby Jeff Temple\n10 May 2008\n\n"
00425 temptext=temptext+"GUI allows users to query DBS for files in a specified\nrun range, and then run HCAL DQM over those files.\n\nQuestions or comments?\nSend to: jtemple@fnal.gov\n"
00426 self.aboutmenu.add_command(label="Info",
00427 command = lambda x=helpfunctions:
00428 x.Helpwin(temptext,usetext=1,title="About this program..."))
00429 self.aboutmenu.add_command(label="Help",
00430 command = lambda x=helpfunctions:
00431 x.Helpwin("%s"%os.path.join(self.basedir,"dqmdbs_instructions.txt"),title="Basic instructions for the user"))
00432 self.BAbout['menu']=self.aboutmenu
00433
00434
00435
00436
00437 self.dbsmenu=Menu(self.Bdbs,
00438 bg="white",
00439 tearoff=0)
00440 self.dbsmenu.add_command(label="Change DBS settings",
00441 command = lambda x=self:x.printDBS())
00442
00443 self.dbsmenu.add_separator()
00444
00445
00446 self.dbsUpdateMenu=Menu(self.dbsmenu,
00447 bg="white",
00448 tearoff=0)
00449 self.dbsUpdateMenu.choices=Menu(self.dbsUpdateMenu,
00450 bg="white",
00451 tearoff=0)
00452
00453 for upTime in range(len(self.updateTimes)):
00454 self.dbsUpdateMenu.choices.add_command(label='%s minutes'%self.updateTimes[upTime],
00455 command = lambda x=upTime,y=self.updateTimes:self.dbsSetUpdateMenu(x,y)
00456 )
00457 self.dbsmenu.add_cascade(label="Set DBS update time",
00458 menu=self.dbsUpdateMenu.choices)
00459
00460
00461
00462 self.dbsHcalOnlyMenu=Menu(self.dbsmenu,
00463 bg="white",
00464 tearoff=0)
00465 self.dbsHcalOnlyMenu.choices=Menu(self.dbsHcalOnlyMenu,
00466 bg="white",
00467 tearoff=0)
00468 self.dbsSetHcalValue=StringVar()
00469 self.dbsHcalOnlyChoices=["All runs in range","Only runs including HCAL"]
00470 self.dbsSetHcalValue.set("All runs in range")
00471 for i in range(len(self.dbsHcalOnlyChoices)):
00472 self.dbsHcalOnlyMenu.choices.add_command(label="%s"%self.dbsHcalOnlyChoices[i],
00473 command = lambda x=self.dbsHcalOnlyChoices[i],
00474 y=self.dbsHcalOnlyChoices:self.dbsSetHcalOnly(x,y))
00475
00476 if (self.dbsHcalOnlyChoices[i]==self.dbsSetHcalValue.get()):
00477 self.dbsHcalOnlyMenu.choices.entryconfig(i,foreground="red")
00478
00479 self.dbsmenu.add_cascade(label="Set DBS run type:",
00480 menu=self.dbsHcalOnlyMenu.choices)
00481 self.Bdbs['menu']=self.dbsmenu
00482
00483
00484 self.dqmmenu=Menu(self.Bdqm,
00485 bg="white",
00486 tearoff=0)
00487 self.dqmmenu.add_command(label="Change DQM settings",
00488 command = lambda x=self:x.printDQM())
00489 self.dqmmenu.add_separator()
00490
00491
00492 self.dqmUpdateMenu=Menu(self.dqmmenu,
00493 bg="white",
00494 tearoff=0)
00495 self.dqmUpdateMenu.choices=Menu(self.dqmUpdateMenu,
00496 bg="white",
00497 tearoff=0)
00498 for upTime in range(len(self.updateTimes)):
00499 self.dqmUpdateMenu.choices.add_command(label='%s minutes'%self.updateTimes[upTime],
00500 command = lambda x=upTime,y=self.updateTimes:self.dqmSetUpdateMenu(x,y))
00501 self.dqmmenu.add_cascade(label="Set DQM update time",
00502 menu=self.dqmUpdateMenu.choices)
00503
00504
00505
00506 self.lumiBlockRangeMenu=Menu(self.dqmmenu,
00507 bg="white",
00508 tearoff=0)
00509 self.lumiBlockRangeMenu.choices=Menu(self.lumiBlockRangeMenu,
00510 bg="white",
00511 tearoff=0)
00512 for lumiChoice in range(len(self.lumiBlockRanges)):
00513 self.lumiBlockRangeMenu.choices.add_command(label='%s'%self.lumiBlockRanges[lumiChoice],
00514 command = lambda x=lumiChoice,y=self.lumiBlockRanges:self.setLumiBlockMenu(x,y))
00515
00516
00517
00518
00519 self.dqmmenu.add_cascade(label="Set Lum'y Block Range",
00520 menu=self.lumiBlockRangeMenu.choices)
00521
00522
00523 self.Bdqm['menu']=self.dqmmenu
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 searchrow=0
00540 Label(self.searchFrame,text = "Search over ",
00541 bg=self.bg,
00542 fg=self.bg_alt).grid(row=searchrow,column=0)
00543
00544
00545 self.dbsRangeEntry=Entry(self.searchFrame,
00546 bg="white",
00547 fg=self.bg_alt,
00548 width=8,
00549 textvar=self.dbsRange)
00550 self.dbsRangeEntry.grid(row=searchrow,column=1)
00551 self.lastFoundDBSEntry=Entry(self.searchFrame,
00552 bg="white",
00553 fg=self.bg_alt,
00554 width=8,
00555 textvar=self.lastFoundDBS)
00556 self.lastFoundDBSEntry.grid(row=searchrow,column=3)
00557
00558
00559 Label(self.searchFrame,
00560 text="runs, starting with run #",
00561 bg=self.bg,
00562 fg=self.bg_alt).grid(row=searchrow,column=2)
00563
00564
00565
00566
00567
00568
00569
00570
00571 mainrow=0
00572
00573 self.stripe=Label(self.mainFrame,text="",
00574 font = ('Times',2,'bold italic'),
00575 bg=self.fg)
00576 self.stripe.grid(row=mainrow,column=0,
00577 columnspan=10,sticky=EW)
00578
00579
00580
00581 mainrow=mainrow+1
00582 Label(self.mainFrame,text="Current Status",
00583 bg=self.bg,
00584 fg=self.bg_alt).grid(row=mainrow,column=1)
00585 Label(self.mainFrame,text="Last Update",
00586 bg=self.bg,
00587 fg=self.bg_alt).grid(row=mainrow,column=2)
00588
00589
00590 self.autoButton=Button(self.mainFrame,
00591 text="Auto-Update\nDisabled!!",
00592 bg="black",
00593 fg="white",
00594 command = lambda x=self:x.checkAutoUpdate())
00595 self.autoButton.grid(row=mainrow,column=4,padx=10,pady=6)
00596
00597
00598
00599 mainrow=mainrow+1
00600 self.dbsLabel=Label(self.mainFrame,
00601 text="DBS:",
00602 fg=self.fg, bg=self.bg,
00603 width=10)
00604 self.dbsProgress=Label(self.mainFrame,
00605 text="Nothing yet...",
00606 bg="black",
00607 width=40,
00608 fg=self.bg)
00609 self.dbsStatus=Label(self.mainFrame,
00610 text="Nothing yet...",
00611 width=40,
00612 bg=self.bg,
00613 fg=self.fg)
00614 self.dbsButton=Button(self.mainFrame,
00615 text="Check DBS\nfor runs",
00616 height=2,
00617 width=15,
00618 fg=self.bg,
00619 bg=self.bg_alt,
00620 activebackground=self.alt_active,
00621 command = lambda x=self:x.checkDBS()
00622 )
00623
00624 self.dbsAutoButton=Checkbutton(self.mainFrame,
00625 text="Auto DBS\nupdate OFF",
00626 state=DISABLED,
00627 bg=self.bg,
00628 fg=self.fg,
00629 width=20,
00630 activebackground=self.alt_active,
00631 variable=self.dbsAutoVar,
00632 command=self.toggleAutoDBS)
00633
00634
00635
00636 self.dbsLabel.grid(row=mainrow,column=0)
00637 self.dbsProgress.grid(row=mainrow,column=1)
00638 self.dbsStatus.grid(row=mainrow,column=2)
00639 self.dbsButton.grid(row=mainrow,column=3)
00640 self.dbsAutoButton.grid(row=mainrow,column=4)
00641
00642
00643 self.dqmLabel=Label(self.mainFrame,
00644 text="DQM:",
00645 fg=self.fg, bg=self.bg,
00646 width=10)
00647 self.dqmProgress=Label(self.mainFrame,
00648 text="Nothing yet...",
00649 bg="black",
00650 width=40,
00651 fg=self.bg)
00652 self.dqmStatus=Label(self.mainFrame,
00653 text="Nothing yet...",
00654 width=40,
00655 bg=self.bg,
00656 fg=self.fg)
00657 self.dqmButton=Button(self.mainFrame,
00658 text="Run the \nHCAL DQM",
00659 height=2,
00660 width=15,
00661 fg=self.bg,
00662 bg=self.bg_alt,
00663 activebackground=self.alt_active,
00664 command = lambda x=self:x.runDQM_thread())
00665
00666 self.dqmAutoButton=Checkbutton(self.mainFrame,
00667 text="Auto DQM\nupdate OFF",
00668 state=DISABLED,
00669 bg=self.bg,
00670 fg=self.fg,
00671 width=20,
00672 activebackground=self.alt_active,
00673 variable=self.dqmAutoVar,
00674 command=self.toggleAutoDQM)
00675
00676
00677
00678 mainrow=mainrow+1
00679 self.dqmLabel.grid(row=mainrow,column=0)
00680 self.dqmProgress.grid(row=mainrow,column=1)
00681 self.dqmStatus.grid(row=mainrow,column=2)
00682 self.dqmButton.grid(row=mainrow,column=3)
00683 self.dqmAutoButton.grid(row=mainrow,column=4)
00684
00685
00686
00687
00688
00689
00690
00691
00692 self.statusFrame.columnconfigure(0,weight=1)
00693
00694 self.commentLabel=Label(self.statusFrame,
00695 bg=self.bg,
00696 fg=self.bg_alt,
00697 height=2)
00698
00699 statusrow=0
00700 self.commentLabel.grid(row=statusrow,column=0,sticky=EW)
00701
00702
00703 self.setup()
00704 return
00705
00706
00707
00708
00709 def setup(self):
00710 '''
00711 **self.setup() **
00712 Setup performs some GUI tuning that cannot be completed until variables are declared and
00713 GUI is drawn.
00714
00715 '''
00716
00717 if self.debug: print self.setup.__doc__
00718
00719
00720
00721
00722 os.chdir(self.basedir)
00723
00724 self.finalDir.set(self.basedir)
00725
00726
00727 self.myDBS = dbsAccessor(self.basedir,debug=self.debug)
00728 self.myDBS.getDefaultsFromPickle()
00729
00730
00731
00732
00733
00734 self.cfgFileName.set(os.path.join(self.basedir,self.mycfg))
00735 self.getDefaultDQMFromPickle(startup=True)
00736
00737 self.readPickle()
00738
00739
00740 if len(self.filesInDBS.keys()):
00741 x=self.filesInDBS.keys()
00742 x.sort()
00743 x.reverse()
00744 self.lastFoundDBS.set(x[0])
00745
00746
00747 for temptime in range(len(self.updateTimes)):
00748 if self.updateTimes[temptime]==self.dbsAutoUpdateTime.get():
00749 self.dbsUpdateMenu.choices.entryconfig(temptime,foreground="red")
00750 if self.updateTimes[temptime]==self.dqmAutoUpdateTime.get():
00751 self.dqmUpdateMenu.choices.entryconfig(temptime,foreground="red")
00752
00753
00754 for templumi in range(len(self.lumiBlockRanges)):
00755 if self.lumiBlockRanges[templumi]==self.lumiBlockRange.get():
00756 self.lumiBlockRangeMenu.choices.entryconfig(templumi,foreground="red")
00757
00758
00759
00760 self.lastFoundDBSEntry.bind("<Shift-Up>",self.toggleAutoRunShift)
00761 self.lastFoundDBSEntry.bind("<Shift-Down>",self.toggleAutoRunShift)
00762
00763 if not os.path.isdir(self.finalDir.get()):
00764 self.commentLabel.configure(text="WARNING -- specified Final DQM Save Directory does not exist!\nCheck settings in DQM options!")
00765 self.commentLabel.update_idletasks()
00766 return
00767
00768
00769
00770 def checkAutoUpdate(self):
00771 '''
00772 ** self.checkAutoUpdate() **
00773 This is the function associated with the "Auto Update" button.
00774 It toggles the self.Automated variable.
00775 If self.Automated is true, then DBS searches and DQM running
00776 are performed automatically.
00777 '''
00778
00779 if (self.debug):
00780 print self.checkAutoUpdate.__doc__
00781
00782
00783 self.Automated.set(1-self.Automated.get())
00784 if (self.debug):
00785 print "<checkAutoUpdate> Checkpoint 1"
00786 if (self.Automated.get()==True):
00787 self.autoButton.configure(text="Auto Update\nEnabled",
00788 bg=self.bg_alt,
00789 fg=self.bg)
00790
00791 self.dqmAutoButton.configure(state=NORMAL,text="Auto DQM update\nevery %s minutes"%self.dqmAutoUpdateTime.get(),
00792 bg=self.bg,fg=self.fg)
00793 self.dbsAutoButton.configure(state=NORMAL,text="Auto DBS update\nevery %s minutes"%self.dbsAutoUpdateTime.get(),
00794 bg=self.bg,fg=self.fg)
00795 self.dbsAutoVar.set(True)
00796 self.dqmAutoVar.set(True)
00797
00798 if (self.debug):
00799 print "<checkAutoUpdate> Starting autoUpdater thread"
00800 thread.start_new(self.autoUpdater,())
00801
00802 else:
00803
00804 if (self.debug):
00805 print "<checkAutoUpdate> Auto update turned off"
00806
00807 self.autoButton.configure(text="Auto Update\nDisabled!!",
00808 bg="black",
00809 fg="white")
00810 self.dqmAutoButton.configure(text="Auto DQM \nupdate OFF",state=DISABLED)
00811 self.dbsAutoButton.configure(text="Auto DBS \nupdate OFF",state=DISABLED)
00812 self.dbsAutoVar.set(False)
00813 self.dqmAutoVar.set(False)
00814
00815 self.commentLabel.update_idletasks()
00816
00817 return
00818
00819
00820 def heartbeat(self,interval=1):
00821 '''
00822 ** self.heartbeat(interval =1 ) **
00823 Make heartbeat label flash once per second.
00824 '''
00825
00826 if (self.debug):
00827 print self.heartbeat.__doc__
00828
00829 while (self.Automated.get()):
00830 if (self.hbcolor==self.bg):
00831 self.hbcolor=self.bg_alt
00832 else:
00833 self.hbcolor=self.bg
00834 self.HeartBeat.configure(bg=self.hbcolor)
00835 self.commentLabel.update_idletasks()
00836 time.sleep(interval)
00837
00838 self.HeartBeat.configure(bg=self.bg)
00839 return
00840
00841
00842 def autoUpdater(self):
00843 '''
00844 ** autoUpdate() **
00845 DQM/DBS Auto updater.
00846 '''
00847
00848 if (self.debug):
00849 print self.autoUpdater.__doc__
00850
00851 if self.autoRunning==True:
00852
00853
00854 self.commentLabel.configure(text="Auto Updater is already running!")
00855 self.commentLabel.update_idletasks()
00856 return
00857 if self.Automated.get()==False:
00858 self.commentLabel.configure(text="Auto Updater is disabled")
00859 self.commentLabel.update_idletasks()
00860 return
00861
00862 thread.start_new(self.heartbeat,())
00863 self.checkDBS()
00864 self.runDQM_thread()
00865
00866 while (self.Automated.get()):
00867 self.autoRunning=True
00868 for xx in range(0,60):
00869 time.sleep(1)
00870 if not self.Automated.get():
00871 break
00872
00873
00874
00875 self.dbsAutoCounter=self.dbsAutoCounter+1
00876 self.dqmAutoCounter=self.dqmAutoCounter+1
00877
00878
00879
00880 if (self.dbsAutoCounter >= self.dbsAutoUpdateTime.get()):
00881
00882 if (self.dbsAutoVar.get()==False):
00883 self.dbsAutoCounter=0
00884 else:
00885
00886 if (self.checkDBS()):
00887 self.dbsAutoCounter=0
00888
00889 else:
00890 self.dbsAutoCounter=(self.dbsAutoUpdateTime.get()-1)*60
00891
00892
00893
00894 if (self.dqmAutoCounter >= self.dqmAutoUpdateTime.get()):
00895
00896
00897
00898
00899 if (self.dqmAutoVar.get()==False):
00900 self.dqmAutoCounter=0
00901
00902 else:
00903 self.runDQM_thread()
00904
00905
00906
00907 self.dbsAutoCounter=0
00908 self.dqmAutoCounter=0
00909 self.autoRunning=False
00910 return
00911
00912
00913 def printDBS(self):
00914 '''
00915 ** self.printDBS() **
00916 Create new window showing DBS values; allow user to change them.
00917 '''
00918
00919 if (self.debug):
00920 print self.printDBS.__doc__
00921
00922 try:
00923 self.dbsvaluewin.destroy()
00924 self.dbsvaluewin=Toplevel()
00925 except:
00926 self.dbsvaluewin=Toplevel()
00927
00928 self.dbsvaluewin.title('Change DBS values')
00929 try:
00930 maingeom=self.root.winfo_geometry()
00931 maingeomx=string.split(maingeom,"+")[1]
00932 maingeomy=string.split(maingeom,"+")[2]
00933 maingeomx=int(maingeomx)
00934 maingeomy=int(maingeomy)
00935 self.dbsvaluewin.geometry('+%i+%i'%(maingeomx+575,maingeomy+275))
00936 except:
00937 self.dbsvaluewin.geometry('+600+300')
00938
00939 myrow=0
00940
00941
00942
00943
00944 myvars={" DBS File Search String = ":self.myDBS.searchStringFile,
00945 " DBS Dataset Search String = ":self.myDBS.searchStringDataset,
00946 " DBS Files to Return = ":self.myDBS.limit,
00947 " DBS Host = ":self.myDBS.host,
00948 " DBS Port = ":self.myDBS.port,
00949 " DBS Instance = ":self.myDBS.dbsInst,
00950 "Output in XML Format? ":self.myDBS.xml,
00951 "Show detailed output? ":self.myDBS.details,
00952 "Case-sensitive matching? ":self.myDBS.case,
00953 "Output page = ":self.myDBS.page,
00954 "Debugging = ":self.myDBS.debug,
00955 " Site = ":self.myDBS.site}
00956
00957 temp=myvars.keys()
00958 temp.sort()
00959
00960
00961 for i in temp:
00962 Label(self.dbsvaluewin,
00963 width=40,
00964 text="%s"%i).grid(row=myrow,column=0)
00965 Entry(self.dbsvaluewin,
00966 width=40,
00967 bg="white",
00968 textvar=myvars[i]).grid(row=myrow,column=1)
00969 myrow=myrow+1
00970
00971
00972 buttonwin=Frame(self.dbsvaluewin)
00973 buttonwin.columnconfigure(0,weight=1)
00974 buttonwin.columnconfigure(1,weight=1)
00975 buttonwin.columnconfigure(2,weight=1)
00976 buttonwin.grid(row=myrow,column=0,columnspan=2,sticky=EW)
00977 Button(buttonwin,text="Save as new default values",
00978 command = lambda x=self.myDBS:x.writeDefaultsToPickle()).grid(row=0,column=0)
00979 Button(buttonwin,text="Restore default values",
00980 command = lambda x=self.myDBS:x.getDefaultsFromPickle()).grid(row=0,
00981 column=1)
00982 Button(buttonwin,text="Close window",
00983 command = lambda x=self.dbsvaluewin:x.destroy()).grid(row=0,column=2)
00984 return
00985
00986
00987 def printDQM(self):
00988 '''
00989 ** self.printDQM() **
00990 Create window for editing DQM values.
00991 '''
00992
00993 if (self.debug):
00994 print self.printDQM.__doc__
00995
00996 try:
00997 self.dqmvaluewin.destroy()
00998 self.dqmvaluewin=Toplevel()
00999 except:
01000 self.dqmvaluewin=Toplevel()
01001
01002 try:
01003 maingeom=self.root.winfo_geometry()
01004 maingeomx=string.split(maingeom,"+")[1]
01005 maingeomy=string.split(maingeom,"+")[2]
01006 maingeomx=int(maingeomx)
01007 maingeomy=int(maingeomy)
01008 self.dqmvaluewin.geometry('+%i+%i'%(maingeomx+375,maingeomy+275))
01009 except:
01010 self.dqmvaluewin.geometry('+600+300')
01011
01012 self.dqmvaluewin.title("Change DQM Values")
01013 myrow=0
01014
01015
01016
01017
01018
01019 myvars={" Final DQM Save Directory = ":self.finalDir,
01020 " # of events to run for each DQM = ":self.maxDQMEvents,
01021 " Prescale to run over entire run (1=yes/0=no)? ":self.prescaleOverRun,
01022 " .cfg file to run for each DQM = ":self.cfgFileName}
01023 temp=myvars.keys()
01024 temp.sort()
01025
01026
01027 for i in range(len(temp)):
01028
01029
01030 if (temp[i]== " Prescale to run over entire run (1=yes/0=no)? " and self.prescaleOverRunText=="# prescale (unused) = "):
01031 continue
01032 Label(self.dqmvaluewin,
01033 width=40,
01034 text="%s"%temp[i]).grid(row=myrow,column=0)
01035
01036 if temp[i]==" Prescale to run over entire run (1=yes/0=no)? ":
01037 tempEnt=OptionMenu(self.dqmvaluewin,
01038 self.prescaleOverRun,
01039 'True',
01040 'False')
01041 tempEnt.configure(width=75,bg="white")
01042 else:
01043 tempEnt=Entry(self.dqmvaluewin,
01044 width=80,
01045 bg="white",
01046 textvar=myvars[temp[i]])
01047 tempEnt.grid(row=myrow,column=1)
01048 if temp[i]==" Final DQM Save Directory = ":
01049 tempEnt.bind("<Return>",(lambda event:self.checkExistence(self.finalDir)))
01050 elif temp[i]== " .cfg file to run for each DQM = ":
01051 tempEnt.bind("<Return>",(lambda event:self.checkExistence(self.cfgFileName)))
01052 myrow=myrow+1
01053 newFrame=Frame(self.dqmvaluewin)
01054 newFrame.grid(row=myrow,column=0,columnspan=2,sticky=EW)
01055 newFrame.columnconfigure(0,weight=1)
01056 newFrame.columnconfigure(1,weight=1)
01057 newFrame.columnconfigure(2,weight=1)
01058 Button(newFrame,text="Save as new default\n DQM values",
01059 command = lambda x=self:x.writeDefaultDQMToPickle()).grid(row=0,column=0)
01060 Button(newFrame,text="Restore default DQM values",
01061 command = lambda x=self:x.getDefaultDQMFromPickle()).grid(row=0,
01062 column=1)
01063
01064
01065 Button(newFrame,text="Exit",
01066 command = lambda x=self.dqmvaluewin:x.destroy()).grid(row=0,column=2)
01067 return
01068
01069
01070 def getDefaultDQMFromPickle(self,startup=False):
01071 '''
01072 ** self.getDefaultDQMFromPickle(startup=False) **
01073 Get DQM default values from .dqmDefaults.cPickle.
01074 startup variable is set True for first function call on startup.
01075 (This only affects the message displayed in the comment label after the function call.)
01076 '''
01077
01078 if (self.debug):
01079 print self.getDefaultDQMFromPickle.__doc__
01080
01081 if os.path.isfile(os.path.join(self.basedir,".dqmDefaults.cPickle")):
01082 try:
01083 pcl=open(os.path.join(self.basedir,".dqmDefaults.cPickle"),'rb')
01084 self.finalDir.set(cPickle.load(pcl))
01085 self.maxDQMEvents.set(cPickle.load(pcl))
01086 self.cfgFileName.set(cPickle.load(pcl))
01087 self.prescaleOverRun.set(cPickle.load(pcl))
01088 pcl.close()
01089 except:
01090 self.commentLabel.configure(text="Could not read file '.dqmDefaults.cPickle' ")
01091 self.commentLabel.update_idletasks()
01092 else:
01093 if not startup:
01094 self.commentLabel.configure(text="Sorry, no default values were found")
01095 self.commentLabel.update_idletasks()
01096 return
01097
01098 def writeDefaultDQMToPickle(self):
01099 '''
01100 ** self.writeDefaultDQMToPickle **
01101 Write DQM default values to basedir/.dqmDefaults.cPickle.
01102 '''
01103
01104 if (self.debug):
01105 print self.writeDefaultDQMToPickle.__doc__
01106
01107 try:
01108 pcl=open(os.path.join(self.basedir,".dqmDefaults.cPickle"),'wb')
01109 cPickle.dump(self.finalDir.get(),pcl)
01110 cPickle.dump(self.maxDQMEvents.get(),pcl)
01111 cPickle.dump(self.cfgFileName.get(),pcl)
01112 cPickle.dump(self.prescaleOverRun.get(),pcl)
01113 pcl.close()
01114 os.system("chmod a+rw %s"%os.path.join(self.basedir,".dqmDefaults.cPickle"))
01115
01116 except SyntaxError:
01117 self.commentLabel.configure(text="Could not write file '.dqmDefaults.cPickle' ")
01118 self.commentLabel.update_idletasks()
01119 return
01120
01121
01122 def readPickle(self):
01123 '''
01124 ** self.readPickle() **
01125 Read list of found runs from basedir/.filesInDBS.cPickle.
01126 '''
01127
01128 if (self.debug):
01129 print self.readPickle.__doc__
01130
01131 if (self.pickleFileOpen):
01132 self.commentLabel.configure(text="Sorry, .filesInDBS.cPickle is already open")
01133 return
01134 self.pickleFileOpen=True
01135
01136 if os.path.isfile(os.path.join(self.basedir,".filesInDBS.cPickle")):
01137 try:
01138 temp=open(os.path.join(self.basedir,".filesInDBS.cPickle"),'rb')
01139 self.filesInDBS=cPickle.load(temp)
01140 self.commentLabel.configure(text = "Loaded previously-read DBS entries from cPickle file")
01141 self.commentLabel.update_idletasks()
01142 except:
01143 self.commentLabel.configure(text="WARNING! Could not read .filesInDBS.cPickle file!\n-- Starting DBS list from scratch")
01144 self.filesInDBS={}
01145 else:
01146 self.filesInDBS={}
01147 self.commentLabel.configure(text = "Could not find file .filesInDBS.cPickle\n-- Starting DBS list from scratch")
01148 self.commentLabel.update_idletasks()
01149
01150 self.pickleFileOpen=False
01151 return
01152
01153
01154 def writePickle(self):
01155 '''
01156 ** self.writePickle() **
01157 Write list of found runs to basedir/.filesInDBS.cPickle.
01158 '''
01159
01160 if (self.debug):
01161 print self.writePickle.__doc__
01162
01163 if (self.pickleFileOpen):
01164 self.commentLabel.configure(text="Sorry, could not write information to .filesInDBS.cPickle.\ncPickle file is currently in use.")
01165 self.commentLabel.update_idletasks()
01166 return
01167 self.pickleFileOpen=True
01168 if len(self.filesInDBS)>0:
01169 try:
01170 myfile=open(os.path.join(self.basedir,".filesInDBS.cPickle"),'wb')
01171 cPickle.dump(self.filesInDBS,myfile)
01172 myfile.close()
01173 os.system("chmod a+rw %s"%os.path.join(self.basedir,".filesInDBS.cPickle"))
01174 except:
01175 self.commentLabel.configure(text="ERROR! Could not write to file .filesInDBS.cPickle!\n This bug will be investigated!")
01176 self.commentLabel.update_idletasks()
01177 self.pickleFileOpen=False
01178 return
01179
01180
01181 def clearPickle(self):
01182 '''
01183 ** self.clearPickle() **
01184 Clear list of found runs, copying .cPickle info to backup file.
01185 '''
01186
01187 if (self.debug):
01188 print self.clearPickle.__doc__
01189
01190 if not (os.path.isfile(os.path.join(self.basedir,".filesInDBS.cPickle"))):
01191 self.commentLabel.configure(text="No run list .filesInDBS.cPickle exists!\nThere is nothing yet to clear!")
01192 self.commentLabel.update_idletasks()
01193 return
01194
01195 if tkMessageBox.askyesno("Remove .filesInDBS.cPickle?",
01196 "Clearing the list of runs is a major change!\nAre you sure you wish to proceed?"):
01197 os.system("mv %s %s"%(os.path.join(self.basedir,".filesInDBS.cPickle"),
01198 os.path.join(self.basedir,".backup_filesInDBS.cPickle")))
01199
01200 self.filesInDBS={}
01201 self.commentLabel.configure(text="Run list cleared (saved as .backup_filesInDBS.cPickle)")
01202 self.commentLabel.update_idletasks()
01203
01204 return
01205
01206 def restoreFromBackupPickle(self):
01207 '''
01208 ** self.restoreFromBackupPickle() **
01209 Restore list of found runs from basedir/.backup_filesInDBS.cPickle file
01210 '''
01211
01212 if (self.debug):
01213 print self.restoreFromBackupPickle.__doc__
01214
01215 if not (os.path.isfile(os.path.join(self.basedir,".backup_filesInDBS.cPickle"))):
01216 self.commentLabel.configure(text="Sorry, backup file does not exist!")
01217 self.commentLabel.update_idletasks()
01218 return
01219 if tkMessageBox.askyesno("Restore from .backup_filesInDBS.cPickle",
01220 "Are you sure you want to restore files\nfrom backup?"):
01221 os.system("mv %s %s"%(os.path.join(self.basedir,".backup_filesInDBS.cPickle"),
01222 os.path.join(self.basedir,".filesInDBS.cPickle")))
01223 self.readPickle()
01224 self.commentLabel.configure(text="Run list restored from .backup_filesInDBS.cPickle")
01225 self.commentLabel.update_idletasks()
01226 return
01227
01228
01229
01230 def removeFiles(self,removeAll=False):
01231 '''
01232 ** self.removeFiles(removeAll=False) **
01233 Removes hidden files (files starting with "."), such as default option settings, etc.
01234 If removeAll is set true, then the .filesInDBS.cPickle file that is used to store run history is also removed.
01235 One exception: .backup_filesInDBS.cPickle can never be removed via the GUI
01236 '''
01237
01238 if (self.debug):
01239 print self.removeFiles.__doc__
01240
01241 if (removeAll):
01242 text="This will remove ALL hidden files\n used by the GUI, and will clear\nthe list of runs processed by the\n program.\n\nAre you ABSOLUTELY SURE \nthis is what you want?\n"
01243 else:
01244 text="This will remove hidden files used to\nstore certain user-set default values.\n\nAre you SURE this is what you want?\n"
01245 if tkMessageBox.askyesno("Remove default files??? Really???",
01246 text):
01247 temp=[".dqmDefaults.cPickle",".dbsDefaults.cPickle",".runOptions.cfi"]
01248 if (removeAll):
01249 temp.append(".filesInDBS.cPickle")
01250 self.filesInDBS={}
01251 for i in temp:
01252 x=os.path.join(self.basedir,i)
01253 if os.path.isfile(x):
01254 self.commentLabel.configure(text="Removing file '%s'"%i)
01255 self.commentLabel.update_idletasks()
01256 os.system("rm -f %s"%x)
01257 time.sleep(0.5)
01258 return
01259
01260 def goodQuit(self):
01261 '''
01262 ** self.goodQuit() **
01263 A "clean exit" from the GUI program.
01264 Checks that DBS/ DQM calls are not currently in progress, and
01265 then closes the GUI.
01266 '''
01267
01268 if (self.debug):
01269 print self.goodQuit.__doc__
01270
01271 if (self.dbsSearchInProgress or self.runningDQM):
01272 text="The following jobs have not yet finished:"
01273 if (self.dbsSearchInProgress):
01274 text=text+"\nA DBS Search is still in progress"
01275 if (self.runningDQM):
01276 text=text+"\nDQM is currently running"
01277 text=text+"\nDo you want to exit anyway?"
01278 if not tkMessageBox.askyesno("Jobs not yet completed",text):
01279 return
01280
01281
01282 self.Automated.set("False")
01283 self.root.destroy()
01284 return
01285
01286
01287 def runDQM_thread(self):
01288 '''
01289 ** self.runDQM_thread() **
01290 Starts new thread for running DQM,
01291 as long as DQM process is not already running
01292 '''
01293
01294 if (self.debug):
01295 print self.runDQM_thread.__doc__
01296
01297 if self.runningDQM:
01298 self.commentLabel.configure(text="Sorry, DQM is already running!")
01299 self.commentLabel.update_idletasks()
01300 else:
01301 thread.start_new(self.runDQM,())
01302 return
01303
01304
01305 def runDQM(self):
01306 '''
01307 ** self.runDQM() **
01308 Runs DQM over all found files.
01309 '''
01310
01311 if (self.debug):
01312 print self.runDQM.__doc__
01313
01314 mytime=time.time()
01315
01316 if self.runningDQM:
01317 self.commentLabel.configure(text="Sorry, DQM is already running")
01318 self.commentLabel.update_idletasks()
01319 return
01320
01321 self.dqmProgress.configure(text="Running DQM on available runs",
01322 bg=self.bg_alt)
01323 self.dqmStatus.configure(text="%s"%time.strftime("%d %b %Y at %H:%M:%S",time.localtime()))
01324
01325
01326
01327 self.readPickle()
01328
01329 if (self.debug):
01330 print "<runDQM> Read pickle file"
01331 if len(self.filesInDBS.keys())==0:
01332 self.commentLabel.configure(text = "Sorry, no file info available.\nTry the 'Check DBS for Runs' button first.")
01333 self.dqmProgress.configure(text="No Run Info available",
01334 bg="black")
01335 self.commentLabel.update_idletasks()
01336 return
01337
01338
01339 if len(self.filesInDBS.keys()):
01340 foundruns=self.filesInDBS.keys()
01341 foundruns.sort()
01342 foundruns.reverse()
01343 else:
01344 self.commentLabel.configure(text="No unprocessed runs found")
01345 self.commentLabel.update_idletasks()
01346 return
01347
01348 self.runningDQM=True
01349 self.dqmButton.configure(state=DISABLED)
01350
01351 unfinished_run=0
01352 finished_run=0
01353 all_run=len(foundruns)
01354 if (self.debug):
01355 print "<runDQM> Set finished, unfinished run vars"
01356 for i in foundruns:
01357
01358 if self.filesInDBS[i].ignoreRun==False and self.filesInDBS[i].finishedDQM==False:
01359 unfinished_run=unfinished_run+1
01360
01361 newFiles=False
01362 for i in foundruns:
01363 if (self.debug):
01364 print "<runDQM> Checking run #%i"%i
01365
01366 self.commentLabel.configure(text="Running DQM on run #%i"%i)
01367 self.dqmProgress.configure(text="Running DQM on run #%i"%i,
01368 bg=self.bg_alt)
01369 self.commentLabel.update_idletasks()
01370
01371
01372 if (self.debug):
01373 print "<runDQM> runningDQM bool = ",self.runningDQM
01374 if (self.runningDQM==False):
01375 if (self.debug):
01376 print "<runDQM> runningDQM bool = False"
01377 self.dqmButton.configure(state=NORMAL)
01378 break
01379
01380 if self.filesInDBS[i].ignoreRun:
01381 continue
01382
01383 if self.filesInDBS[i].startedDQM:
01384
01385
01386 if self.filesInDBS[i].finishedDQM:
01387 self.filesInDBS[i].previouslyFinishedDQM=True
01388
01389 continue
01390
01391
01392
01393
01394
01395
01396 success=self.getcmsRunOutput(i)
01397 if not success:
01398
01399
01400
01401 if (self.lumiBlockRange.get()=="All"):
01402
01403
01404
01405
01406 print "Problem with Run # %i -- DQM started but did not finish!"%i
01407 self.commentLabel.configure(text="Problem with Run # %i -- DQM started but did not finish!"%i)
01408 self.commentLabel.update_idletasks()
01409
01410 else:
01411
01412 self.filesInDBS[i].finishedDQM=True
01413 finished_run=finished_run+1
01414 continue
01415
01416
01417 if ((not self.filesInDBS[i].startedDQM ) or
01418 (self.lumiBlockRange.get()<>"All" and
01419 self.filesInDBS[i].startedDQM and not
01420 self.filesInDBS[i].finishedDQM)):
01421
01422
01423
01424
01425 if (self.debug):
01426 print "<runDQM> looking for cmsRun"
01427 checkcmsRun=os.popen3("which cmsRun")
01428
01429
01430 if len(checkcmsRun[2].readlines())>0:
01431 self.commentLabel.configure(text="Could not find 'cmsRun'\nHave you set up your CMSSW environment?")
01432 self.commentLabel.update_idletasks()
01433 return
01434
01435 self.runningDQM=True
01436 self.filesInDBS[i].startedDQM=True
01437
01438
01439 if (self.callDQMscript(i)):
01440
01441 if (self.lumiBlockRange.get()=="All"):
01442 self.filesInDBS[i].finishedDQM=True
01443
01444 else:
01445
01446 self.filesInDBS[i].currentLumiBlock=self.filesInDBS[i].currentLumiBlock+int(self.lumiBlockRange.get())
01447 if (self.filesInDBS[i].currentLumiBlock>self.filesInDBS[i].numLumiBlocks):
01448 self.filesInDBS[i].finishedDQM=True
01449
01450 finished_run=finished_run+1
01451
01452 if (self.debug):
01453 print "<runDQM> made it through callDQMscript"
01454
01455
01456
01457
01458
01459
01460 if (time.time()-mytime)>20*60:
01461
01462 if (self.debug):
01463 print "<runDQM> getting time info"
01464 mytime=time.time()
01465 self.checkDBS()
01466 if len(self.filesInDBS.keys())<>len(foundruns):
01467 self.commentLabel.configure(text="DBS files have been added since last call to DQM.\n Restarting DQM.")
01468 self.commentLabel.update_idletasks()
01469 newFiles=True
01470 break
01471 if (newFiles):
01472
01473 self.writePickle()
01474
01475
01476
01477
01478 self.dqmButton.configure(state=ACTIVE)
01479 self.runningDQM=False
01480 self.runDQM()
01481 return
01482 else:
01483 self.runningDQM=True
01484
01485
01486 self.runningDQM=False
01487 self.writePickle()
01488
01489 if (finished_run==unfinished_run):
01490 self.dqmProgress.configure(text="Successfully finished running DQM",
01491 bg="black")
01492 else:
01493 self.dqmProgress.configure(text="Ran DQM on %i/%i runs"%(finished_run, unfinished_run))
01494 self.dqmStatus.configure(text="%s"%time.strftime("%d %b %Y at %H:%M:%S",time.localtime()))
01495 self.commentLabel.configure(text="Finished running DQM:\n%i out of %i runs successfully processed"%(finished_run,unfinished_run))
01496 time.sleep(3)
01497
01498
01499 self.dqmButton.configure(state=NORMAL)
01500
01501 self.commentLabel.update_idletasks()
01502 return
01503
01504
01505 def callDQMscript(self,i):
01506 '''
01507 ** self.callDQMscript(i) **
01508 Here is where we actually perform the cmsRun call for the given run number `i`.
01509 '''
01510
01511 if (self.debug):
01512 print self.callDQMscript.__doc__
01513
01514 time.sleep(1)
01515
01516
01517 filesToRun=[]
01518 if (self.lumiBlockRange.get()=="All"):
01519 filesToRun=self.filesInDBS[i].files
01520 else:
01521
01522 totalevents=0
01523 for myfile in range(len(self.filesInDBS[i].fileInfo)):
01524 myval=self.filesInDBS[i].fileInfo[myfile].lumiBlock
01525
01526
01527 if (myval>=self.filesInDBS[i].currentLumiBlock and myval<self.filesInDBS[i].currentLumiBlock+int(self.lumiBlockRange.get())):
01528 filesToRun.append(self.filesInDBS[i].fileInfo[myfile].fileName)
01529 totalevents=totalevents+self.filesInDBS[i].fileInfo[myfile].numEvents
01530 self.filesInDBS[i].totalEvents=totalevents
01531
01532 filelength=len(filesToRun)
01533 if (filelength==0):
01534
01535 if (self.lumiBlockRange.get()<>"All"):
01536 self.filesInDBS[i].currentLumiBlock=self.filesInDBS[i].currentLumiBlock+int(self.lumiBlockRange.get())
01537 self.commentLabel.configure(text = "<ERROR> No files found for run %i!"%i)
01538 self.commentLabel.update_idletasks()
01539 time.sleep(2)
01540 return
01541
01542
01543
01544 if (string.atoi(self.cmsVersion[0])<2 or (string.atoi(self.cmsVersion[0])==2 and string.atoi(self.cmsVersion[1])==0)):
01545
01546 if os.path.isfile(os.path.join(self.basedir,".runOptions.cfi")):
01547 os.system("rm %s"%(os.path.join(self.basedir,".runOptions.cfi")))
01548 time.sleep(1)
01549
01550
01551 try:
01552 temp=open(os.path.join(self.basedir,".runOptions.cfi"),'w')
01553 except:
01554 self.commentLabel.configure(text="MAJOR ERROR! Could not write to .runOptions.cfi! \nCheck file/directory permissions!")
01555 self.dqmProgress.configure(text="FAILED! Couldn't write .runOptions.cfi")
01556 self.commentLabel.update_idletasks()
01557 time.sleep(2)
01558 return False
01559
01560
01561
01562
01563
01564 if (self.prescaleOverRun.get() and self.prescaleOverRunText<>"# prescale (unused) = "):
01565
01566
01567
01568 try:
01569
01570 prescaleVal=int(self.filesInDBS[i].totalEvents/self.maxDQMEvents.get())
01571 if (self.debug):
01572 print "Run #%i Total events = %i Max Events to run = %i Prescale = %i"%(i,self.filesInDBS[i].totalEvents, self.maxDQMEvents.get(),prescaleVal)
01573 if (prescaleVal>0):
01574 temp.write("%s %i\n\n"%(self.prescaleOverRunText,prescaleVal))
01575
01576 temp.write("replace maxEvents.input=%i\n"%self.filesInDBS[i].totalEvents)
01577
01578 except:
01579
01580 temp.write("replace maxEvents.input=%i\n"%self.maxDQMEvents.get())
01581
01582
01583
01584 else:
01585 temp.write("replace maxEvents.input=%i\n"%self.maxDQMEvents.get())
01586
01587 if (self.debug):
01588 print "run= ",i," lumi increment = ",self.lumiBlockRange.get()
01589
01590
01591
01592
01593
01594
01595 temp.write("replace PoolSource.fileNames={\n")
01596
01597 print "WRITING TO FILE!"
01598 for f in range(0,filelength):
01599 if (f>200):
01600 print "Skipping # ",f
01601
01602 if (f>200):
01603 continue
01604 temp.write("'%s'"%string.strip(filesToRun[f]))
01605 if (f==filelength-1):
01606 temp.write("\n")
01607 else:
01608 temp.write(",\n")
01609 temp.write("}\n")
01610 temp.close()
01611 os.system("chmod a+rw %s"%os.path.join(self.basedir,".runOptions.cfi"))
01612
01613
01614 if not (os.path.isfile(os.path.join(self.basedir,".runOptions.cfi"))):
01615 self.commentLabel.configure(text="Could not find .runOptions.cfi file\nFor run #%i"%i)
01616 self.commentLabel.update_idletasks()
01617 time.sleep(2)
01618 return False
01619
01620
01621
01622 else:
01623 tempinput=open(self.cfgFileName.get(),'r').readlines()
01624 tempoutput=[]
01625 temp_inreplaceloop=False
01626
01627 for myline in tempinput:
01628 if (temp_inreplaceloop==False):
01629 tempoutput.append(myline)
01630 if (string.find(myline,"###<<<<<<<<<<")>-1):
01631 temp_inreplaceloop=True
01632
01633 tempoutput.append("process.maxEvents=cms.untracked.PSet(input = cms.untracked.int32(%i))\n"%self.maxDQMEvents.get())
01634
01635 tempoutput.append('process.source = cms.Source("PoolSource",\n')
01636 tempoutput.append('\tfileNames= cms.untracked.vstring(\n')
01637 for f in range(0,filelength):
01638 if (f==filelength-1 or f==250):
01639 tempoutput.append("\t\t'%s')\n"%string.strip(filesToRun[f]))
01640 break
01641 else:
01642 tempoutput.append("\t\t'%s',\n"%string.strip(filesToRun[f]))
01643 tempoutput.append("\t)\n")
01644 if (string.find(myline,"###>>>>>>>>>>>")>-1):
01645 temp_inreplaceloop=False
01646 tempoutput.append(myline)
01647
01648 newcfg=open(self.cfgFileName.get(),'w')
01649 for zzz in tempoutput:
01650 newcfg.write(zzz)
01651 newcfg.close()
01652
01653
01654
01655 os.system("cmsRun %s"%self.cfgFileName.get())
01656
01657
01658
01659 success=self.getcmsRunOutput(i)
01660
01661 if (self.debug):
01662 print "Were all expected files found? ",success
01663 if (success):
01664 for myobject in self.cmsRunOutput:
01665
01666 if (
01667 self.finalDir.get()<>self.basedir
01668 ):
01669
01670 if (self.debug):
01671 print "myobject = ",myobject
01672 print "BaseName = ",os.path.basename(myobject)
01673
01674
01675 if os.path.exists(os.path.join(self.finalDir.get(),os.path.basename(myobject))):
01676 os.system("rm -rf %s"%os.path.join(self.finalDir.get(),os.path.basename(myobject)))
01677
01678
01679 os.system("mv %s %s"%(myobject,os.path.join(self.finalDir.get(),os.path.basename(myobject))))
01680
01681
01682
01683 statusname="HcalDQMstatus_%i.txt"%i
01684 if os.path.isfile(statusname):
01685 os.system("mv %s %s/%s"%(statusname,self.finalDir.get(),statusname))
01686
01687
01688
01689
01690
01691
01692
01693 self.commentLabel.configure(text = "moved %s\n to directory %s"%(myobject,
01694 self.finalDir.get()))
01695 self.commentLabel.update_idletasks()
01696 else:
01697
01698 self.commentLabel.configure(text="%s output created in \n%s"%(os.path.basename(myobject), self.basedir))
01699 self.commentLabel.update_idletasks()
01700 time.sleep(3)
01701
01702
01703
01704
01705
01706 else:
01707 self.commentLabel.configure(text="ERROR -- did not retrieve all expected output from cmsRun")
01708 self.commentLabel.update_idletasks()
01709 time.sleep(3)
01710
01711 if self.debug:
01712 print "<CallDQMScript> Success = %s"%success
01713
01714 return success
01715
01716
01717
01718 def getcmsRunOutput(self,runnum):
01719 '''
01720 ** self.getcmsRunOutput(runnum) **
01721 Looks for all the output files, directories that should be
01722 produced by cmsRun call for run #(runnum).
01723 Returns a boolean = whether or not all files and directories have
01724 been found.
01725 '''
01726
01727 if (self.debug):
01728 print self.getcmsRunOutput.__doc__
01729
01730 success=True
01731
01732 self.cmsRunOutput=[]
01733 if (runnum<100000):
01734 outname="DQM_Hcal_R0000%i"%runnum
01735 else:
01736 outname="DQM_Hcal_R000%i"%runnum
01737
01738
01739 if (self.debug):
01740 print "%s exists? %i"%(os.path.join(self.basedir,outname),os.path.isdir(os.path.join(self.basedir,outname)))
01741
01742 outputdir=os.path.join(self.basedir,outname)
01743
01744 success=success and (os.path.isdir(outputdir))
01745
01746 if (success):
01747 if (self.debug):
01748 print "<getcmsRunOutput> success=True!"
01749
01750 if (self.lumiBlockRange.get()<>"All"):
01751
01752 newdirname="%s_L%i_%i"%(outputdir,self.filesInDBS[runnum].currentLumiBlock,
01753
01754 min(self.filesInDBS[runnum].currentLumiBlock+int(self.lumiBlockRange.get())-1,
01755 self.filesInDBS[runnum].numLumiBlocks)
01756 )
01757 os.system("mv %s %s"%(outputdir,newdirname))
01758 outputdir=newdirname
01759 self.cmsRunOutput.append(outputdir)
01760
01761
01762
01763 if (runnum<100000):
01764 outname="DQM_V0001_Hcal_R0000%i"%runnum
01765 else:
01766 outname="DQM_V0001_Hcal_R000%i"%runnum
01767 outputroot="%s.root"%(os.path.join(self.basedir,outname))
01768
01769
01770
01771 success=success and (os.path.exists(outputroot))
01772 if os.path.exists(outputroot):
01773
01774
01775 if (self.lumiBlockRange.get()<>"All"):
01776 newfilename="%s_L%i_%i.root"%(os.path.join(self.basedir,outname),
01777 self.filesInDBS[runnum].currentLumiBlock,
01778
01779 min(self.filesInDBS[runnum].currentLumiBlock+int(self.lumiBlockRange.get())-1,
01780 self.filesInDBS[runnum].numLumiBlocks)
01781 )
01782 os.system("mv %s %s"%(outputroot,newfilename))
01783 outputroot=newfilename
01784 self.cmsRunOutput.append(outputroot)
01785
01786
01787
01788 timingoutput="HcalTiming_run%i.root"%runnum
01789 if os.path.exists(timingoutput):
01790 self.cmsRunOutput.append(timingoutput)
01791
01792 if (self.debug):
01793 print "<getcmsRunOutput> The following cmsRun outputs were found:"
01794 for i in self.cmsRunOutput:
01795 print "\t%s"%i
01796 print "\nAll files found? %s"%success
01797
01798 return success
01799
01800
01801
01802
01803 def checkDBS(self):
01804 '''
01805 ** self.checkDBS() **
01806 Looks in DBS for files with given file/dataset names, and in specified run range.
01807 '''
01808
01809 if (self.debug):
01810 print self.checkDBS.__doc__
01811
01812 if (self.dbsSearchInProgress):
01813 self.commentLabel.configure(text="Sorry, a DBS search is already in progress at the moment")
01814 return False
01815
01816 self.dbsButton.configure(state=DISABLED)
01817 self.dbsSearchInProgress=True
01818 begin=self.lastFoundDBS.get()
01819 end=begin+self.dbsRange.get()
01820
01821 self.dbsProgress.configure(text="Checking DBS for runs %i-%i..."%(begin,end),
01822 bg=self.bg_alt)
01823 self.dbsStatus.configure(text="%s"%time.strftime("%d %b %Y at %H:%M:%S",time.localtime()))
01824
01825 self.commentLabel.configure(text="Checking DBS for runs in range %i-%i..."%(begin,end))
01826 self.commentLabel.update_idletasks()
01827 self.myDBS.searchDBS(begin,end)
01828
01829 if (self.parseDBSInfo()):
01830 self.commentLabel.configure(text="Finished checking DBS runs (%i-%i)\nFound a total of %i files"%(begin,end,self.foundfiles))
01831
01832 self.dbsSearchInProgress=False
01833 self.dbsButton.configure(state=NORMAL)
01834 return True
01835
01836
01837 def parseDBSInfo(self):
01838 '''
01839 ** self.parseDBSInfo() **
01840 Once we've checked DBS, let's parse the output for runs!
01841 We'll get info by checking DBS for all run numbers within range.
01842 Then, for each found run number, we'll grab all the files for that run number
01843 '''
01844
01845 if (self.debug):
01846 print self.parseDBSInfo.__doc__
01847
01848
01849 hcalrunlist=[]
01850
01851
01852 if (self.dbsSetHcalValue.get()=="Only runs including HCAL"):
01853 hcalRunSummary=pyRunSummaryBaseClass.goodHCALList(self.lastFoundDBS.get(),self.lastFoundDBS.get()+self.dbsRange.get(),debug=False)
01854 hcalrunlist=hcalRunSummary.hcalruns
01855 if (self.debug):
01856 print hcalRunSummary.allruns
01857
01858
01859 runlist=[]
01860 begin=self.lastFoundDBS.get()
01861 end=begin+self.dbsRange.get()
01862 runs=string.split(self.myDBS.searchResult,"\n")
01863
01864 for r in runs:
01865 if (len(r)==0):
01866 continue
01867
01868 if (r.startswith("Found")):
01869
01870 self.foundfiles=string.atoi(string.split(r)[1])
01871 if (self.foundfiles==0):
01872 self.commentLabel.configure(text="WARNING! No runs found in the run range %i-%i"%(self.lastFoundDBS.get(),self.lastFoundDBS.get()+self.dbsRange.get()))
01873 self.dbsProgress.configure(text="No runs found in range %i-%i"%(self.lastFoundDBS.get(),self.lastFoundDBS.get()+self.dbsRange.get()),
01874 bg="black")
01875 self.commentLabel.update_idletasks()
01876 return False
01877
01878 try:
01879 r.strip("\n")
01880 r=string.atoi(r)
01881
01882 if r not in runlist:
01883
01884
01885 if (self.dbsSetHcalValue.get()=="Only runs including HCAL"):
01886 if r not in hcalrunlist:
01887 continue
01888 runlist.append(r)
01889 except:
01890 continue
01891
01892
01893
01894 if len(runlist)==0:
01895 self.commentLabel.configure(text="ODD BEHAVIOR! Runs apparently found, but cannot be parsed!\nIt's possible runs did not contain HCAL -- DBS output being redirected to screen")
01896
01897 print "DBS Run search result: ",self.myDBS.searchResult
01898 print "\n\nRunSummary page search result (Valid Hcal Runs): "
01899 for iii in hcalrunlist:
01900 print iii
01901 self.dbsProgress.configure(text="No runs in (%i-%i) could be parsed!"%(self.lastFoundDBS.get(),self.lastFoundDBS.get()+self.dbsRange.get()),
01902 bg="black")
01903 self.commentLabel.update_idletasks()
01904 return False
01905
01906
01907
01908
01909 self.foundfiles=0
01910 badcount=0
01911 for r in runlist:
01912
01913 self.dbsProgress.configure(text="Found run %i in range (%i-%i)..."%(r,self.lastFoundDBS.get(),self.lastFoundDBS.get()+self.dbsRange.get()))
01914 self.commentLabel.update_idletasks()
01915
01916 tempfiles=[]
01917
01918
01919 x=dbsAccessor(debug=self.debug)
01920 x.host.set(self.myDBS.host.get())
01921 x.port.set(self.myDBS.port.get())
01922 x.dbsInst.set(self.myDBS.dbsInst.get())
01923 x.searchStringFile.set(self.myDBS.searchStringFile.get())
01924 x.searchStringDataset.set(self.myDBS.searchStringDataset.get())
01925 x.page.set(self.myDBS.page.get())
01926 x.limit.set(self.myDBS.limit.get())
01927 x.xml.set(self.myDBS.xml.get())
01928 x.case.set(self.myDBS.case.get())
01929 x.details.set(self.myDBS.details.get())
01930 x.debug.set(self.myDBS.debug.get())
01931
01932 x.site.set("")
01933
01934
01935
01936 text="find file,file.numevents,lumi,dataset where %s run=%i"%(self.myDBS.formParsedString(),r)
01937
01938 x.searchDBS(mytext=text)
01939
01940 searchfiles=string.split(x.searchResult,"\n")
01941 if (self.debug):
01942 print "File,numevents,lumi,dataset search output = ",searchfiles
01943 dataset=None
01944
01945 for searchfile in searchfiles:
01946
01947
01948 if len(searchfile)==0:
01949 continue
01950
01951
01952
01953
01954 if (searchfile.startswith("Found")):
01955 self.foundfiles=self.foundfiles+string.atoi(string.split(searchfile)[1])
01956 if (self.foundfiles==0):
01957 self.commentLabel.configure(text="WARNING! No files found for run # %i"%r)
01958 self.dbsProgress.configure(text="No files found for run # %i"%r,
01959 bg="black")
01960 self.commentLabel.update_idletasks()
01961
01962 continue
01963 else:
01964 if (self.debug): print "\tFile,dataset,lumi search output = ",searchfile
01965 try:
01966 i=string.split(searchfile,",")
01967 if (i[0].endswith(".root")):
01968 tempFileInfo=FileInfo(searchfile)
01969 if (tempFileInfo.goodFile==False):
01970 self.commentLabel.configure(text="Could not properly parse DBS entry:\n'%s'"%i)
01971 badcount=badcount+1
01972 if (self.debug):
01973 print "Could not properly parse DBS entry: %s"%i
01974 self.commentLabel.update_idletasks()
01975 else:
01976 tempfiles.append(tempFileInfo)
01977 else:
01978 self.commentLabel.configure(text="Could not recognize DBS entry:\n'%s'"%i)
01979 badcount=badcount+1
01980 if (self.debug):
01981 print "Could not parse DBS entry: %s"%i
01982 self.commentLabel.update_idletasks()
01983
01984 except SyntaxError:
01985 self.commentLabel.configure(text="Could not parse DBS entry:\n'%s'"%i)
01986 badcount=badcount+1
01987 print "Could not parse DBS entry: %s"%i
01988 self.commentLabel.update_idletasks()
01989
01990 if len(tempfiles)==0:
01991
01992 self.commentLabel.configure(text="No valid files found for run # %i"%r)
01993 self.commentLabel.update_idletasks()
01994 continue
01995 tempDBS=DBSRun()
01996 tempDBS.runnum=r
01997 tempDBS.maxEvents=self.maxDQMEvents.get()
01998 for fileobject in tempfiles:
01999 tempDBS.AddFileInfo(fileobject)
02000 tempDBS.UpdateRunInfo()
02001
02002
02003 if r not in self.filesInDBS.keys():
02004 self.filesInDBS[r]=tempDBS
02005 else:
02006
02007 for f in tempfiles:
02008
02009 if f.fileName not in self.filesInDBS[r].files:
02010 self.filesInDBS[r].fileInfo.append(f)
02011
02012 self.filesInDBS[r].UpdateRunInfo()
02013
02014
02015 tmpvar=self.lumiBlockRange.get()
02016 if (tmpvar=="All"):
02017 tmpvar="0"
02018 self.filesInDBS[r].lumiBlockIncrement=string.atoi(tmpvar)
02019
02020
02021
02022 if len(self.filesInDBS.keys()):
02023 x=self.filesInDBS.keys()
02024 x.sort()
02025 x.reverse()
02026 if (self.autoRunShift):
02027 self.lastFoundDBS.set(x[0]+1)
02028
02029
02030
02031
02032
02033
02034 self.writePickle()
02035
02036 if (self.foundfiles>self.myDBS.limit.get()):
02037 self.commentLabel.configure(text="WARNING! A total of %i files were found in DBS, but the current DBS limit is set to %i. \nConsider increasing your DBS limit, or running on a smaller range of runs."%(self.foundfiles,self.myDBS.limit.get()))
02038 self.dbsProgress.configure(text="%i files found; only %i stored!"%(foundfiles,self.myDBS.limit.get()),
02039 bg="black")
02040 self.commentLabel.update_idletasks()
02041 return False
02042
02043 if badcount:
02044 self.dbsProgress.configure(text="%i lines from DBS could not be parsed!"%badcount)
02045 self.commentLabel.update_idletasks()
02046 return False
02047
02048 self.dbsProgress.configure(text="Successfully grabbed runs %i-%i"%(begin,end),
02049 bg="black")
02050 self.commentLabel.update_idletasks()
02051
02052 return True
02053
02054
02055
02056 def displayFiles(self):
02057 '''
02058 ** self.displayFiles() **
02059 Show all run numbers that have been found from DBS, along with the
02060 DQM status of each run.
02061 '''
02062
02063 if (self.debug):
02064 print self.displayFiles.__doc__
02065
02066
02067 x=self.filesInDBS.keys()
02068 x.sort()
02069 x.reverse()
02070 temp ="%10s %35s%10s%10s %10s%12s%15s%15s %20s\n"%(" Run #", "Dataset"," ",
02071 "# of files","#events","IgnoreRun?",
02072 "Started DQM?","Finished DQM?","Starting Lumiblock")
02073
02074 for i in x:
02075 temp=temp+self.filesInDBS[i].Print()
02076
02077 if (len(x)<>1):
02078 title="A total of %i runs have been found in DBS"%len(x)
02079 else:
02080 title="A total of 1 run has been found in DBS"
02081 helpfunctions.Helpwin(temp,usetext=1,title=title )
02082 return
02083
02084
02085 def changeFileSettings(self):
02086 '''
02087 ** self.changeFileSettings() **
02088 Allows user to change the DQM status of the runs found from DBS.
02089 (Mark runs as having already completed DQM, set ignoreRun true, etc.)
02090 '''
02091
02092 if (self.debug):
02093 print self.changeFileSettings.__doc__
02094
02095
02096 try:
02097 self.changevaluewin.destroy()
02098 self.changevaluewin=Toplevel()
02099 except:
02100 self.changevaluewin=Toplevel()
02101
02102 maingeom=self.root.winfo_geometry()
02103 maingeomx=string.split(maingeom,"+")[1]
02104 maingeomy=string.split(maingeom,"+")[2]
02105 try:
02106 maingeomx=string.atoi(maingeomx)
02107 maingeomy=string.atoi(maingeomy)
02108
02109
02110 if (self.root.winfo_screenheight()-(maingeomy+250)>350):
02111 self.changevaluewin.geometry('+%i+%i'%(maingeomx,maingeomy+250))
02112 elif (maingeomy>380):
02113 self.changevaluewin.geometry('+%i+%i'%(maingeomx,maingeomy-380))
02114 except:
02115 self.changevaluewin.geometry('+500+320')
02116
02117
02118 self.changevaluewin.title("Change status of files")
02119
02120
02121
02122 self.changevaluewin.rowconfigure(0,weight=1)
02123 self.changevaluewin.columnconfigure(0,weight=1)
02124 scrollwin=Frame(self.changevaluewin)
02125 scrollwin.grid(row=0,column=0,sticky=NSEW)
02126 scrollwin.rowconfigure(1,weight=1)
02127 scrollwin.columnconfigure(0,weight=1)
02128 myrow=0
02129 temp = "%s%s%s%s%s%s"%(string.ljust(" Run #",20),
02130 string.ljust("Started DQM?",20),string.ljust("Finished DQM?",20),
02131 string.ljust("IgnoreRun?",20),string.ljust("# of files",20),
02132 string.ljust("Dataset",30))
02133 Label(scrollwin,
02134 text=temp).grid(row=myrow,column=0,sticky=W)
02135 myrow=myrow+1
02136 self.lb=Listbox(scrollwin,
02137 bg="white",
02138 selectmode = MULTIPLE)
02139
02140 self.listboxruns=self.filesInDBS.keys()
02141 self.listboxruns.sort()
02142 self.listboxruns.reverse()
02143
02144 for i in self.listboxruns:
02145 self.lb.insert(END,self.filesInDBS[i].Print2(screenoutput=self.debug))
02146
02147 scroll=Scrollbar(scrollwin,command=self.lb.yview)
02148
02149 self.lb.configure(yscrollcommand=scroll.set)
02150
02151 xscroll=Scrollbar(scrollwin,command=self.lb.xview,
02152 orient=HORIZONTAL)
02153 self.lb.configure(xscrollcommand=xscroll.set)
02154
02155 self.lb.grid(row=myrow,column=0,sticky=NSEW)
02156 scroll.grid(row=myrow,column=1,sticky=NS)
02157 myrow=myrow+1
02158 xscroll.grid(row=myrow,column=0,sticky=EW)
02159
02160
02161 myrow=myrow+1
02162
02163 bFrame=Frame(self.changevaluewin)
02164 bFrame.grid(row=1,column=0)
02165 igY=Button(bFrame,
02166 text="Set\n'Ignore Run'\nTrue",
02167 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02168 "ignoreRun",True),
02169 width=14,height=3)
02170 igN=Button(bFrame,
02171 text="Set\n'Ignore Run'\nFalse",
02172 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02173 "ignoreRun",False),
02174 width=14,height=3)
02175 stY=Button(bFrame,
02176 text="Set\n'Started DQM'\nTrue",
02177 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02178 "startedDQM",True),
02179 width=14,height=3)
02180 stN=Button(bFrame,
02181 text="Set\n'Started DQM'\nFalse",
02182 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02183 "startedDQM",False),
02184 width=14,height=3)
02185 fiY=Button(bFrame,
02186 text="Set\n'Finished DQM'\nTrue",
02187 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02188 "finishedDQM",True),
02189 width=14,height=3)
02190 fiN=Button(bFrame,
02191 text="Set\n'Finished DQM'\nFalse",
02192 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02193 "finishedDQM",False),
02194 width=14,height=3)
02195 selAll=Button(bFrame,
02196 text="Select\nall runs",
02197 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02198 "selectall",True),
02199 width=14,height=3)
02200 deselAll=Button(bFrame,
02201 text="Deselect\nall runs",
02202 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02203 "deselectall",False),
02204 width=14,height=3)
02205 dbsSearch=Button(bFrame,
02206 text="Search\nDBS for new\nruns",
02207 bg=self.bg,
02208 fg=self.fg,
02209 command=lambda x=self:x.commandChangeFileSettings(self.lb.curselection(),
02210 "searchDBS",False))
02211
02212 quitButton=Button(bFrame,
02213 text="Close\nwindow",
02214 bg=self.bg_alt,
02215 fg=self.bg,
02216 command=lambda x=self:x.changevaluewin.destroy())
02217
02218 igY.grid(row=0,column=3)
02219 stY.grid(row=0,column=1)
02220 fiY.grid(row=0,column=2)
02221 igN.grid(row=1,column=3)
02222 stN.grid(row=1,column=1)
02223 fiN.grid(row=1,column=2)
02224 selAll.grid(row=0,column=4)
02225 deselAll.grid(row=1,column=4)
02226 dbsSearch.grid(row=0,column=0,rowspan=2,sticky=NS)
02227 quitButton.grid(row=0,column=5,rowspan=2,sticky=NS)
02228
02229 return
02230
02231
02232 def updateListbox(self):
02233 '''
02234 ** self.updateListbox() **
02235 Grabs updated run info from self.filesInDBS.keys
02236 and displays it in listbox.
02237 '''
02238
02239 if (self.debug):
02240 print self.updateListbox.__doc__
02241
02242 self.lb.delete(0,END)
02243 temp = "%s%s%s%s%s%s"%(string.ljust(" Run #",20),
02244 string.ljust("Started DQM?",20),string.ljust("Finished DQM?",20),
02245 string.ljust("IgnoreRun?",20),string.ljust("# of files",20),
02246 string.ljust("Dataset",80))
02247
02248
02249 self.listboxruns=self.filesInDBS.keys()
02250 self.listboxruns.sort()
02251 self.listboxruns.reverse()
02252
02253 for i in self.listboxruns:
02254
02255 self.lb.insert(END,self.filesInDBS[i].Print2(screenoutput=self.debug))
02256 return
02257
02258 def commandChangeFileSettings(self,selected,var,value=True):
02259 '''
02260 ** self.commandChangeFileSettings(selected, var, value=True) **
02261 Commands for changing DQM settings.
02262 "selected" is the set of listbox indices that have been
02263 highlighted by the user.
02264 (self.listboxruns[int(i)] returns the associated run #, for
02265 all i in selected.)
02266 Allowed options for var:
02267 "ignoreRun", "startedDQM", "finishedDQM", "selectall", "deselectall"
02268 Value indicates whether var should be set True or False. Default is True.
02269 '''
02270
02271 if (self.debug):
02272 print self.commandChangeFileSettings.__doc__
02273
02274 if (var=="selectall"):
02275 for i in range(0,self.lb.size()):
02276 self.lb.selection_set(i)
02277 return
02278 elif (var=="deselectall"):
02279 for i in range(0,self.lb.size()):
02280 self.lb.selection_clear(i)
02281 return
02282
02283 for i in selected:
02284 run=self.listboxruns[int(i)]
02285
02286 if (var=="ignoreRun"):
02287 self.filesInDBS[run].ignoreRun=value
02288 elif (var=="startedDQM"):
02289 self.filesInDBS[run].startedDQM=value
02290 self.filesInDBS[run].currentLumiBlock=1
02291 elif (var=="finishedDQM"):
02292 self.filesInDBS[run].finishedDQM=value
02293
02294 if (var=="searchDBS"):
02295 self.checkDBS()
02296 self.writePickle()
02297 self.updateListbox()
02298 return
02299
02300
02301 def toggleSCP(self):
02302
02303 '''
02304 ** self.toggleSCP() **
02305 configures scp label based on self.enableSCP value.
02306 If SCP variable is off, no scp copying will take place.'''
02307
02308 if (self.debug):
02309 print self.toggleSCP.__doc__
02310
02311 if (self.enableSCP.get()==0):
02312 self.scpAutoButton.configure(text="scp copying disabled")
02313 self.copyLoc.configure(state=DISABLED)
02314 else:
02315 self.scpAutoButton.configure(text="scp copying enabled")
02316 self.copyLoc.configure(state=NORMAL)
02317 return
02318
02319
02320 def toggleAutoDBS(self):
02321 '''
02322 ** self.toggleSCP() **
02323 Changes DBS Auto update label based on state of self.dbsAutoVar.
02324 '''
02325
02326 if (self.debug):
02327 print self.toggleAutoDBS.__doc__
02328
02329 if (self.Automated.get()==False):
02330 self.dbsAutoButton.configure(text="Auto DQM\nupdate OFF",state=DISABLED)
02331 return
02332
02333 if self.dbsAutoVar.get()==0 :
02334 self.dbsAutoButton.configure(text="Auto DBS\nupdate OFF")
02335 else:
02336 self.dbsAutoButton.configure(text="Auto DBS update\nevery %s minutes"%self.dbsAutoUpdateTime.get())
02337
02338 return
02339
02340 def toggleAutoDQM(self):
02341 '''
02342 ** self.toggleAutoDQM() **
02343 Changes DQM Auto update label based on state of self.dqmAutoVar.
02344 '''
02345
02346 if (self.debug):
02347 print self.toggleAutoDQM.__doc__
02348
02349 if (self.Automated.get()==False):
02350 self.dqmAutoButton.configure(text="Auto DQM\nupdate OFF",state=DISABLED)
02351 return
02352 if self.dqmAutoVar.get()==0 :
02353 self.dqmAutoButton.configure(text="Auto DQM\nupdate OFF")
02354 else:
02355 self.dqmAutoButton.configure(text="Auto DQM update\nevery %s minutes"%self.dqmAutoUpdateTime.get())
02356
02357 return
02358
02359
02360 def toggleAutoRunShift(self,event):
02361 '''
02362 ** self.toggleAutoRunShift(event) **
02363 This toggles the autoRunShift variable.
02364 If autoRunShift is true, then the run entry
02365 value will increment whenever a new run is found.
02366 If not, the run entry value will remain the same.
02367 '''
02368
02369 if (self.debug):
02370 print self.toggleAutoRunShift.__doc__
02371
02372 self.autoRunShift=1-self.autoRunShift
02373
02374 if (self.autoRunShift==False):
02375 self.lastFoundDBSEntry.configure(bg="yellow")
02376 else:
02377 self.lastFoundDBSEntry.configure(bg="white")
02378 return
02379
02380
02381 def checkExistence(self,obj):
02382 '''
02383 ** self.checkExistence(obj) **
02384 Checks to see whether file/dir "obj" exists.
02385 Returns true/false boolean based on object existence.
02386
02387 '''
02388
02389 if (self.debug):
02390 print self.checkExistence.__doc__
02391 print obj.get()
02392 exists=True
02393 if not os.path.exists(obj.get()):
02394 self.commentLabel.configure(text="ERROR!\n Object '%s' does not exist!"%obj.get())
02395 self.commentLabel.update_idletasks()
02396 obj.set("ERROR -- FILE/DIR DOES NOT EXIST")
02397 exists=False
02398 else:
02399 self.commentLabel.configure(text="Set value to '%s'"%obj.get())
02400 self.commentLabel.update_idletasks()
02401 return exists
02402
02403 def tempSCP(self):
02404 '''
02405 ** self.tempSCP() **
02406 Temporary method for running scp from local final directory
02407 to hcalusc55@cmshcal01:hcaldqm/global_auto/
02408 This feature has now been disabled
02409 '''
02410
02411 if (self.debug):
02412 print self.tempSCP.__doc__
02413
02414 if (self.debug):
02415 self.commentLabel.configure(text="scp copying is no longer used")
02416 self.commentLabel.update_idletasks()
02417 return
02418
02419
02420 if not (self.enableSCP.get()):
02421 self.commentLabel.configure(text="scp copying is not currently enabled.\n(Check button in the middle of the menu bar)")
02422 self.commentLabel.update_idletasks()
02423 return
02424
02425 if not (os.path.exists(self.finalDir.get())):
02426 self.commentLabel.configure(text="ERROR -- directory '%s' DOES NOT EXIST!!\nEdit the Final DQM Save Directory in DQM options!"%self.finalDir.get())
02427 return
02428
02429 self.commentLabel.configure(text="Trying to scp results to cmshcal01")
02430 self.commentLabel.update_idletasks()
02431
02432
02433 if not os.path.isdir(os.path.join(self.finalDir.get(),"copied_to_hcaldqm")):
02434 os.mkdir(os.path.join(self.finalDir.get(),"copied_to_hcaldqm"))
02435
02436 movelist=os.listdir(self.finalDir.get())
02437 movelist.remove("copied_to_hcaldqm")
02438 if len(movelist)==0:
02439 self.commentLabel.configure(text="There are no files in %s\n to be copied to cmshcal01!"%self.finalDir.get())
02440 self.commentLabel.update_idletasks()
02441 return
02442 text1="scp -r "
02443 text="scp -r "
02444 for i in movelist:
02445 text=text+"%s "%os.path.join(self.finalDir.get(),"copied_to_hcaldqm",i)
02446 text1=text1+"%s "%os.path.join(self.finalDir.get(),i)
02447 text=text+" hcalusc55@cmshcal01:/hcaldqm/global_auto\n\n"
02448 text1=text1+" hcalusc55@cmshcal01:/hcaldqm/global_auto\n\n"
02449
02450
02451
02452
02453 compname=os.uname()[1]
02454
02455 if (string.find(compname,"lxplus")>-1 or string.find(compname,"lxb")) and string.find(compname,".cern.ch")>-1:
02456 zzz=os.system(text1)
02457 print text1
02458
02459 self.commentLabel.configure(text = "FINISHED!\nPerformed scp of files to cmshcal01!")
02460 self.commentLabel.update_idletasks()
02461
02462 else:
02463 helpfunctions.Helpwin(text,usetext=1,title="Cut and paste this command into your lxplus window now!" )
02464 self.commentLabel.configure(text="Cannot auto-scp to cmshcal from your machine!\nFollow instructions in the help window!")
02465 self.commentLabel.update_idletasks()
02466
02467
02468 for i in movelist:
02469 if os.path.isdir(os.path.join(self.finalDir.get(),"copied_to_hcaldqm",i)):
02470 os.system("rm -rf %s"%os.path.join(self.finalDir.get(),"copied_to_hcaldqm",i))
02471 cmd="mv %s %s\n"%(os.path.join(self.finalDir.get(),i),
02472 os.path.join(self.finalDir.get(),"copied_to_hcaldqm",i))
02473 os.system(cmd)
02474
02475 return
02476
02477
02478
02479 def dbsSetUpdateMenu(self,upTime,allTimes):
02480 '''
02481 ** self.dbsUpdateMenu(upTime, allTimes) **
02482 Sets colors in "Set DBS Option Time" menu, and configures the DBS auto button label.
02483 allTimes = list of all time options specified in the menu
02484 upTime = list index of chosen time.
02485 Chosen time appears in red; all other times in black
02486 '''
02487
02488 if (self.debug):
02489 print self.dbsSetUpdateMenu.__doc__
02490
02491 self.dbsAutoUpdateTime.set(allTimes[upTime])
02492 for i in range(len(allTimes)):
02493 if i==upTime:
02494 self.dbsUpdateMenu.choices.entryconfig(i,foreground="red")
02495 else:
02496 self.dbsUpdateMenu.choices.entryconfig(i,foreground="black")
02497 if (self.Automated.get()==True):
02498 self.dbsAutoButton.configure(state=NORMAL,text="Auto DBS update\nevery %s minutes"%self.dbsAutoUpdateTime.get(),
02499 bg=self.bg,fg=self.fg)
02500 return
02501
02502
02503 def dbsSetHcalOnly(self,value,choices):
02504 '''
02505 ** self.dbsSetHcalOnlyMenu(value, choices) **
02506 Sets colors in "Set Hcal Only" menu, and configures the bool for only
02507 checking runs in which HCAL was present.
02508 '''
02509
02510 if (self.debug):
02511 print self.dbsSetHcalOnly.__doc__
02512
02513 self.dbsSetHcalValue.set(value)
02514
02515 for i in range(len(choices)):
02516 if choices[i]==value:
02517 self.dbsHcalOnlyMenu.choices.entryconfig(i,foreground="red")
02518 else:
02519 self.dbsHcalOnlyMenu.choices.entryconfig(i,foreground="black")
02520 return
02521
02522
02523
02524
02525
02526
02527 def dqmSetUpdateMenu(self,upTime,allTimes):
02528 '''
02529 ** self.dqmUpdateMenu(upTime, allTimes) **
02530 Sets colors in "Set DQM Option Time" menu, and configures the DQM auto button label.
02531 allTimes = list of all time options specified in the menu
02532 upTime = list index of chosen time.
02533 Chosen time appears in red; all other times in black
02534 '''
02535
02536 if (self.debug):
02537 print self.dqmSetUpdateMenu.__doc__
02538
02539 self.dqmAutoUpdateTime.set(allTimes[upTime])
02540 for i in range(len(allTimes)):
02541 if i==upTime:
02542 self.dqmUpdateMenu.choices.entryconfig(i,foreground="red")
02543 else:
02544 self.dqmUpdateMenu.choices.entryconfig(i,foreground="black")
02545 if (self.Automated.get()==True):
02546 self.dqmAutoButton.configure(state=NORMAL,text="Auto DQM update\nevery %s minutes"%self.dqmAutoUpdateTime.get(),
02547 bg=self.bg,fg=self.fg)
02548 return
02549
02550
02551
02552 def setLumiBlockMenu(self,lumiChoice,allLumis):
02553 '''
02554 *** self.setLumiBlockMenu(lumiChoice, allLumis) ***
02555 Sets colors in "Set lum"y block range" menu,
02556 and sets value of self.lumiBlockRange variable.
02557 lumiChoice = index of chosen lumi range.
02558 allLumis = list of all possible choices.
02559 Will also set all the lumi choices for all previously-found runs to the selected value
02560 '''
02561
02562 if (self.debug):
02563 print self.setLumiBlockMenu.__doc__
02564
02565 self.lumiBlockRange.set(allLumis[lumiChoice])
02566 if (self.debug):
02567 print "Chosen lumi range = ",self.lumiBlockRange.get()
02568 for i in range(len(allLumis)):
02569 if i==lumiChoice:
02570 self.lumiBlockRangeMenu.choices.entryconfig(i,foreground="red")
02571 else:
02572 self.lumiBlockRangeMenu.choices.entryconfig(i,foreground="black")
02573 choice=self.lumiBlockRange.get()
02574 if choice=="All":
02575 choice="0"
02576
02577 for r in self.filesInDBS.keys():
02578
02579 totalevents=0
02580 for myfile in range(len(self.filesInDBS[r].fileInfo)):
02581 myval=self.filesInDBS[r].fileInfo[myfile].lumiBlock
02582
02583 if (choice=="0" or (myval>=self.filesInDBS[r].currentLumiBlock and myval<self.filesInDBS[r].currentLumiBlock+int(choice))):
02584
02585 totalevents=totalevents+self.filesInDBS[r].fileInfo[myfile].numEvents
02586 self.filesInDBS[r].totalEvents=totalevents
02587
02588
02589 self.filesInDBS[r].lumiBlockIncrement=string.atoi(choice)
02590
02591 if (self.debug):
02592 print "<setLumiBlockMenu> run # = %i, lumi block increment = %i"%(r, self.filesInDBS[r].lumiBlockIncrement)
02593 return
02594
02595
02596
02597 if __name__=="__main__":
02598
02599 mygui=dbsBaseGui(debug=1)
02600 mygui.DrawGUI()
02601 mygui.root.mainloop()
02602
02603
02604