CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DeltaR.py
Go to the documentation of this file.
1 from __future__ import print_function
2 #ROOTTOOLS
3 import math
4 import copy
5 
6 def deltaR2( e1, p1, e2, p2):
7  de = e1 - e2
8  dp = deltaPhi(p1, p2)
9  return de*de + dp*dp
10 
11 
12 def deltaR( *args ):
13  return math.sqrt( deltaR2(*args) )
14 
15 
16 def deltaPhi( p1, p2):
17  '''Computes delta phi, handling periodic limit conditions.'''
18  res = p1 - p2
19  while res > math.pi:
20  res -= 2*math.pi
21  while res < -math.pi:
22  res += 2*math.pi
23  return res
24 
25 def matchObjectCollection3 ( objects, matchCollection, deltaRMax = 0.3, filter = lambda x,y : True ):
26  '''Univoque association of an element from matchCollection to an element of objects.
27  Reco and Gen objects get the "matched" attribute, true if they are part of a matched tuple.
28  By default, the matching is true only if delta R is smaller than 0.3.
29  '''
30  #
31  pairs = {}
32  if len(objects)==0:
33  return pairs
34  if len(matchCollection)==0:
35  return dict( zip(objects, [None]*len(objects)) )
36  # build all possible combinations
37 
38  allPairs = sorted([(deltaR2 (object.eta(), object.phi(), match.eta(), match.phi()), (object, match)) for object in objects for match in matchCollection if list(filter(object,match)) ])
39  #
40  # to flag already matched objects
41  # FIXME this variable remains appended to the object, I do not like it
42 
43  for object in objects:
44  object.matched = False
45  for match in matchCollection:
46  match.matched = False
47  #
48 
49  deltaR2Max = deltaRMax * deltaRMax
50  for dR2, (object, match) in allPairs:
51  if dR2 > deltaR2Max:
52  break
53  if dR2 < deltaR2Max and object.matched == False and match.matched == False:
54  object.matched = True
55  match.matched = True
56  pairs[object] = match
57  #
58 
59  for object in objects:
60  if object.matched == False:
61  pairs[object] = None
62  #
63 
64  return pairs
65  # by now, the matched attribute remains in the objects, for future usage
66  # one could remove it with delattr (object, attrname)
67 
68 
69 def cleanObjectCollection2( objects, masks, deltaRMin ):
70  '''Masks objects using a deltaR cut, another algorithm (same results).'''
71  if len(objects)==0:
72  return objects
73  deltaR2Min = deltaRMin*deltaRMin
74  cleanObjects = copy.copy( objects )
75  for mask in masks:
76  tooClose = []
77  for idx, object in enumerate(cleanObjects):
78  dR2 = deltaR2( object.eta(), object.phi(),
79  mask.eta(), mask.phi() )
80  if dR2 < deltaR2Min:
81  tooClose.append( idx )
82  nRemoved = 0
83  for idx in tooClose:
84  # yes, everytime an object is removed, the list of objects is updated
85  # so need to update the index accordingly.
86  # example: to remove : ele 1 and 2
87  # first, ele 1 is removed
88  # -> ele 2 is now at index 1
89  # one should again remove the element at index 1
90  idx -= nRemoved
91  del cleanObjects[idx]
92  nRemoved += 1
93  return cleanObjects
94 
95 
96 def cleanObjectCollection( objects, masks, deltaRMin ):
97  '''Masks objects using a deltaR cut.'''
98  if len(objects)==0 or len(masks)==0:
99  return objects, []
100  deltaR2Min = deltaRMin*deltaRMin
101  cleanObjects = []
102  dirtyObjects = []
103  for object in objects:
104  ok = True
105  for mask in masks:
106  dR2 = deltaR2( object.eta(), object.phi(),
107  mask.eta(), mask.phi() )
108  if dR2 < deltaR2Min:
109  ok = False
110  if ok:
111  cleanObjects.append( object )
112  else:
113  dirtyObjects.append( object )
114  return cleanObjects, dirtyObjects
115 
116 
117 
118 def bestMatch( object, matchCollection):
119  '''Return the best match to object in matchCollection, which is the closest object in delta R'''
120  deltaR2Min = float('+inf')
121  bm = None
122  for match in matchCollection:
123  dR2 = deltaR2( object.eta(), object.phi(),
124  match.eta(), match.phi() )
125  if dR2 < deltaR2Min:
126  deltaR2Min = dR2
127  bm = match
128  return bm, deltaR2Min
129 
130 
131 def matchObjectCollection( objects, matchCollection, deltaR2Max):
132  pairs = {}
133  if len(objects)==0:
134  return pairs
135  if len(matchCollection)==0:
136  return dict( zip(objects, [None]*len(objects)) )
137  for object in objects:
138  bm, dr2 = bestMatch( object, matchCollection )
139  if dr2<deltaR2Max:
140  pairs[object] = bm
141  else:
142  pairs[object] = None
143  return pairs
144 
145 
146 def matchObjectCollection2 ( objects, matchCollection, deltaRMax = 0.3 ):
147  '''Univoque association of an element from matchCollection to an element of objects.
148  Reco and Gen objects get the "matched" attribute, true if they are part of a matched tuple.
149  By default, the matching is true only if delta R is smaller than 0.3.
150  '''
151 
152  pairs = {}
153  if len(objects)==0:
154  return pairs
155  if len(matchCollection)==0:
156  return dict( zip(objects, [None]*len(objects)) )
157  # build all possible combinations
158  allPairs = sorted([(deltaR2 (object.eta(), object.phi(), match.eta(), match.phi()), (object, match)) for object in objects for match in matchCollection])
159 
160  # to flag already matched objects
161  # FIXME this variable remains appended to the object, I do not like it
162  for object in objects:
163  object.matched = False
164  for match in matchCollection:
165  match.matched = False
166 
167  deltaR2Max = deltaRMax * deltaRMax
168  for dR2, (object, match) in allPairs:
169  if dR2 > deltaR2Max:
170  break
171  if dR2 < deltaR2Max and object.matched == False and match.matched == False:
172  object.matched = True
173  match.matched = True
174  pairs[object] = match
175 
176  for object in objects:
177  if object.matched == False:
178  pairs[object] = None
179 
180  return pairs
181  # by now, the matched attribute remains in the objects, for future usage
182  # one could remove it with delattr (object, attrname)
183 
184 
185 
186 if __name__ == '__main__':
187 
188  import sys
189  args = sys.argv[1:]
190  fargs = map( float, args )
191 
192  print('dR2 = ', deltaR2( *fargs ))
193  print('dR = ', deltaR( *fargs ))
194 
195 
196 
def cleanObjectCollection
Definition: DeltaR.py:96
def matchObjectCollection3
Definition: DeltaR.py:25
def bestMatch
Definition: DeltaR.py:118
def matchObjectCollection2
Definition: DeltaR.py:146
def matchObjectCollection
Definition: DeltaR.py:131
def deltaR2
Definition: DeltaR.py:6
def deltaPhi
Definition: DeltaR.py:16
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def cleanObjectCollection2
Definition: DeltaR.py:69
def deltaR
Definition: DeltaR.py:12