source: trunk/CDFCones/MidPointAlgorithm.cc@ 5

Last change on this file since 5 was 2, checked in by Pavel Demin, 16 years ago

first commit

File size: 10.2 KB
Line 
1#include "MidPointAlgorithm.hh"
2#include "ClusterComparisons.hh"
3#include <algorithm>
4#include <cmath>
5
6void MidPointAlgorithm::findStableConesFromSeeds(std::vector<PhysicsTower>& towers, std::vector<Cluster>& stableCones)
7{
8 bool reduceConeSize = true;
9 for(std::vector<PhysicsTower>::iterator towerIter = towers.begin(); towerIter != towers.end(); towerIter++)
10 if(towerIter->fourVector.pt() > _seedThreshold)
11 iterateCone(towerIter->fourVector.y(),towerIter->fourVector.phi(),0,towers,stableCones,reduceConeSize);
12}
13
14void MidPointAlgorithm::findStableConesFromMidPoints(std::vector<PhysicsTower>& towers, std::vector<Cluster>& stableCones)
15{
16 // distanceOK[i-1][j] = Is distance between stableCones i and j (i>j) less than 2*_coneRadius?
17 std::vector< std::vector<bool> > distanceOK;
18if(stableCones.size() > 0){
19 distanceOK.resize(stableCones.size() - 1);
20 for(int nCluster1 = 1; nCluster1 < stableCones.size(); nCluster1++){
21 distanceOK[nCluster1 - 1].resize(nCluster1);
22 double cluster1Rapidity = stableCones[nCluster1].fourVector.y();
23 double cluster1Phi = stableCones[nCluster1].fourVector.phi();
24 for(int nCluster2 = 0; nCluster2 < nCluster1; nCluster2++){
25 double cluster2Rapidity = stableCones[nCluster2].fourVector.y();
26 double cluster2Phi = stableCones[nCluster2].fourVector.phi();
27 double dRapidity = fabs(cluster1Rapidity - cluster2Rapidity);
28 double dPhi = fabs(cluster1Phi - cluster2Phi);
29 if(dPhi > M_PI)
30 dPhi = 2*M_PI - dPhi;
31 double dR = sqrt(dRapidity*dRapidity + dPhi*dPhi);
32 distanceOK[nCluster1 - 1][nCluster2] = dR < 2*_coneRadius;
33 }
34 }
35}
36 // Find all pairs (triplets, ...) of stableCones which are less than 2*_coneRadius apart from each other.
37 std::vector< std::vector<int> > pairs(0);
38 std::vector<int> testPair(0);
39 int maxClustersInPair = _maxPairSize;
40 if(!maxClustersInPair)
41 maxClustersInPair = stableCones.size();
42 addClustersToPairs(testPair,pairs,distanceOK,maxClustersInPair);
43
44 // Loop over all combinations. Calculate MidPoint. Make midPointClusters.
45 bool reduceConeSize = false;
46 for(int iPair = 0; iPair < pairs.size(); iPair++){
47 // Calculate rapidity, phi and pT of MidPoint.
48 LorentzVector midPoint(0,0,0,0);
49 for(int iPairMember = 0; iPairMember < pairs[iPair].size(); iPairMember++)
50 midPoint.add(stableCones[pairs[iPair][iPairMember]].fourVector);
51 iterateCone(midPoint.y(),midPoint.phi(),midPoint.pt(),towers,stableCones,reduceConeSize);
52 }
53
54 sort(stableCones.begin(),stableCones.end(),ClusterPtGreater());
55}
56
57void MidPointAlgorithm::iterateCone(double startRapidity, double startPhi, double startPt,
58 std::vector<PhysicsTower>& towers, std::vector<Cluster>& stableCones, bool reduceConeSize)
59{
60 int nIterations = 0;
61 bool keepJet = true;
62 Cluster trialCone;
63 double iterationConeRadius = _coneRadius;
64 if(reduceConeSize)
65 iterationConeRadius *= sqrt(_coneAreaFraction);
66 while(nIterations++ < _maxIterations + 1 && keepJet){
67 trialCone.clear();
68 // Find particles which should go in the cone.
69 if(nIterations == _maxIterations + 1)
70 iterationConeRadius = _coneRadius;
71 for(std::vector<PhysicsTower>::iterator towerIter = towers.begin(); towerIter != towers.end(); towerIter++){
72 double dRapidity = fabs(towerIter->fourVector.y() - startRapidity);
73 double dPhi = fabs(towerIter->fourVector.phi() - startPhi);
74 if(dPhi > M_PI)
75 dPhi = 2*M_PI - dPhi;
76 double dR = sqrt(dRapidity*dRapidity + dPhi*dPhi);
77 if(dR < iterationConeRadius)
78 trialCone.addTower(*towerIter);
79 }
80 if(!trialCone.size()) // Empty cone?
81 keepJet = false;
82 else{
83 if(nIterations <= _maxIterations){
84 double endRapidity = trialCone.fourVector.y();
85 double endPhi = trialCone.fourVector.phi();
86 double endPt = trialCone.fourVector.pt();
87 // Do we have a stable cone?
88 if(endRapidity == startRapidity && endPhi == startPhi && endPt == startPt){
89 // If cone size is reduced, then do one more iteration.
90 nIterations = _maxIterations;
91 if(!reduceConeSize)
92 nIterations++;
93 }
94 else{
95 // Another iteration.
96 startRapidity = endRapidity;
97 startPhi = endPhi;
98 startPt = endPt;
99 }
100 }
101 }
102 }
103
104 if(keepJet){
105 // We have a stable cone.
106 bool identical = false;
107 for(std::vector<Cluster>::iterator stableConeIter = stableCones.begin(); stableConeIter != stableCones.end(); stableConeIter++)
108 if(trialCone.fourVector.isEqual(stableConeIter->fourVector))
109 identical = true;
110 if(!identical)
111 stableCones.push_back(trialCone);
112 }
113}
114
115void MidPointAlgorithm::addClustersToPairs(std::vector<int>& testPair, std::vector< std::vector<int> >& pairs,
116 std::vector< std::vector<bool> >& distanceOK, int maxClustersInPair)
117{
118 // Recursively adds clusters to pairs, triplets, ... whose mid-points are then calculated.
119
120 // Find StableCone number to start with (either 0 at the beginning or last element of testPair + 1).
121 int nextClusterStart = 0;
122 if(testPair.size())
123 nextClusterStart = testPair.back() + 1;
124 for(int nextCluster = nextClusterStart; nextCluster <= distanceOK.size(); nextCluster++){
125 // Is new SeedCone less than 2*_coneRadius apart from all clusters in testPair?
126 bool addCluster = true;
127 for(int iCluster = 0; iCluster < testPair.size() && addCluster; iCluster++)
128 if(!distanceOK[nextCluster - 1][testPair[iCluster]])
129 addCluster = false;
130 if(addCluster){
131 // Add it to the testPair.
132 testPair.push_back(nextCluster);
133 // If testPair is a pair, add it to pairs.
134 if(testPair.size() > 1)
135 pairs.push_back(testPair);
136 // If not bigger than allowed, find more clusters within 2*_coneRadius.
137 if(testPair.size() < maxClustersInPair)
138 addClustersToPairs(testPair,pairs,distanceOK,maxClustersInPair);
139 // All combinations containing testPair found. Remove last element.
140 testPair.pop_back();
141 }
142 }
143}
144
145void MidPointAlgorithm::splitAndMerge(std::vector<Cluster>& stableCones, std::vector<Cluster>& jets)
146{
147 bool mergingNotFinished = true;
148 while(mergingNotFinished){
149 // Sort the stable cones (highest pt first).
150 sort(stableCones.begin(),stableCones.end(),ClusterPtGreater());
151 // Start with the highest pt cone.
152 std::vector<Cluster>::iterator stableConeIter1 = stableCones.begin();
153 if(stableConeIter1 == stableCones.end()) // Stable cone list empty?
154 mergingNotFinished = false;
155 else{
156 bool coneNotModified = true;
157 // Determine whether highest pt cone has an overlap with other stable cones.
158 std::vector<Cluster>::iterator stableConeIter2 = stableConeIter1;
159 stableConeIter2++; // 2nd highest pt cone.
160 while(coneNotModified && stableConeIter2 != stableCones.end()){
161 // Calculate overlap of the two cones.
162 Cluster overlap;
163 for(std::vector<PhysicsTower>::iterator towerIter1 = stableConeIter1->towerList.begin();
164 towerIter1 != stableConeIter1->towerList.end();
165 towerIter1++){
166 bool isInCone2 = false;
167 for(std::vector<PhysicsTower>::iterator towerIter2 = stableConeIter2->towerList.begin();
168 towerIter2 != stableConeIter2->towerList.end();
169 towerIter2++)
170 if(towerIter1->isEqual(*towerIter2))
171 isInCone2 = true;
172 if(isInCone2)
173 overlap.addTower(*towerIter1);
174 }
175 if(overlap.size()){ // non-empty overlap
176 coneNotModified = false;
177 if(overlap.fourVector.pt() >= _overlapThreshold*stableConeIter2->fourVector.pt()){
178 // Merge the two cones.
179 for(std::vector<PhysicsTower>::iterator towerIter2 = stableConeIter2->towerList.begin();
180 towerIter2 != stableConeIter2->towerList.end();
181 towerIter2++){
182 bool isInOverlap = false;
183 for(std::vector<PhysicsTower>::iterator overlapTowerIter = overlap.towerList.begin();
184 overlapTowerIter != overlap.towerList.end();
185 overlapTowerIter++)
186 if(towerIter2->isEqual(*overlapTowerIter))
187 isInOverlap = true;
188 if(!isInOverlap)
189 stableConeIter1->addTower(*towerIter2);
190 }
191 // Remove the second cone.
192 stableCones.erase(stableConeIter2);
193 }
194 else{
195 // Separate the two cones.
196 // Which particle goes where?
197 std::vector<PhysicsTower> removeFromCone1,removeFromCone2;
198 for(std::vector<PhysicsTower>::iterator towerIter = overlap.towerList.begin();
199 towerIter != overlap.towerList.end();
200 towerIter++){
201 double towerRapidity = towerIter->fourVector.y();
202 double towerPhi = towerIter->fourVector.phi();
203 // Calculate distance from cone 1.
204 double dRapidity1 = fabs(towerRapidity - stableConeIter1->fourVector.y());
205 double dPhi1 = fabs(towerPhi - stableConeIter1->fourVector.phi());
206 if(dPhi1 > M_PI)
207 dPhi1 = 2*M_PI - dPhi1;
208 double dRJet1 = sqrt(dRapidity1*dRapidity1 + dPhi1*dPhi1);
209 // Calculate distance from cone 2.
210 double dRapidity2 = fabs(towerRapidity - stableConeIter2->fourVector.y());
211 double dPhi2 = fabs(towerPhi - stableConeIter2->fourVector.phi());
212 if(dPhi2 > M_PI)
213 dPhi2 = 2*M_PI - dPhi2;
214 double dRJet2 = sqrt(dRapidity2*dRapidity2 + dPhi2*dPhi2);
215 if(dRJet1 < dRJet2)
216 // Particle is closer to cone 1. To be removed from cone 2.
217 removeFromCone2.push_back(*towerIter);
218 else
219 // Particle is closer to cone 2. To be removed from cone 1.
220 removeFromCone1.push_back(*towerIter);
221 }
222 // Remove particles in the overlap region from the cones to which they have the larger distance.
223 for(std::vector<PhysicsTower>::iterator towerIter = removeFromCone1.begin();
224 towerIter != removeFromCone1.end();
225 towerIter++)
226 stableConeIter1->removeTower(*towerIter);
227 for(std::vector<PhysicsTower>::iterator towerIter = removeFromCone2.begin();
228 towerIter != removeFromCone2.end();
229 towerIter++)
230 stableConeIter2->removeTower(*towerIter);
231 }
232 }
233 stableConeIter2++;
234 }
235 if(coneNotModified){
236 // Cone 1 has no overlap with any of the other cones and can become a jet.
237 jets.push_back(*stableConeIter1);
238 stableCones.erase(stableConeIter1);
239 }
240 }
241 }
242
243 sort(jets.begin(),jets.end(),ClusterPtGreater());
244}
245
246void MidPointAlgorithm::run(std::vector<PhysicsTower>& towers, std::vector<Cluster>& jets)
247{
248 std::vector<Cluster> stableCones;
249 findStableConesFromSeeds(towers,stableCones);
250 findStableConesFromMidPoints(towers,stableCones);
251 splitAndMerge(stableCones,jets);
252}
Note: See TracBrowser for help on using the repository browser.