CMS 3D CMS Logo

DeltaR.py
Go to the documentation of this file.
1 #ROOTTOOLS
2 import math
3 import copy
4 
5 def deltaR2( e1, p1, e2, p2):
6  de = e1 - e2
7  dp = deltaPhi(p1, p2)
8  return de*de + dp*dp
9 
10 
11 def deltaR( *args ):
12  return math.sqrt( deltaR2(*args) )
13 
14 
15 def deltaPhi( p1, p2):
16  '''Computes delta phi, handling periodic limit conditions.'''
17  res = p1 - p2
18  while res > math.pi:
19  res -= 2*math.pi
20  while res < -math.pi:
21  res += 2*math.pi
22  return res
23 
24 def matchObjectCollection3 ( objects, matchCollection, deltaRMax = 0.3, filter = lambda x,y : True ):
25  '''Univoque association of an element from matchCollection to an element of objects.
26  Reco and Gen objects get the "matched" attribute, true if they are part of a matched tuple.
27  By default, the matching is true only if delta R is smaller than 0.3.
28  '''
29  #
30  pairs = {}
31  if len(objects)==0:
32  return pairs
33  if len(matchCollection)==0:
34  return dict( zip(objects, [None]*len(objects)) )
35  # build all possible combinations
36 
37  allPairs = [(deltaR2 (object.eta(), object.phi(), match.eta(), match.phi()), (object, match)) for object in objects for match in matchCollection if filter(object,match) ]
38  allPairs.sort ()
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 = [(deltaR2 (object.eta(), object.phi(), match.eta(), match.phi()), (object, match)) for object in objects for match in matchCollection]
159  allPairs.sort ()
160 
161  # to flag already matched objects
162  # FIXME this variable remains appended to the object, I do not like it
163  for object in objects:
164  object.matched = False
165  for match in matchCollection:
166  match.matched = False
167 
168  deltaR2Max = deltaRMax * deltaRMax
169  for dR2, (object, match) in allPairs:
170  if dR2 > deltaR2Max:
171  break
172  if dR2 < deltaR2Max and object.matched == False and match.matched == False:
173  object.matched = True
174  match.matched = True
175  pairs[object] = match
176 
177  for object in objects:
178  if object.matched == False:
179  pairs[object] = None
180 
181  return pairs
182  # by now, the matched attribute remains in the objects, for future usage
183  # one could remove it with delattr (object, attrname)
184 
185 
186 
187 if __name__ == '__main__':
188 
189  import sys
190  args = sys.argv[1:]
191  fargs = map( float, args )
192 
193  print 'dR2 = ', deltaR2( *fargs )
194  print 'dR = ', deltaR( *fargs )
195 
196 
197 
def cleanObjectCollection2(objects, masks, deltaRMin)
Definition: DeltaR.py:69
def deltaPhi(p1, p2)
Definition: DeltaR.py:15
def matchObjectCollection3
Definition: DeltaR.py:24
def cleanObjectCollection(objects, masks, deltaRMin)
Definition: DeltaR.py:96
def deltaR2(e1, p1, e2, p2)
Definition: DeltaR.py:5
def matchObjectCollection2(objects, matchCollection, deltaRMax=0.3)
Definition: DeltaR.py:146
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
def matchObjectCollection(objects, matchCollection, deltaR2Max)
Definition: DeltaR.py:131
def deltaR(args)
Definition: DeltaR.py:11
def bestMatch(object, matchCollection)
Definition: DeltaR.py:118