ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/RateMonShiftTool_dev/MenuAnalyzer.py
Revision: 1.10
Committed: Mon Oct 1 09:42:31 2012 UTC (12 years, 6 months ago) by amott
Content type: text/x-python
Branch: MAIN
Changes since 1.9: +10 -0 lines
Log Message:
Added checks to see if things aren't valid

File Contents

# User Rev Content
1 amott 1.1 #!/usr/bin/env python
2    
3     import os
4     import sys
5     from DatabaseParser import ConnectDB
6     import re
7     import cx_Oracle
8 amott 1.5 import eventContent
9 amott 1.1
10     try: ## set is builtin in python 2.6.4 and sets is deprecated
11     set
12     except NameError:
13     from sets import Set
14    
15     class MenuAnalyzer:
16     def __init__(self,name):
17     ##default ranges
18     self.maxModuleNameLength = 300
19     self.maxModulesPerPath = 50
20     self.maxPaths = 500
21     self.maxEndPaths = 30
22    
23     ##required streams
24     self.requiredStreamsAndPDs = { 'Calibration' : ['TestEnablesEcalHcalDT'],'EcalCalibration' : ['EcalLaser'],
25 amott 1.3 'TrackerCalibration' : ['TestEnablesTracker'], 'DQM' : 'OnlineMonitor'}
26 amott 1.1 self.ExpressStreamName = 'Express'
27     self.expressPDs = { 'ExpressPhysics' : 'Collisions',
28     'ExpressCosmics' : 'Cosmics' }
29    
30     self.expressType = ''
31    
32     self.menuName = name
33     self.endPathList = set()
34     self.perPathModuleList={}
35     self.perModuleTypeList={}
36     self.perStreamPDList={}
37     self.perPDPathList={}
38     self.Results={}
39     self.ModuleList=[]
40 amott 1.6 self.ESModuleList=[]
41 amott 1.5 self.eventContent={}
42 amott 1.8 self.ParkingTriggers=[]
43     self.NotParkingTriggers=[]
44 amott 1.5
45 amott 1.1 self.AnalysisList=[]
46    
47    
48     ## statically define the analysis map: new analyses must be registered here
49     self.AnalysisMap = {
50     'moduleLength' : self.checkModuleLength,
51     'numberOfPaths' : self.checkNumPaths,
52     'numberOfEndPaths' : self.checkNumEndPaths,
53     'reqStreamsAndPDs' : self.reqStreamsAndPDs,
54     'checkExpress' : self.checkExpress,
55 amott 1.5 'checkNameFormats' :self.checkNameFormats,
56 amott 1.6 'checkEventContent':self.checkEventContent,
57 amott 1.8 'checkL1Unmask':self.checkL1Unmask,
58     'checkDQMStream':self.checkDQMStream,
59     'checkStreamB':self.checkStreamB
60 amott 1.1 }
61 amott 1.2 self.ProblemDescriptions = {
62     'moduleLength':'Modules too long',
63     'numberOfPaths':'Too many paths',
64     'numberOfEndPaths':'Too many endpaths',
65     'reqStreamsAndPDs':'Missing required stream/PD',
66     'checkExpress' : 'Invalid or missing express stream/PD',
67 amott 1.5 'checkNameFormats' : 'Invalid PD or path name format',
68 amott 1.6 'checkEventContent' : 'Invalid Event Content',
69 amott 1.8 'checkL1Unmask' : 'L1 Unmask Module in Menu',
70     'checkDQMStream' : 'Check that the DQM stream contains correct trigger',
71     'checkStreamB' : 'Check all parking triggers in stream B'
72 amott 1.2 }
73 amott 1.1
74     self.T0REGEXP = { ## These are the regexps that T0 uses to access things
75     # Regexp for save file name paths. We don't process anything else.
76     'RXSAFEPATH' : re.compile("^[-A-Za-z0-9_]+$"),
77     # Regexp for valid dataset names.
78     'RXDATASET' : re.compile("^[-A-Za-z0-9_]+$"),
79     # Regexp for valid RelVal dataset names.
80     'RXRELVALMC' : re.compile("^/RelVal[^/]+/(CMSSW(?:_[0-9]+)+(?:_pre[0-9]+)?)[-_].*$"),
81     'RXRELVALDATA' : re.compile("^/[^/]+/(CMSSW(?:_[0-9]+)+(?:_pre[0-9]+)?)[-_].*$"),
82     # Regexp for online DQM files.
83     'RXONLINE' : re.compile("^(?:.*/)?DQM_V(\d+)(_[A-Za-z0-9]+)?_R(\d+)\.root$"),
84     # Regexp for offline DQM files.
85     'RXOFFLINE' : re.compile("^(?:.*/)?DQM_V(\d+)_R(\d+)((?:__[-A-Za-z0-9_]+){3})\.root$"),
86     # Regexp for acquisition era part of the processed dataset name.
87     'RXERA' : re.compile("^([A-Za-z]+\d+|CMSSW(?:_[0-9]+)+(?:_pre[0-9]+)?)")
88     }
89    
90     def AddAnalysis(self,name):
91     self.AnalysisList.append(name)
92    
93     def AddAllAnalyses(self):
94     for name in self.AnalysisMap.iterkeys():
95     self.AddAnalysis(name)
96    
97     def Analyze(self):
98     cursor = ConnectDB('hlt')
99     self.GetModules(cursor)
100 amott 1.6 self.GetESModules(cursor)
101 amott 1.1 self.GetStreamsPathsPDs(cursor)
102 amott 1.5 self.GetEventContent(cursor)
103 amott 1.10 isError = False
104     if len(self.perStreamPDList) == 0:
105     print "FATAL ERROR: Cannot find any streams in this menu"
106     isError=True
107     if len(self.perPDPathList) ==0:
108     print "FATAL ERROR: Cannot find any PDs in this menu"
109     isError=True
110     if isError:
111     print "ABORTING"
112     sys.exit()
113 amott 1.8 self.findParkingTriggers()
114 amott 1.1 for analysis in self.AnalysisList:
115     if not self.AnalysisMap.has_key(analysis):
116     print "ERROR: Analysis %s not defined" % (analysis,)
117     continue
118     self.AnalysisMap[analysis]()
119    
120    
121     def checkModuleLength(self):
122     self.Results['moduleLength'] = []
123     for modName,type in self.perModuleTypeList.iteritems():
124     if len(modName) > self.maxModuleNameLength: self.Results['moduleLength'].append(modName)
125    
126     def checkNumPaths(self):
127     if len(self.perPathModuleList) > self.maxPaths:
128     self.Results['numberOfPaths'] = len(self.perPathModuleList)
129     else:
130     self.Results['numberOfPaths'] = 0
131     def checkNumEndPaths(self):
132     if len(self.endPathList) > self.maxEndPaths:
133     self.Results['numberOfEndPaths'] = len(self.endPathList)
134     else:
135     self.Results['numberOfEndPaths'] = 0
136     def reqStreamsAndPDs(self):
137     self.Results['reqStreamsAndPDs'] = []
138     for stream,PDList in self.requiredStreamsAndPDs.iteritems():
139     if not self.perStreamPDList.has_key(stream): self.Results['reqStreamsAndPDs'].append(stream)
140     for PD in PDList:
141     if not PD in self.requiredStreamsAndPDs[stream]: self.Results['reqStreamsAndPDs'].append(stream+'::'+PD)
142    
143     def checkExpress(self):
144     self.Results['checkExpress'] = []
145     if not self.perStreamPDList.has_key(self.ExpressStreamName):
146     self.Results['checkExpress'].append(self.ExpressStreamName)
147     return
148    
149     if len(self.perStreamPDList[self.ExpressStreamName]) >1:
150     self.Results['checkExpress'].append("MULTIPLE_PDS")
151     if len(self.perStreamPDList[self.ExpressStreamName]) <1:
152     self.Results['checkExpress'].append("NO_PDS")
153    
154     for PD in self.perStreamPDList[self.ExpressStreamName]:
155     if not self.expressPDs.has_key(PD):
156     self.Results['checkExpress'].append(self.ExpressStreamName+"::"+PD)
157     else:
158     self.expressType = self.expressPDs[PD]
159    
160    
161    
162     def checkNameFormats(self):
163     self.Results['checkNameFormats']=[]
164     for PD in self.perPDPathList.iterkeys():
165     if not self.T0REGEXP['RXDATASET'].match(PD):
166 amott 1.7 for k,v in self.perStreamPDList.iteritems():
167     if PD in v:
168     self.Results['checkNameFormats'].append(k+"::"+PD)
169     break
170    
171     self.Results['checkNameFormats'].append('NO STREAM::'+PD)
172 amott 1.1 for path in self.perPathModuleList.iterkeys():
173     if not self.T0REGEXP['RXSAFEPATH'].match(path):
174     self.Results['checkNameFormats'].append(path)
175 amott 1.5
176     def checkEventContent(self):
177     self.Results['checkEventContent']=[]
178     for stream,content in self.eventContent.iteritems():
179     #first check for a drop statement
180     if not ('drop *' in content or 'drop *_hlt*_*_*' in content):
181     self.Results['checkEventContent'].append(stream+'::drop *')
182     if not eventContent.requiredEventContent.has_key(stream): continue
183     requiredContent = eventContent.requiredEventContent[stream]
184     for entry in requiredContent:
185     if not entry in content:
186     self.Results['checkEventContent'].append(stream+'::'+entry)
187 amott 1.6
188     def checkL1Unmask(self):
189     self.Results['checkL1Unmask']=[]
190     if 'L1GtTriggerMaskAlgoTrigTrivialProducer' in self.ESModuleList:
191     self.Results['checkL1Unmask'].append('L1GtTriggerMaskAlgoTrigTrivialProducer')
192     if 'L1GtTriggerMaskTechTrigTrivialProducer' in self.ESModuleList:
193     self.Results['checkL1Unmask'].append('L1GtTriggerMaskTechTrigTrivialProducer')
194    
195 amott 1.8
196     def findParkingPDs(self):
197     ParkingPDs=[]
198     NotParkingPDs=[]
199     for PD in self.perStreamPDList["A"]: # look at PDs only in stream A
200     if PD.find("Parked")!=-1: #look for PDs with Parked in the name
201     ParkingPDs.append(PD)
202     else:
203     NotParkingPDs.append(PD)
204     return (ParkingPDs,NotParkingPDs)
205    
206     def findParkingTriggers(self):
207     ParkingPDs,NotParkingPDs = self.findParkingPDs()
208     for PD in NotParkingPDs:
209     for trig in self.perPDPathList[PD]: self.NotParkingTriggers.append(trig) # first append ALL triggers from the not in parking PDs
210     for PD in ParkingPDs:
211     for trig in self.perPDPathList[PD]:
212     if not trig in self.NotParkingTriggers: self.ParkingTriggers.append(trig) # get triggers that don't show up in the non-parking PDs
213    
214    
215     def checkDQMStream(self):
216     self.Results['checkDQMStream']=[]
217     for trig in self.NotParkingTriggers:
218 amott 1.9 if trig.find("LogMonitor")!=-1: continue
219 amott 1.8 if not trig in self.perPDPathList["OnlineMonitor"]: self.Results['checkDQMStream'].append("NotInDQM::%s"%trig)
220     for trig in self.ParkingTriggers:
221     if trig in self.perPDPathList["OnlineMonitor"]: self.Results['checkDQMStream'].append("ParkingTriggerInDQM::%s"%trig)
222    
223     def checkStreamB(self):
224     self.Results['checkStreamB']=[]
225     for trig in self.ParkingTriggers:
226     if not trig in self.perPDPathList["ParkingMonitor"]: self.Results['checkStreamB'].append("ParkingTriggerNotInStreamB::%s" %trig)
227    
228 amott 1.1 def GetModules(self,cursor):
229     sqlquery ="""
230     SELECT I.NAME,E.NAME,D.NAME,I.ISENDPATH
231     FROM
232     CMS_HLT.PARAMETERS B,
233     CMS_HLT.SUPERIDPARAMETERASSOC C,
234     CMS_HLT.MODULETEMPLATES D,
235     CMS_HLT.MODULES E,
236     CMS_HLT.PATHMODULEASSOC F,
237     CMS_HLT.CONFIGURATIONPATHASSOC G,
238     CMS_HLT.CONFIGURATIONS H,
239     CMS_HLT.PATHS I
240     WHERE
241     B.PARAMID = C.PARAMID AND
242     C.SUPERID = F.MODULEID AND
243     E.TEMPLATEID = D.SUPERID AND
244     F.MODULEID = E.SUPERID AND
245     F.PATHID=G.PATHID AND
246     I.PATHID=G.PATHID AND
247     G.CONFIGID=H.CONFIGID AND
248     H.CONFIGDESCRIPTOR='%s'
249     """ % (self.menuName,)
250    
251     cursor.execute(sqlquery)
252     for PathName,ModuleName,ModuleType,endPath in cursor.fetchall():
253     if not self.perPathModuleList.has_key(PathName): self.perPathModuleList[PathName] = []
254     self.perPathModuleList[PathName].append(ModuleName)
255     self.perModuleTypeList[ModuleName] = ModuleType
256 amott 1.6 if not ModuleName in self.ModuleList: self.ModuleList.append(ModuleName)
257 amott 1.1 if endPath: self.endPathList.add(PathName)
258    
259    
260     def GetStreamsPathsPDs(self,cursor):
261     sqlquery= """
262     SELECT A.STREAMLABEL,E.NAME,F.DATASETLABEL
263     FROM
264     CMS_HLT.STREAMS A,
265     CMS_HLT.CONFIGURATIONS B,
266     CMS_HLT.CONFIGURATIONPATHASSOC C,
267     CMS_HLT.PATHSTREAMDATASETASSOC D,
268     CMS_HLT.PATHS E,
269     CMS_HLT.PRIMARYDATASETS F
270     WHERE
271     B.CONFIGDESCRIPTOR='%s' AND
272     C.CONFIGID=B.CONFIGID AND
273     D.PATHID=C.PATHID AND
274     A.STREAMID=D.STREAMID AND
275     E.PATHID = C.PATHID AND
276     F.DATASETID = D.DATASETID
277     """ % (self.menuName,)
278    
279     cursor.execute(sqlquery)
280     for StreamName,PathName,PDName in cursor.fetchall():
281     if not self.perStreamPDList.has_key(StreamName): self.perStreamPDList[StreamName] = []
282     if not PDName in self.perStreamPDList[StreamName]: self.perStreamPDList[StreamName].append(PDName)
283     if not self.perPDPathList.has_key(PDName): self.perPDPathList[PDName] = []
284     self.perPDPathList[PDName].append(PathName)
285    
286 amott 1.6 def GetESModules(self,cursor):
287     sqlquery = """
288     SELECT UNIQUE(F.NAME)
289     FROM
290     CMS_HLT.ESMODULES F,
291     CMS_HLT.CONFIGURATIONESMODULEASSOC G,
292     CMS_HLT.CONFIGURATIONS H
293     WHERE
294     G.ESMODULEID = F.SUPERID AND
295     G.CONFIGID=H.CONFIGID AND
296     H.CONFIGDESCRIPTOR='%s'
297     """ % (self.menuName,)
298    
299     cursor.execute(sqlquery)
300     for ModuleName, in cursor.fetchall():
301     if not ModuleName in self.ESModuleList: self.ESModuleList.append(ModuleName)
302    
303 amott 1.4 def GetEventContent(self,cursor):
304 amott 1.5 sqlquery = """
305     SELECT A.STREAMLABEL,H.STATEMENTTYPE,H.CLASSN,H.MODULEL,H.EXTRAN,H.PROCESSN
306 amott 1.4 FROM
307     CMS_HLT.STREAMS A,
308     CMS_HLT.CONFIGURATIONS B,
309 amott 1.5 CMS_HLT.CONFIGURATIONPATHASSOC C,
310     CMS_HLT.PATHSTREAMDATASETASSOC D,
311     CMS_HLT.PATHS E,
312     CMS_HLT.ECSTREAMASSOC F,
313     CMS_HLT.ECSTATEMENTASSOC G,
314     CMS_HLT.EVENTCONTENTSTATEMENTS H
315 amott 1.4 WHERE
316     B.CONFIGDESCRIPTOR='%s' AND
317     C.CONFIGID=B.CONFIGID AND
318     D.PATHID=C.PATHID AND
319     A.STREAMID=D.STREAMID AND
320     E.PATHID = C.PATHID AND
321 amott 1.5 F.STREAMID = D.STREAMID AND
322     G.EVENTCONTENTID=F.EVENTCONTENTID AND
323     H.STATEMENTID=G.STATEMENTID
324 amott 1.4 """ % (self.menuName,)
325 amott 1.5
326     cursor.execute(sqlquery)
327     for stream,keep,Class,module,extra,process in cursor.fetchall():
328     if not self.eventContent.has_key(stream): self.eventContent[stream]=[]
329     statement = "%s_%s_%s_%s" % (Class,module,extra,process,)
330     if statement == "*_*_*_*": statement = "*"
331     if keep == 1: statement = "keep "+statement
332     else: statement = "drop "+statement
333     if not statement in self.eventContent[stream]:
334     self.eventContent[stream].append( statement )