Fork me on GitHub

source: svn/trunk/external/fastjet/plugins/CDFCones/MidPointAlgorithm.cc@ 1330

Last change on this file since 1330 was 859, checked in by Pavel Demin, 12 years ago

update fastjet to version 3.0.3

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision Date
File size: 13.8 KB
Line 
1//----------------------------------------------------------------------
2// This file distributed with FastJet has been obtained from
3// http://www.pa.msu.edu/~huston/Les_Houches_2005/JetClu+Midpoint-StandAlone.tgz
4//
5// Permission to distribute it with FastJet has been granted by Joey
6// Huston (see the COPYING file in the main FastJet directory for
7// details).
8// Changes from the original file are listed below.
9//----------------------------------------------------------------------
10
11// History of changes compared to the original MidPointAlgorithm.cc file
12//
13// 2009-01-17 Gregory Soyez <soyez@fastjet.fr>
14//
15// * put the code in the fastjet::cdf namespace
16//
17// 2008-01-15 Gavin Salam <salam@lpthe.jussieu.fr>
18//
19// * put in the volatile fix for midpoint with optimization;
20// checked regression test, and that speed comes out OK
21//
22//
23// 2007-10-16 Gavin Salam <salam@lpthe.jussieu.fr>
24//
25// * added protection to midpoint for cases where no stable cones
26// are found
27//
28// 2007-03-10 Gavin Salam <salam@lpthe.jussieu.fr>
29//
30// * added support for the pttilde scale choice in the CDF midpoint code
31//
32// 2007-02-21 Gavin Salam <salam@lpthe.jussieu.fr>
33//
34// * added option of choosing the scale used in the split-merge
35// procedure (pt [default], Et or mt)
36//
37// 2006-09-24 Gavin Salam <salam@lpthe.jussieu.fr>
38//
39// * removed the local_sort method
40//
41// 2006-09-24 Gavin Salam <salam@lpthe.jussieu.fr>
42//
43// * added JetClu+MidPoint to FastJet
44
45#include "MidPointAlgorithm.hh"
46#include "ClusterComparisons.hh"
47#include <algorithm>
48#include <iostream>
49#include <cmath>
50
51#include <fastjet/internal/base.hh>
52
53FASTJET_BEGIN_NAMESPACE
54
55namespace cdf{
56
57void MidPointAlgorithm::findStableConesFromSeeds(std::vector<PhysicsTower>& towers, std::vector<Cluster>& stableCones)
58{
59 bool reduceConeSize = true;
60 for(std::vector<PhysicsTower>::iterator towerIter = towers.begin(); towerIter != towers.end(); towerIter++)
61 if(towerIter->fourVector.pt() > _seedThreshold)
62 iterateCone(towerIter->fourVector.y(),towerIter->fourVector.phi(),0,towers,stableCones,reduceConeSize);
63}
64
65void MidPointAlgorithm::findStableConesFromMidPoints(std::vector<PhysicsTower>& towers, std::vector<Cluster>& stableCones)
66{
67 // distanceOK[i-1][j] = Is distance between stableCones i and j (i>j) less than 2*_coneRadius?
68 std::vector< std::vector<bool> > distanceOK;
69 distanceOK.resize(stableCones.size() - 1);
70 for(int nCluster1 = 1; nCluster1 < stableCones.size(); nCluster1++){
71 distanceOK[nCluster1 - 1].resize(nCluster1);
72 double cluster1Rapidity = stableCones[nCluster1].fourVector.y();
73 double cluster1Phi = stableCones[nCluster1].fourVector.phi();
74 for(int nCluster2 = 0; nCluster2 < nCluster1; nCluster2++){
75 double cluster2Rapidity = stableCones[nCluster2].fourVector.y();
76 double cluster2Phi = stableCones[nCluster2].fourVector.phi();
77 double dRapidity = fabs(cluster1Rapidity - cluster2Rapidity);
78 double dPhi = fabs(cluster1Phi - cluster2Phi);
79 if(dPhi > M_PI)
80 dPhi = 2*M_PI - dPhi;
81 double dR = sqrt(dRapidity*dRapidity + dPhi*dPhi);
82 distanceOK[nCluster1 - 1][nCluster2] = dR < 2*_coneRadius;
83 }
84 }
85
86 // Find all pairs (triplets, ...) of stableCones which are less than 2*_coneRadius apart from each other.
87 std::vector< std::vector<int> > pairs(0);
88 std::vector<int> testPair(0);
89 int maxClustersInPair = _maxPairSize;
90 if(!maxClustersInPair)
91 maxClustersInPair = stableCones.size();
92 addClustersToPairs(testPair,pairs,distanceOK,maxClustersInPair);
93
94 // Loop over all combinations. Calculate MidPoint. Make midPointClusters.
95 bool reduceConeSize = false;
96 for(int iPair = 0; iPair < pairs.size(); iPair++){
97 // Calculate rapidity, phi and pT of MidPoint.
98 LorentzVector midPoint(0,0,0,0);
99 for(int iPairMember = 0; iPairMember < pairs[iPair].size(); iPairMember++)
100 midPoint.add(stableCones[pairs[iPair][iPairMember]].fourVector);
101 iterateCone(midPoint.y(),midPoint.phi(),midPoint.pt(),towers,stableCones,reduceConeSize);
102 }
103
104 //sort(stableCones.begin(),stableCones.end(),ClusterPtGreater());
105 local_sort(stableCones); // GPS mod. to allow split-merge with various scales
106}
107
108
109void MidPointAlgorithm::iterateCone(volatile double startRapidity, volatile double startPhi, volatile double startPt,
110 std::vector<PhysicsTower>& towers, std::vector<Cluster>& stableCones, bool reduceConeSize)
111{
112 int nIterations = 0;
113 bool keepJet = true;
114 Cluster trialCone;
115 double iterationConeRadius = _coneRadius;
116 if(reduceConeSize)
117 iterationConeRadius *= sqrt(_coneAreaFraction);
118 while(nIterations++ < _maxIterations + 1 && keepJet){
119 trialCone.clear();
120 // Find particles which should go in the cone.
121 if(nIterations == _maxIterations + 1)
122 iterationConeRadius = _coneRadius;
123 for(std::vector<PhysicsTower>::iterator towerIter = towers.begin(); towerIter != towers.end(); towerIter++){
124 double dRapidity = fabs(towerIter->fourVector.y() - startRapidity);
125 double dPhi = fabs(towerIter->fourVector.phi() - startPhi);
126 if(dPhi > M_PI)
127 dPhi = 2*M_PI - dPhi;
128 double dR = sqrt(dRapidity*dRapidity + dPhi*dPhi);
129 if(dR < iterationConeRadius)
130 trialCone.addTower(*towerIter);
131 }
132 if(!trialCone.size()) // Empty cone?
133 keepJet = false;
134 else{
135 if(nIterations <= _maxIterations){
136 volatile double endRapidity = trialCone.fourVector.y();
137 volatile double endPhi = trialCone.fourVector.phi();
138 volatile double endPt = trialCone.fourVector.pt();
139 // Do we have a stable cone?
140 if(endRapidity == startRapidity && endPhi == startPhi && endPt == startPt){
141 // If cone size is reduced, then do one more iteration.
142 nIterations = _maxIterations;
143 if(!reduceConeSize)
144 nIterations++;
145 }
146 else{
147 // Another iteration.
148 startRapidity = endRapidity;
149 startPhi = endPhi;
150 startPt = endPt;
151 }
152 }
153 }
154 }
155
156 if(keepJet){
157 // We have a stable cone.
158 bool identical = false;
159 for(std::vector<Cluster>::iterator stableConeIter = stableCones.begin(); stableConeIter != stableCones.end(); stableConeIter++)
160 if(trialCone.fourVector.isEqual(stableConeIter->fourVector))
161 identical = true;
162 if(!identical)
163 stableCones.push_back(trialCone);
164 }
165}
166
167void MidPointAlgorithm::addClustersToPairs(std::vector<int>& testPair, std::vector< std::vector<int> >& pairs,
168 std::vector< std::vector<bool> >& distanceOK, int maxClustersInPair)
169{
170 // Recursively adds clusters to pairs, triplets, ... whose mid-points are then calculated.
171
172 // Find StableCone number to start with (either 0 at the beginning or last element of testPair + 1).
173 int nextClusterStart = 0;
174 if(testPair.size())
175 nextClusterStart = testPair.back() + 1;
176 for(int nextCluster = nextClusterStart; nextCluster <= distanceOK.size(); nextCluster++){
177 // Is new SeedCone less than 2*_coneRadius apart from all clusters in testPair?
178 bool addCluster = true;
179 for(int iCluster = 0; iCluster < testPair.size() && addCluster; iCluster++)
180 if(!distanceOK[nextCluster - 1][testPair[iCluster]])
181 addCluster = false;
182 if(addCluster){
183 // Add it to the testPair.
184 testPair.push_back(nextCluster);
185 // If testPair is a pair, add it to pairs.
186 if(testPair.size() > 1)
187 pairs.push_back(testPair);
188 // If not bigger than allowed, find more clusters within 2*_coneRadius.
189 if(testPair.size() < maxClustersInPair)
190 addClustersToPairs(testPair,pairs,distanceOK,maxClustersInPair);
191 // All combinations containing testPair found. Remove last element.
192 testPair.pop_back();
193 }
194 }
195}
196
197void MidPointAlgorithm::splitAndMerge(std::vector<Cluster>& stableCones, std::vector<Cluster>& jets)
198{
199 bool mergingNotFinished = true;
200 while(mergingNotFinished){
201 // Sort the stable cones (highest pt first).
202 //sort(stableCones.begin(),stableCones.end(),ClusterPtGreater());
203 local_sort(stableCones);
204
205 // Start with the highest pt cone.
206 std::vector<Cluster>::iterator stableConeIter1 = stableCones.begin();
207 if(stableConeIter1 == stableCones.end()) // Stable cone list empty?
208 mergingNotFinished = false;
209 else{
210 bool coneNotModified = true;
211 // Determine whether highest pt cone has an overlap with other stable cones.
212 std::vector<Cluster>::iterator stableConeIter2 = stableConeIter1;
213 stableConeIter2++; // 2nd highest pt cone.
214 while(coneNotModified && stableConeIter2 != stableCones.end()){
215 // Calculate overlap of the two cones.
216 Cluster overlap;
217 for(std::vector<PhysicsTower>::iterator towerIter1 = stableConeIter1->towerList.begin();
218 towerIter1 != stableConeIter1->towerList.end();
219 towerIter1++){
220 bool isInCone2 = false;
221 for(std::vector<PhysicsTower>::iterator towerIter2 = stableConeIter2->towerList.begin();
222 towerIter2 != stableConeIter2->towerList.end();
223 towerIter2++)
224 if(towerIter1->isEqual(*towerIter2))
225 isInCone2 = true;
226 if(isInCone2)
227 overlap.addTower(*towerIter1);
228 }
229 if(overlap.size()){ // non-empty overlap
230 coneNotModified = false;
231 // GPS mod to allow various scale choices in split merge --------
232 double overlap_scale, jet2_scale;
233 switch(_smScale) {
234 case SM_pt:
235 overlap_scale = overlap.fourVector.pt();
236 jet2_scale = stableConeIter2->fourVector.pt();
237 break;
238 case SM_Et:
239 overlap_scale = overlap.fourVector.Et();
240 jet2_scale = stableConeIter2->fourVector.Et();
241 break;
242 case SM_mt:
243 overlap_scale = overlap.fourVector.mt();
244 jet2_scale = stableConeIter2->fourVector.mt();
245 break;
246 case SM_pttilde:
247 overlap_scale = overlap.pt_tilde;
248 jet2_scale = stableConeIter2->pt_tilde;
249 break;
250 default:
251 std::cerr << "Unrecognized value for _smScale: "
252 << _smScale << std::endl;
253 exit(-1);
254 }
255 if(overlap_scale >= _overlapThreshold*jet2_scale){
256 // end of GPS modification ---------------------------
257 //if(overlap.fourVector.pt() >= _overlapThreshold*stableConeIter2->fourVector.pt()){
258 // Merge the two cones.
259 for(std::vector<PhysicsTower>::iterator towerIter2 = stableConeIter2->towerList.begin();
260 towerIter2 != stableConeIter2->towerList.end();
261 towerIter2++){
262 bool isInOverlap = false;
263 for(std::vector<PhysicsTower>::iterator overlapTowerIter = overlap.towerList.begin();
264 overlapTowerIter != overlap.towerList.end();
265 overlapTowerIter++)
266 if(towerIter2->isEqual(*overlapTowerIter))
267 isInOverlap = true;
268 if(!isInOverlap)
269 stableConeIter1->addTower(*towerIter2);
270 }
271 // Remove the second cone.
272 stableCones.erase(stableConeIter2);
273 }
274 else{
275 // Separate the two cones.
276 // Which particle goes where?
277 std::vector<PhysicsTower> removeFromCone1,removeFromCone2;
278 for(std::vector<PhysicsTower>::iterator towerIter = overlap.towerList.begin();
279 towerIter != overlap.towerList.end();
280 towerIter++){
281 double towerRapidity = towerIter->fourVector.y();
282 double towerPhi = towerIter->fourVector.phi();
283 // Calculate distance from cone 1.
284 double dRapidity1 = fabs(towerRapidity - stableConeIter1->fourVector.y());
285 double dPhi1 = fabs(towerPhi - stableConeIter1->fourVector.phi());
286 if(dPhi1 > M_PI)
287 dPhi1 = 2*M_PI - dPhi1;
288 double dRJet1 = sqrt(dRapidity1*dRapidity1 + dPhi1*dPhi1);
289 // Calculate distance from cone 2.
290 double dRapidity2 = fabs(towerRapidity - stableConeIter2->fourVector.y());
291 double dPhi2 = fabs(towerPhi - stableConeIter2->fourVector.phi());
292 if(dPhi2 > M_PI)
293 dPhi2 = 2*M_PI - dPhi2;
294 double dRJet2 = sqrt(dRapidity2*dRapidity2 + dPhi2*dPhi2);
295 if(dRJet1 < dRJet2)
296 // Particle is closer to cone 1. To be removed from cone 2.
297 removeFromCone2.push_back(*towerIter);
298 else
299 // Particle is closer to cone 2. To be removed from cone 1.
300 removeFromCone1.push_back(*towerIter);
301 }
302 // Remove particles in the overlap region from the cones to which they have the larger distance.
303 for(std::vector<PhysicsTower>::iterator towerIter = removeFromCone1.begin();
304 towerIter != removeFromCone1.end();
305 towerIter++)
306 stableConeIter1->removeTower(*towerIter);
307 for(std::vector<PhysicsTower>::iterator towerIter = removeFromCone2.begin();
308 towerIter != removeFromCone2.end();
309 towerIter++)
310 stableConeIter2->removeTower(*towerIter);
311 }
312 }
313 stableConeIter2++;
314 }
315 if(coneNotModified){
316 // Cone 1 has no overlap with any of the other cones and can become a jet.
317 jets.push_back(*stableConeIter1);
318 stableCones.erase(stableConeIter1);
319 }
320 }
321 }
322
323 //sort(jets.begin(),jets.end(),ClusterPtGreater());
324 local_sort(jets); // GPS mod. to allow split-merge with various scales
325}
326
327
328
329void MidPointAlgorithm::local_sort(std::vector<Cluster>& clusters) {
330 switch(_smScale) {
331 case SM_pt:
332 sort(clusters.begin(),clusters.end(),ClusterPtGreater());
333 break;
334 case SM_Et:
335 sort(clusters.begin(),clusters.end(),ClusterFourVectorEtGreater());
336 break;
337 case SM_mt:
338 sort(clusters.begin(),clusters.end(),ClusterMtGreater());
339 break;
340 case SM_pttilde:
341 sort(clusters.begin(),clusters.end(),ClusterPtTildeGreater());
342 break;
343 default:
344 std::cerr << "Unrecognized value for _smScale: " << _smScale << std::endl;
345 exit(-1);
346 }
347}
348
349
350
351void MidPointAlgorithm::run(std::vector<PhysicsTower>& towers, std::vector<Cluster>& jets)
352{
353 std::vector<Cluster> stableCones;
354 findStableConesFromSeeds(towers,stableCones);
355 // GPS addition to prevent crashes if no stable cones
356 // are found (e.g. all particles below seed threshold)
357 if (stableCones.size() > 0) {
358 findStableConesFromMidPoints(towers,stableCones);
359 splitAndMerge(stableCones,jets);
360 }
361}
362
363} // namespace cdf
364
365FASTJET_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.