ATLAS Offline Software
Loading...
Searching...
No Matches
Control/GaudiSequencer/python/PyComps.py
Go to the documentation of this file.
1# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
2
3# @file: GaudiSequencer/python/PyComps.py
4# @purpose: a set of python components for event filtering
5# @author: Sebastien Binet <binet@cern.ch>
6
7__doc__ = 'A set of python components for event filtering'
8__author__ = 'Sebastien Binet <binet@cern.ch>'
9
10import AthenaPython.PyAthena as PyAthena
11from AthenaPython.PyAthena import StatusCode
12
14 """Filtering algorithm to be used in conjunction with an AthSequencer.
15 Different operating modes are possible:
16 - give a list of events to accept
17 - give a list of events to veto
18 For each of these modes, the list of events can be:
19 - a list of event numbers: [ 13, 45, 24, 90 ]
20 - a list of pairs run/evt [ (1,13), (1,45), ... ]
21
22 Note that when in 'event list' mode and an event is found in the
23 event list, the event is accepted or not according to the
24 'filter_policy' property value ('accept' XOR 'reject')
25
26 Another way of filtering events is to provide the component with a
27 filtering function (via the 'filter_fct' property) which is expected
28 to take 2 arguments:
29 def my_filter_fct (runnbr, evtnbr):
30 'accept all events'
31 return True
32
33 examples of usage:
34 athena> seq = AthSequencer('seq')
35 athena> from GaudiSequencer.PyComps import PyEvtFilter
36 athena> seq += PyEvtFilter ('alg')
37 athena> seq.alg.filter_fct = lambda run,evt: evt in xrange(100)
38
39 or:
40 athena> def my_filter_fct(runnbr, evtnbr):
41 ... if runnbr > 5001 and runnbr < 5100 and
42 ... ( evtnbr in [ 1, 34, 600] or evtnbr > 600 ):
43 ... return True
44 ... return False
45 athena> seq.alg.filter_fct = my_filter_fct
46
47 or: (veto events 3,4 and 10)
48 athena> seq.alg.filter_fct = lambda r,e : e not in [3,4,10]
49
50 or:
51 athena> seq.alg.evt_list = [ (5010, 3), (5010, 4) ]
52 athena> seq.alg.evt_list = xrange(100)
53 athena> seq.alg.evt_list = range(10) + range(15,20)
54 athena> seq.alg.evt_list = map (lambda evt: (5100, evt), xrange(100))
55
56 or, to veto events:
57 athena> seq.alg.evt_list = [ 10, 3, 40 ]
58 athena> seq.alg.filter_policy = 'reject'
59 """
60 def __init__(self, name='PyEvtFilter', **kw):
61
62 kw['name'] = name
63 super(PyEvtFilter, self).__init__(**kw)
64
65
67 self.evt_list = kw.get('evt_list', None) # default value
68 # filtering policy for current event found in event list
69 self.filter_policy = kw.get('filter_policy', 'accept')
70 # filtering function
71 self.filter_fct = kw.get('filter_fct', None) # default value
72
73 # location of EventInfo
74 self.evt_info = kw.get('evt_info', None)
75
76 return
77
78 def initialize(self):
79 _info = self.msg.info
80 _error = self.msg.error
81 _info('==> initialize...')
82
83 # check our properties and which modus operandi is active
84 if self.evt_list is None and self.filter_fct is None:
85 _error ('invalid properties: evt_list *and* filter_fct are None !')
86 _error ('usage:\n%s', self.__doc__)
87 return StatusCode.Failure
88
89 if (not (self.evt_list is None)) and \
90 (not (self.filter_fct is None)):
91 _error ('invalid properties: evt_list *and* filter_fct '
92 'are not None !')
93 _error ('usage:\n%s', self.__doc__)
94 return StatusCode.Failure
95
96 if not (self.filter_fct is None):
97 # checking the filtering function is sound
98 import inspect
99 args = inspect.getargspec (self.filter_fct)[0]
100 # FIXME: class' methods have the hidden 'self' argument...
101 if len(args) != 2:
102 _error ('filter_fct has NOT the expected signature')
103 _error (' nbr of arguments: %i', len(args))
104 _error (' expected: 2')
105 return StatusCode.Failure
106 if not (self.filter_policy in ('reject', 'accept')):
107 _error ('invalid value for filter_policy: %r',
108 self.filter_policy)
109 _error ("valid values are 'reject' or 'accept'")
110 return StatusCode.Failure
111 else:
112 # transform the list of events into a set of pairs (run,evt)
113 evt_list = self.evt_list[:]
114 self.evt_list = set()
115 for i in evt_list:
116 if isinstance(i, tuple): irun, ievt = i
117 else: irun, ievt = None, i
118 self.evt_list.add ((irun, ievt))
119
120 _info ('EventInfo name: %s',
121 self.evt_info
122 if self.evt_info else '<any>')
123
124 if self.evt_list:
125 _info("filtering mode: evt_list")
126 _info("filtering policy: %s", self.filter_policy)
127 self.filter_policy = False if self.filter_policy == 'reject' else \
128 True
129 else:
130 _info ("filtering mode: filter_fct")
131
132 self.sg = PyAthena.py_svc ('StoreGateSvc')
133 if self.sg is None:
134 _error ('could not retrieve event store')
135 return StatusCode.Failure
136
137 self._evt_cnt = 0 # total number of events processed
138 self._evt_acc_cnt = 0 # total number of events accepted by the filter
139 self._evt_rej_cnt = 0 # total number of events rejected by the filter
140 return StatusCode.Success
141
142 def execute(self):
143 self._evt_cnt += 1
144 _info = self.msg.info
145 _error= self.msg.error
146
147 evtinfo = self.sg.retrieve ('EventInfo', self.evt_info)
148 if evtinfo is None:
149 _error ('could not retrieve EventInfo at [%s]', self.evt_info)
150 return StatusCode.Failure
151
152 filter_passed = None
153
154 evtid = evtinfo.event_ID()
155 runnbr = evtid.run_number()
156 evtnbr = evtid.event_number()
157 if self.filter_fct:
158 filter_passed = self.filter_fct (runnbr, evtnbr)
159 else:
160 if (runnbr,evtnbr) in self.evt_list or \
161 (None, evtnbr) in self.evt_list:
162 filter_passed = self.filter_policy
163 else:
164 filter_passed = not self.filter_policy
165
166
167 if not isinstance(filter_passed, bool):
168 self.msg.error ('invalid filter-passed decision: %r', filter_passed)
169 return StatusCode.Failure
170
171 self.setFilterPassed (filter_passed)
172 if filter_passed:
173 self._evt_acc_cnt += 1
174 dec = 'accepted'
175 else:
176 self._evt_rej_cnt += 1
177 dec = 'rejected'
178 _info ('[run=%s | evt=%s] ==> [%s]',
179 str(runnbr).zfill(5),
180 str(evtnbr).zfill(5),
181 dec)
182 return StatusCode.Success
183
184 def finalize(self):
185 _info = self.msg.info
186 _info ('==> finalize...')
187 _info (' #evts processed: %i', self._evt_cnt)
188 _info (' #evts accepted : %i', self._evt_acc_cnt)
189 _info (' #evts rejected : %i', self._evt_rej_cnt)
190 return StatusCode.Success
191
192 # class PyEvtFilter
MsgStream & msg() const
virtual StatusCode execute() override
virtual StatusCode finalize() override
virtual StatusCode initialize() override
evt_list
properties and data members list of events to accept
STL class.