ATLAS Offline Software
Loading...
Searching...
No Matches
Logic.py
Go to the documentation of this file.
1# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
2
3__all__ = ['Logic', 'Not']
4
5from copy import copy
6from enum import Enum
7
8from AthenaCommon.Logging import logging
9log = logging.getLogger(__name__)
10
11class LogicType( Enum ):
12 NONE = ('')
13 AND = ('&')
14 OR = ('|')
15 NOT = ('!')
16 THRESHOLD = ('T')
17 INTERNAL = ('I')
18
19 def __init__(self, opSymbol):
20 self.opSymbol = opSymbol
21
22 def __str__(self):
23 return self.opSymbol
24
25 def __repr__(self):
26 return self.name
27
29
30 __slots__ = ['content', 'logicType', 'subConditions']
31
32 @staticmethod
33 def Not(x):
34 a = Logic()
35 a.logicType = LogicType.NOT
36 a.subConditions.append(x)
37 return a
38
39 @staticmethod
40 def stripBunchGroups(theLogic):
41 subConds = []
42 bunchGroups = []
43 for sc in theLogic.subConditions:
44 if sc.logicType is LogicType.INTERNAL and sc.name().startswith('BGRP'):
45 bunchGroups.append(sc.name())
46 else:
47 subConds.append( sc )
48
49 if len(subConds)>1:
50 theLogic.subConditions = subConds
51 return (theLogic, bunchGroups)
52
53 if len(subConds)==1:
54 return (subConds[0], bunchGroups)
55
56 raise RuntimeError("Item with logic '%s' has only internal triggers defined" % theLogic)
57
58
59
60 def __init__(self, logicType = LogicType.NONE, content = None):
61 self.content = content # only filled for THRESHOLD and INTERNAL
62 self.logicType = logicType
63 self.subConditions = [] # holds Logic instances
64
65
66 def __or__(self, x):
67 newLogic = Logic( logicType = LogicType.OR )
68
69 if self.logicType is LogicType.OR:
70 newLogic.subConditions += copy(self.subConditions)
71 else:
72 newLogic.subConditions += [copy(self)]
73
74 if x.logicType is LogicType.OR:
75 newLogic.subConditions += copy(x.subConditions)
76 else:
77 newLogic.subConditions += [copy(x)]
78
79 return newLogic
80
81
82 def __and__(self, x):
83 newLogic = Logic( logicType = LogicType.AND )
84
85 if self.logicType is LogicType.AND:
86 newLogic.subConditions += copy(self.subConditions)
87 else:
88 newLogic.subConditions += [copy(self)]
89
90 if x.logicType is LogicType.AND:
91 newLogic.subConditions += copy(x.subConditions)
92 else:
93 newLogic.subConditions += [copy(x)]
94
95 return newLogic
96
97 def __not__(self, x):
98 if self.logicType is LogicType.NONE:
99 self.logicType = LogicType.NOT
100 if self.logicType is LogicType.NOT:
101 if len(self.subConditions) == 1:
102 log.debug('not is a unary operator, ignore it')
103 else:
104 self.subConditions.append(x)
105 return self
106
107
108 def __str__(self):
109 if self.logicType is LogicType.NONE:
110 log.error('LogicType NONE should not have an instance')
111 return ''
112
113 if self.logicType is LogicType.NOT:
114 if len(self.subConditions)==1:
115 if self.subConditions[0].logicType is LogicType.NONE:
116 return '!'+str(self.subConditions[0])
117 else:
118 return '!('+str(self.subConditions[0]) + ')'
119 log.error('Logic NOT must have exactly one element but has %i', len(self.subConditions))
120 return ''
121
122 if self.logicType in (LogicType.AND, LogicType.OR):
123 s = ''
124 if len(self.subConditions)<=1:
125 log.error('Logic AND/OR must have more than one sub element but has %i: %r', len(self.subConditions), self.subConditions)
126 return ''
127 else:
128 for (i, a) in enumerate(self.subConditions):
129 if i > 0:
130 s += ' ' + str(self.logicType) + ' '
131 if a.logicType in (LogicType.THRESHOLD, LogicType.INTERNAL, LogicType.NOT):
132 s += str(a)
133 else:
134 s += '(' + str(a) + ')'
135 return s
136 return ''
137
138 def thresholdNames(self, include_bgrp=False):
139 names = set()
140 if self.logicType is LogicType.THRESHOLD:
141 names.add( self.threshold.name )
142 elif self.logicType is LogicType.INTERNAL:
143 if include_bgrp:
144 names.add(self.name())
145 else:
146 for sc in self.subConditions:
147 names.update( sc.thresholdNames(include_bgrp) )
148 return sorted(list(names))
149
150
151 def conditions(self, include_internal=False):
152 cond = set([])
153 if hasattr(self,'condition') and self.condition is not None:
154 from .CTPCondition import InternalTrigger
155 if isinstance(self.condition, InternalTrigger):
156 if include_internal:
157 cond.add(self.condition)
158 else:
159 cond.add( self.condition )
160 else:
161 for sc in self.subConditions:
162 cond.update( sc.conditions(include_internal) )
163 return sorted(list(cond))
164
165
166 def normalize(self):
167 if self.logicType in (LogicType.AND, LogicType.OR):
168 mylogic = self.logicType
169 newconditions = []
170 for c in self.subConditions:
171 if c.logicType == mylogic: # X&(A&B) or X|(A|B)
172 # expand it to X&A&B or X|A|B
173 c.normalize()
174 newconditions.extend(c.subConditions)
175 else:
176 newconditions.append(c)
177 self.subConditions = newconditions
178
179
180def Not(x):
181 return Logic.Not(x)
182
183
__init__(self, opSymbol)
Definition Logic.py:19
__init__(self, logicType=LogicType.NONE, content=None)
Definition Logic.py:60
stripBunchGroups(theLogic)
Definition Logic.py:40
thresholdNames(self, include_bgrp=False)
Definition Logic.py:138
conditions(self, include_internal=False)
Definition Logic.py:151
STL class.