4 from __future__
import print_function
5 from CoolRunQuery.selector.AtlRunQuerySelectorBase
import Selector, RunLBBasedCondition, OOO
6 from CoolRunQuery.utils.AtlRunQueryIOV
import IOVRange
7 from CoolRunQuery.utils.AtlRunQueryUtils
import coolDbConn
8 from CoolRunQuery.utils.AtlRunQueryLookup
import DQChannel
10 from collections
import defaultdict, namedtuple
12 DQDefectPayload = namedtuple(
"DQDefectPayload",
"defect comment user ignore primary tolerable recoverable")
13 DQDefectPayload.pickled = DQDefectPayload._asdict
15 DD = namedtuple(
"DD",
"description comment since until")
19 yield OOO(obj.channel, (
str(obj.Code),obj.Comment), IOVRange(starttime=obj.since, endtime=obj.until),
True)
23 super(DQSelector,self).
__init__(name)
26 from CoolRunQuery.AtlRunQuerySelectorWorker
import SelectorWorker
27 SelectorWorker.getRetrieveSelector(
'readyforphysics',
'ReadyForPhysicsSelector')
31 cf = chanAndfolder.split()
37 return (channel,folder)
42 if folder.startswith(
'DEFECTS'):
50 dq can be e.g. ['EMBA yellow SHIFTOFL', 'FCALA green+ DQMFOFL', 'EMBA,EMBC,EMECA,EMECC yellow+ SHIFTOFL']
51 this example should be translated into two selectors, one for each of the folders 'SHIFTOFL' and 'DQMFOFL'
53 folderCriteria = defaultdict(list)
56 folderCriteria[s[-1]].
append(s[:-1])
57 for f
in folderCriteria.keys():
58 if f.startswith(
'DEFECTS'):
60 self.
selectors[f].addSelectionChannels(folderCriteria[f])
68 condition.addShowChannel(folder, channel,
'HEAD')
90 runlist = sel.select(runlist)
95 sel.runAfterQuery(runlist)
101 code = {
'unknown': 0,
'red': 1,
'yellow': 2,
'green': 3,
'black': -1}
102 color = {
'n.a.':
'n.a.',
'0':
'U',
'1':
'R',
'2':
'Y',
'3':
'G',
'-1':
'B'}
103 invert = {
'n.a.': -2,
'B': -1,
'U': 0,
'R': 1,
'Y': 2,
'G': 3 }
115 dbname =
'COOLOFL_GLOBAL'
117 dbname =
'COOLONL_GLOBAL'
126 self.
flags += [(x+[
''])[1]]
152 super(DQCondition,self).
__init__(name=name,
153 dbfolderkey=
'%s::/GLOBAL/DETSTATUS/%s' % (dbname, self.
foldername),
154 channelKeys = channelKeys)
157 for flag
in self.
flags:
162 d[
'passFncName'] =
''
165 d[
'passFnc'] =
lambda x: x==-2
166 d[
'passFncName'] =
"x=='n.a.'"
167 elif flag[-1]
in '+-':
168 cd = self.
code[flag[:-1].lower()]
172 d[
'passFnc'] =
lambda x:
int(x)>=-1
174 d[
'passFnc'] =
lambda x:
int(x)>=0
176 d[
'passFnc'] =
lambda x:
int(x)>=1
178 d[
'passFnc'] =
lambda x:
int(x)>=2
180 d[
'passFnc'] =
lambda x:
int(x)>=3
181 d[
'passFncName'] =
"x>='%i'" % d[
'refVal']
184 d[
'passFnc'] =
lambda x:
int(x)<=-1
186 d[
'passFnc'] =
lambda x:
int(x)<=0
188 d[
'passFnc'] =
lambda x:
int(x)<=1
190 d[
'passFnc'] =
lambda x:
int(x)<=2
192 d[
'passFnc'] =
lambda x:
int(x)<=3
193 d[
'passFncName'] =
"x<='%i'" % d[
'refVal']
195 cd = self.
code[flag.lower()]
198 d[
'passFnc'] =
lambda x:
int(x)==-1
200 d[
'passFnc'] =
lambda x:
int(x)==0
202 d[
'passFnc'] =
lambda x:
int(x)==1
204 d[
'passFnc'] =
lambda x:
int(x)==2
206 d[
'passFnc'] =
lambda x:
int(x)==3
207 d[
'passFncName'] =
"x=='%i'" % d[
'refVal']
215 from CoolRunQuery.AtlRunQueryRun
import RunData
219 f = coolDbConn.GetDBConn(schema = self.schema,db=Selector.condDB()).getFolder(self.folder)
223 if f.versioningMode()==0:
225 if self.
tagname not in [
"HEAD",
""]:
232 objs =
vfgen(f.browseObjects( iovmin, iovmax, channels, self.
tagname ))
234 objs = super(DQCondition,self).
_retrieve(iovmin, iovmax, f, sortedRanges)
238 dqname = dqfullname.split(
':')[-1].
split(
'#')[0]
241 return self.
vfl.get_logic_list()[dqname].record.channel
242 except AttributeError:
243 return self.
vfl.get_logic_list()[dqname].channel
247 for i
in range(len(dqlist)):
248 dqs = dqlist[i][0].
split(
',')
255 dqlist[i][0] =
','.
join(newdqs)
259 vflags = vfl.get_logic_list().
keys()
260 useprimaries = cpflag[-1]==
'+'
261 cpflag=cpflag.rstrip(
'+')
271 if vf.startswith(cpflag):
278 raise RuntimeError(
"Virtual Flag pattern %s does not match any virtual flag: %r" % (cpflag, vfl.get_logic_list().
keys()))
287 from VirtualFlags
import VirtualFlagLogicFolder, VirtualFlagFolder
289 print (
"Can't import virtual flags")
291 traceback.print_exc()
294 self.
vfl = VirtualFlagLogicFolder(coolDbConn.GetDBConn(schema=schema, db=db))
300 from CoolRunQuery.AtlRunQueryRun
import Run
301 if cpflag
in Run.Fieldinfo:
303 Run.Fieldinfo[cpflag] =
'<strong><b>%s</b></strong><br><table width="300"><tr><td>%s</td></tr></div>' % \
304 (self.
vfl.get_logic_list()[cpflag].comment,
308 return self.
vfl.resolve_primary_flags(self.
vfl.resolve_dependancies([cpflag]))
318 tmplist = [[channelname,
'']]
321 for shch
in tmplist[0][0].
split(
','):
326 ssr = self.DoSelectShowRetrieve()
343 self.setChannelKeys(channelKeys,ssr)
346 if self.applySelection:
347 s =
"SELOUT Checking in the DQ folder %s" % self.
foldername
348 flagCh = defaultdict(list)
350 flagCh[flag].
append(
'(' +
' or '.
join(ch) +
')')
352 chlist =
' and '.
join(flagCh[flag])
353 s +=
"\nSELOUT %s is %r" % (chlist, flag)
360 if isinstance(values,tuple):
377 for k
in self.ResultKey():
379 for entry
in run.data[k]:
381 dqres = v[0]
if type(v)==tuple
else v
382 dqcode = self.
invert[dqres]
383 entry.rejected =
not passfnc( dqcode )
384 return super(DQCondition,self).
rejectRun(run)
389 if type(value)==tuple:
390 return (self.
color[value[0]], value[1])
392 return self.
color[value]
395 dqs = [
'G',
'Y',
'R',
'B',
'U',
'n.a.']
397 for k
in self.ResultKey():
403 for entry
in run.data[k]:
405 if entry.value ==
'n.a.':
406 dq, dqcomment = (
'n.a.',
'')
408 dq, dqcomment = entry.value
410 dq, dqcomment = (entry.value,
None)
413 if entry.startlb == 0:
415 if len(blocks) > 0
and blocks[-1][0]==(dq,dqcomment)
and blocks[-1][2]==entry.startlb:
416 blocks[-1][2] = entry.endlb
418 blocks += [ [(dq, dqcomment), entry.startlb, entry.endlb] ]
420 maxn =
max(n.values())
427 run.stats[k] = {
"counts" : n,
"max": dqmax,
"blocks": blocks }
438 super(DQDefectCondition,self).
__init__(name=name,
439 dbfolderkey =
'COOLOFL_GLOBAL::%s' % self.
foldername,
440 channelKeys = [(
'DQDEFECT',
'DQ',(
'Code',
'Comment'))])
442 self.data_keys[0]._second_internal_key = self.tagname
445 from CoolRunQuery.AtlRunQueryRun
import RunData
446 RunData.DefectSelector = self.
_pass
447 self.
__db = coolDbConn.GetDBConn(
'DEFECTS',self.tagname)
454 if x.value.ignore
is None:
455 these_defects += [x.value.defect]
457 these_defects += [x.value.defect+
'\\'+x.value.ignore]
465 passes = kk
not in these_defects
467 passes = k
in these_defects
483 newlitem.append(
'!' + db.normalize_defect_names(k[1:]))
485 newlitem.append(db.normalize_defect_names(k))
486 newl.append(newlitem)
492 """ based on the patterns in the list channel_name_patterns create a
493 list of pairs of patterns and matching defects ( pattern, set(matching defects) )
494 and attach it to the global Run.FieldInfo dictionary under 'DQ'
496 from re
import compile
497 from CoolRunQuery.AtlRunQueryRun
import Run
498 if 'DQ' not in Run.Fieldinfo:
499 Run.Fieldinfo[
'DQ'] = {}
500 if 'DefMatch' not in Run.Fieldinfo[
'DQ']:
501 Run.Fieldinfo[
'DQ'][
'DefMatch'] = []
502 Run.Fieldinfo[
'DQ'][
'IntolerableDefects'] = db.get_intolerable_defects(old_primary_only=
False)
504 for pattern
in channel_name_patterns:
505 if pattern.upper() !=
'DET':
506 cpattern = compile(pattern)
507 channelnames =
set(
filter(cpattern.match,db.defect_names))
508 channelnames.update(
filter(cpattern.match,db.virtual_defect_names))
510 channelnames =
set([d
for d
in db.defect_names
if '_' not in d])
511 channelnames.update([d
for d
in db.virtual_defect_names
if '_' not in d])
512 matches.update(channelnames)
513 Run.Fieldinfo[
'DQ'][
'DefMatch'] += [(pattern,channelnames)]
520 since = (runmin,iovmin&0xFFFFFFFF)
521 until = (runmax,iovmax&0xFFFFFFFF)
530 channels_with_ignore = {}
532 channels.update([x.lstrip(
'!')
for x
in selChans
if '\\' not in x])
537 if ignore_str
not in channels_with_ignore:
538 channels_with_ignore[ignore_str] = []
539 channels_with_ignore[ignore_str] += [channel.lstrip(
'!')]
542 if len(channels) + len(channels_with_ignore)==0:
546 if 'ANY' in channels:
547 channels.remove(
'ANY')
549 res = []
if len(channels)==0
else [ (db.retrieve(since=since, until=until, channels=channels, ignore=self.
global_ignore, with_primary_dependencies=
True).trim_iovs,
None) ]
552 for _ignore_str, _channels
in channels_with_ignore.items():
553 ignore =
set(_ignore_str.split(
'\\'))
556 res += [ (db.retrieve(since=since, until=until, channels=_channels, ignore=ignore, with_primary_dependencies=
True).trim_iovs, _ignore_str) ]
558 return self.
defgen(db, res, channels, channels_with_ignore)
562 def defgen(self, db, defects_with_ignore, channels, channels_with_ignore):
564 defects: list of defects returned by query
565 channels: explicit list of channels that matched the pattern
567 intolerableDefects = db.get_intolerable_defects(old_primary_only=
False)
568 for defects, ignore
in defects_with_ignore:
569 chanlist = channels
if ignore
is None else channels_with_ignore[ignore]
573 isVirtual = (d.user ==
'sys:virtual')
580 if d.channel
not in chanlist:
584 user = d.user, primary =
not isVirtual,
586 tolerable = (d.channel
not in intolerableDefects),
587 recoverable = d.recoverable)
593 o =
OOO(
"DQDEFECT", defPayload, IOVRange(starttime=d.since.real, endtime=d.until.real),
True)
603 if '\\' not in requirement:
605 x = requirement.split(
'\\')
611 for channels,flag
in dq:
613 prefix =
'!' if flag ==
'green' else ''
614 for x
in channels.split(
','):
625 from CoolRunQuery.AtlRunQueryRun
import Run
626 if 'DQ' not in Run.Fieldinfo:
627 Run.Fieldinfo[
'DQ'] = {}
628 if 'DefChannels' not in Run.Fieldinfo[
'DQ']:
629 Run.Fieldinfo[
'DQ'][
'DefChannels'] = []
630 Run.Fieldinfo[
'DQ'][
'DefChannels'] += [channelname]
634 if self.applySelection:
643 return super(DQDefectCondition,self).
rejectRun(run)
646 """ two adjacent defect entries are merged into one"""
651 (openedat,openuntil) = (x.startlb,x.endlb)
653 if x.startlb == openuntil:
656 mergedByDefect += [(openedat, openuntil)]
657 openedat,openuntil = x.startlb,x.endlb
658 mergedByDefect += [(openedat, openuntil)]
659 return mergedByDefect
661 return [(x.startlb,x.endlb)
for x
in it]
667 collects, sorts, and groups defects with LBs and comments
669 from itertools
import groupby
670 from operator
import attrgetter
674 for k
in self.ResultKey():
680 if k
not in run.data.keys():
684 all_defects =
sorted(
list(
set([x.value[0]
for x
in run.data[k]])))
686 grouped_defects = groupby(
sorted(run.data[k],key=
lambda x: x.value[0]),key =
lambda x: x.value[0])
688 desired_defects = [ (defect_name, self.
mergeRanges(lblist))
for defect_name, lblist
in grouped_defects ]
690 run.stats[k] = {
"defects": desired_defects,
695 primgroups = groupby(
sorted([p
for p
in self.
primaries[run.runNr]],key=attrgetter(
'channel')),key=attrgetter(
'channel'))
696 primaries = dict([(p,
list(l))
for p,l
in primgroups])
698 for defect
in all_defects:
699 if self.
__db.defect_is_virtual(defect):
701 self.
find_primaries(DD, self.
__db.virtual_defect_logics[defect], primaries, defect, reps)
702 run.stats[k][
"primaries"][defect] = reps
703 elif defect
in primaries:
704 run.stats[k][
"primaries"][defect] = [
DD(
"->%s" % def_obj.channel, def_obj.comment, def_obj.since.lumi, def_obj.until.lumi)
for def_obj
in primaries[defect] ]
719 for pdef
in defect_logic.primary_defects:
720 if pdef
not in primaries:
722 pdefects = primaries[pdef]
723 for pdeflb
in pdefects:
724 reps += [
DD(
"%s->%s" % (curpath, pdeflb.channel), pdeflb.comment, pdeflb.since.lumi, pdeflb.until.lumi) ]
725 for dep
in defect_logic.dependencies:
726 self.
find_primaries(DD, dep, primaries, curpath+
"->"+dep.name, reps)