CMS 3D CMS Logo

deltar.py
Go to the documentation of this file.
1 # Copyright (C) 2014 Colin Bernet
2 # https://github.com/cbernet/heppy/blob/master/LICENSE
3 
4 import math
5 import copy
6 
7 def deltaR2( e1, p1, e2=None, p2=None):
8  """Take either 4 arguments (eta,phi, eta,phi) or two objects that have 'eta', 'phi' methods)"""
9  if (e2 == None and p2 == None):
10  return deltaR2(e1.eta(),e1.phi(), p1.eta(), p1.phi())
11  de = e1 - e2
12  dp = deltaPhi(p1, p2)
13  return de*de + dp*dp
14 
15 
16 def deltaR( *args ):
17  return math.sqrt( deltaR2(*args) )
18 
19 
20 def deltaPhi( p1, p2):
21  '''Computes delta phi, handling periodic limit conditions.'''
22  res = p1 - p2
23  while res > math.pi:
24  res -= 2*math.pi
25  while res < -math.pi:
26  res += 2*math.pi
27  return res
28 
29 
30 def inConeCollection(pivot, particles, deltaRMax, deltaRMin=1e-5):
31  '''Returns the list of particles that are less than deltaRMax away from pivot.'''
32  dR2Max = deltaRMax ** 2
33  dR2Min = deltaRMin ** 2 if deltaRMin > 0 else -1
34  results = []
35  for ptc in particles:
36  dR2 = deltaR2(pivot.eta(), pivot.phi(), ptc.eta(), ptc.phi())
37  if dR2Min < dR2 and dR2 < dR2Max:
38  results.append(ptc)
39  return results
40 
41 def matchObjectCollection3 ( objects, matchCollection, deltaRMax = 0.3, filter = lambda x,y : True ):
42  '''Univoque association of an element from matchCollection to an element of objects.
43  Reco and Gen objects get the "matched" attribute, true is they are re part of a matched tulpe.
44  By default, the matching is true only if delta R is smaller than 0.3.
45  '''
46  #
47 
48  pairs = {}
49  if len(objects)==0:
50  return pairs
51  if len(matchCollection)==0:
52  return dict( list(zip(objects, [None]*len(objects))) )
53  # build all possible combinations
54 
55  objectCoords = [ (o.eta(),o.phi(),o) for o in objects ]
56  matchdCoords = [ (o.eta(),o.phi(),o) for o in matchCollection ]
57  allPairs = sorted([(deltaR2 (oeta, ophi, meta, mphi), (object, match)) for (oeta,ophi,object) in objectCoords for (meta,mphi,match) in matchdCoords if abs(oeta-meta)<=deltaRMax and filter(object,match) ])
58  #allPairs = [(deltaR2 (object.eta(), object.phi(), match.eta(), match.phi()), (object, match)) for object in objects for match in matchCollection if filter(object,match) ]
59  #
60  # to flag already matched objects
61  # FIXME this variable remains appended to the object, I do not like it
62 
63  for object in objects:
64  object.matched = False
65  for match in matchCollection:
66  match.matched = False
67  #
68 
69  deltaR2Max = deltaRMax * deltaRMax
70  for dR2, (object, match) in allPairs:
71  if dR2 > deltaR2Max:
72  break
73  if dR2 < deltaR2Max and object.matched == False and match.matched == False:
74  object.matched = True
75  match.matched = True
76  pairs[object] = match
77  #
78 
79  for object in objects:
80  if object.matched == False:
81  pairs[object] = None
82  #
83 
84  return pairs
85  # by now, the matched attribute remains in the objects, for future usage
86  # one could remove it with delattr (object, attrname)
87 
88 
89 
90 
91 def cleanObjectCollection2( objects, masks, deltaRMin ):
92  '''Masks objects using a deltaR cut, another algorithm (same results).'''
93  if len(objects)==0:
94  return objects
95  deltaR2Min = deltaRMin*deltaRMin
96  cleanObjects = copy.copy( objects )
97  for mask in masks:
98  tooClose = []
99  for idx, object in enumerate(cleanObjects):
100  dR2 = deltaR2( object.eta(), object.phi(),
101  mask.eta(), mask.phi() )
102  if dR2 < deltaR2Min:
103  tooClose.append( idx )
104  nRemoved = 0
105  for idx in tooClose:
106  # yes, everytime an object is removed, the list of objects is updated
107  # so need to update the index accordingly.
108  # example: to remove : ele 1 and 2
109  # first, ele 1 is removed
110  # -> ele 2 is now at index 1
111  # one should again remove the element at index 1
112  idx -= nRemoved
113  del cleanObjects[idx]
114  nRemoved += 1
115  return cleanObjects
116 
117 
118 def cleanObjectCollection( objects, masks, deltaRMin ):
119  '''Masks objects using a deltaR cut.'''
120  if len(objects)==0 or len(masks)==0:
121  return objects, []
122  deltaR2Min = deltaRMin*deltaRMin
123  cleanObjects = []
124  dirtyObjects = []
125  for object in objects:
126  ok = True
127  for mask in masks:
128  dR2 = deltaR2( object.eta(), object.phi(),
129  mask.eta(), mask.phi() )
130  if dR2 < deltaR2Min:
131  ok = False
132  if ok:
133  cleanObjects.append( object )
134  else:
135  dirtyObjects.append( object )
136  return cleanObjects, dirtyObjects
137 
138 def bestMatch( object, matchCollection):
139  '''Return the best match to object in matchCollection, which is the closest object in delta R'''
140  deltaR2Min = float('+inf')
141  bm = None
142  for match in matchCollection:
143  dR2 = deltaR2( object.eta(), object.phi(),
144  match.eta(), match.phi() )
145  if dR2 < deltaR2Min:
146  deltaR2Min = dR2
147  bm = match
148  return bm, deltaR2Min
149 
150 
151 def matchObjectCollection( objects, matchCollection, deltaR2Max, filter = lambda x,y : True):
152  pairs = {}
153  if len(objects)==0:
154  return pairs
155  if len(matchCollection)==0:
156  return dict( list(zip(objects, [None]*len(objects))) )
157  for object in objects:
158  bm, dr2 = bestMatch( object, [mob for mob in matchCollection if filter(object,mob)] )
159  if dr2<deltaR2Max:
160  pairs[object] = bm
161  else:
162  pairs[object] = None
163  return pairs
164 
165 
166 def matchObjectCollection2 ( objects, matchCollection, deltaRMax = 0.3 ):
167  '''Univoque association of an element from matchCollection to an element of objects.
168  Reco and Gen objects get the "matched" attribute, true is they are re part of a matched tulpe.
169  By default, the matching is true only if delta R is smaller than 0.3.
170  '''
171 
172  pairs = {}
173  if len(objects)==0:
174  return pairs
175  if len(matchCollection)==0:
176  return dict( list(zip(objects, [None]*len(objects))) )
177  # build all possible combinations
178  allPairs = sorted([(deltaR2 (object.eta(), object.phi(), match.eta(), match.phi()), (object, match)) for object in objects for match in matchCollection])
179 
180  # to flag already matched objects
181  # FIXME this variable remains appended to the object, I do not like it
182  for object in objects:
183  object.matched = False
184  for match in matchCollection:
185  match.matched = False
186 
187  deltaR2Max = deltaRMax * deltaRMax
188  for dR2, (object, match) in allPairs:
189  if dR2 > deltaR2Max:
190  break
191  if dR2 < deltaR2Max and object.matched == False and match.matched == False:
192  object.matched = True
193  match.matched = True
194  pairs[object] = match
195 
196  for object in objects:
197  if object.matched == False:
198  pairs[object] = None
199 
200  return pairs
201  # by now, the matched attribute remains in the objects, for future usage
202  # one could remove it with delattr (object, attrname)
203 
204 
205 
def deltaR(args)
Definition: deltar.py:16
def deltaR2(e1, p1, e2=None, p2=None)
Definition: deltar.py:7
def deltaPhi(p1, p2)
Definition: deltar.py:20
def matchObjectCollection
Definition: deltar.py:151
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
def bestMatch(object, matchCollection)
Definition: deltar.py:138
def cleanObjectCollection(objects, masks, deltaRMin)
Definition: deltar.py:118
def matchObjectCollection2(objects, matchCollection, deltaRMax=0.3)
Definition: deltar.py:166
def inConeCollection(pivot, particles, deltaRMax, deltaRMin=1e-5)
Definition: deltar.py:30
def matchObjectCollection3
Definition: deltar.py:41
def cleanObjectCollection2(objects, masks, deltaRMin)
Definition: deltar.py:91
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run