ATLAS Offline Software
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 
5 from copy import copy
6 from enum import Enum
7 
8 from AthenaCommon.Logging import logging
9 log = logging.getLogger(__name__)
10 
11 class 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 
28 class Logic(object):
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 
180 def Not(x):
181  return Logic.Not(x)
182 
183 
python.L1.Base.Logic.Logic.Not
def Not(x)
Definition: Logic.py:33
python.L1.Base.Logic.Not
def Not(x)
Definition: Logic.py:180
python.L1.Base.Logic.LogicType.__repr__
def __repr__(self)
Definition: Logic.py:25
python.L1.Base.Logic.Logic.normalize
def normalize(self)
Definition: Logic.py:166
python.L1.Base.Logic.LogicType.__init__
def __init__(self, opSymbol)
Definition: Logic.py:19
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.L1.Base.Logic.Logic.content
content
Definition: Logic.py:61
python.L1.Base.Logic.LogicType.opSymbol
opSymbol
Definition: Logic.py:20
python.L1.Base.Logic.Logic.__init__
def __init__(self, logicType=LogicType.NONE, content=None)
Definition: Logic.py:60
python.L1.Base.Logic.Logic.__str__
def __str__(self)
Definition: Logic.py:108
python.L1.Base.Logic.Logic.conditions
def conditions(self, include_internal=False)
Definition: Logic.py:151
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.L1.Base.Logic.LogicType
Definition: Logic.py:11
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
python.L1.Base.Logic.Logic.stripBunchGroups
def stripBunchGroups(theLogic)
Definition: Logic.py:40
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
python.L1.Base.Logic.Logic.__and__
def __and__(self, x)
Definition: Logic.py:82
python.L1.Base.Logic.Logic.__or__
def __or__(self, x)
Definition: Logic.py:66
python.L1.Base.Logic.Logic.thresholdNames
def thresholdNames(self, include_bgrp=False)
Definition: Logic.py:138
python.L1.Base.Logic.Logic.subConditions
subConditions
Definition: Logic.py:63
python.L1.Base.Logic.LogicType.__str__
def __str__(self)
Definition: Logic.py:22
pickleTool.object
object
Definition: pickleTool.py:30
str
Definition: BTagTrackIpAccessor.cxx:11
calibdata.copy
bool copy
Definition: calibdata.py:27
python.L1.Base.Logic.Logic
Definition: Logic.py:28
python.L1.Base.Logic.Logic.__not__
def __not__(self, x)
Definition: Logic.py:97
python.L1.Base.Logic.Logic.logicType
logicType
Definition: Logic.py:62