00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "fastjet/ClusterSequence.hh"
00032 #include "fastjet/internal/ClosestPair2D.hh"
00033 #include<limits>
00034 #include<vector>
00035 #include<cmath>
00036 #include<iostream>
00037
00038 FASTJET_BEGIN_NAMESPACE
00039
00040 using namespace std;
00041
00042
00043 namespace Private {
00044
00045 class MirrorInfo{
00046 public:
00047 int orig, mirror;
00048 MirrorInfo(int a, int b) : orig(a), mirror(b) {};
00049 MirrorInfo() {};
00050 };
00051
00052
00053
00054
00055 bool make_mirror(Coord2D & point, double Dlim) {
00056 if (point.y < Dlim) {point.y += twopi; return true;}
00057 if (twopi-point.y < Dlim) {point.y -= twopi; return true;}
00058 return false;
00059 }
00060
00061 }
00062
00063 using namespace Private;
00064
00065
00066
00067
00068
00069 void ClusterSequence::_CP2DChan_limited_cluster (double Dlim) {
00070
00071 unsigned int n = _initial_n;
00072
00073 vector<MirrorInfo> coordIDs(2*n);
00074 vector<int> jetIDs(2*n);
00075 vector<Coord2D> coords(2*n);
00076
00077
00078
00079
00080
00081
00082
00083 double Dlim4mirror = min(Dlim,pi);
00084
00085
00086 double minrap = numeric_limits<double>::max();
00087 double maxrap = -minrap;
00088 int coord_index = -1;
00089 int n_active = 0;
00090 for (unsigned jet_i = 0; jet_i < _jets.size(); jet_i++) {
00091
00092
00093
00094 if (_history[_jets[jet_i].cluster_hist_index()].child != Invalid ||
00095 (_jets[jet_i].E() == abs(_jets[jet_i].pz()) &&
00096 _jets[jet_i].perp2() == 0.0)
00097 ) {continue;}
00098
00099 n_active++;
00100
00101 coordIDs[jet_i].orig = ++coord_index;
00102 coords[coord_index] = Coord2D(_jets[jet_i].rap(), _jets[jet_i].phi_02pi());
00103 jetIDs[coord_index] = jet_i;
00104 minrap = min(coords[coord_index].x,minrap);
00105 maxrap = max(coords[coord_index].x,maxrap);
00106
00107 Coord2D mirror_point(coords[coord_index]);
00108 if (make_mirror(mirror_point, Dlim4mirror)) {
00109 coordIDs[jet_i].mirror = ++coord_index;
00110 coords[coord_index] = mirror_point;
00111 jetIDs[coord_index] = jet_i;
00112 } else {
00113 coordIDs[jet_i].mirror = Invalid;
00114 }
00115 }
00116
00117
00118 coords.resize(coord_index+1);
00119
00120
00121 Coord2D left_edge(minrap-1.0, -3.15);
00122 Coord2D right_edge(maxrap+1.0, 9.45);
00123
00124
00125
00126
00127 ClosestPair2D cp(coords, left_edge, right_edge);
00128
00129
00130
00131
00132
00133
00134 vector<Coord2D> new_points(2);
00135 vector<unsigned int> cIDs_to_remove(4);
00136 vector<unsigned int> new_cIDs(2);
00137
00138 do {
00139
00140 unsigned int cID1, cID2;
00141 double distance2;
00142 cp.closest_pair(cID1,cID2,distance2);
00143
00144
00145 if (distance2 > Dlim*Dlim) {break;}
00146
00147
00148 distance2 *= _invR2;
00149
00150
00151 int jet_i = jetIDs[cID1];
00152 int jet_j = jetIDs[cID2];
00153 assert (jet_i != jet_j);
00154 int newjet_k;
00155 _do_ij_recombination_step(jet_i, jet_j, distance2, newjet_k);
00156
00157
00158
00159 if (--n_active == 1) {break;}
00160
00161
00162 cIDs_to_remove.resize(0);
00163 cIDs_to_remove.push_back(coordIDs[jet_i].orig);
00164 cIDs_to_remove.push_back(coordIDs[jet_j].orig);
00165 if (coordIDs[jet_i].mirror != Invalid)
00166 cIDs_to_remove.push_back(coordIDs[jet_i].mirror);
00167 if (coordIDs[jet_j].mirror != Invalid)
00168 cIDs_to_remove.push_back(coordIDs[jet_j].mirror);
00169
00170 Coord2D new_point(_jets[newjet_k].rap(),_jets[newjet_k].phi_02pi());
00171 new_points.resize(0);
00172 new_points.push_back(new_point);
00173 if (make_mirror(new_point, Dlim4mirror)) new_points.push_back(new_point);
00174
00175
00176 cp.replace_many(cIDs_to_remove, new_points, new_cIDs);
00177
00178
00179 coordIDs[newjet_k].orig = new_cIDs[0];
00180 jetIDs[new_cIDs[0]] = newjet_k;
00181 if (new_cIDs.size() == 2) {
00182 coordIDs[newjet_k].mirror = new_cIDs[1];
00183 jetIDs[new_cIDs[1]] = newjet_k;
00184 } else {coordIDs[newjet_k].mirror = Invalid;}
00185
00186
00187
00188
00189
00190 } while(true);
00191
00192
00193
00194
00195
00196 }
00197
00198
00199
00200
00201
00202 void ClusterSequence::_CP2DChan_cluster_2pi2R () {
00203
00204 if (_jet_algorithm != cambridge_algorithm) throw Error("CP2DChan clustering method called for a jet-finder that is not the cambridge algorithm");
00205
00206
00207
00208 _CP2DChan_limited_cluster(_Rparam);
00209
00210
00211 _do_Cambridge_inclusive_jets();
00212 }
00213
00214
00215
00216
00217
00218 void ClusterSequence::_CP2DChan_cluster_2piMultD () {
00219
00220
00221 if (_Rparam >= 0.39) {
00222 _CP2DChan_limited_cluster(min(_Rparam/2,0.3));
00223 }
00224
00225
00226 _CP2DChan_cluster_2pi2R ();
00227 }
00228
00229
00230
00231
00232 void ClusterSequence::_CP2DChan_cluster () {
00233
00234 if (_jet_algorithm != cambridge_algorithm) throw Error("_CP2DChan_cluster called for a jet-finder that is not the cambridge algorithm");
00235
00236 unsigned int n = _jets.size();
00237
00238 vector<MirrorInfo> coordIDs(2*n);
00239 vector<int> jetIDs(2*n);
00240 vector<Coord2D> coords(2*n);
00241
00242
00243 double minrap = numeric_limits<double>::max();
00244 double maxrap = -minrap;
00245 int coord_index = 0;
00246 for (unsigned i = 0; i < n; i++) {
00247
00248 if (_jets[i].E() == abs(_jets[i].pz()) && _jets[i].perp2() == 0.0) {
00249 coordIDs[i] = MirrorInfo(BeamJet,BeamJet);
00250 } else {
00251 coordIDs[i].orig = coord_index;
00252 coordIDs[i].mirror = coord_index+1;
00253 coords[coord_index] = Coord2D(_jets[i].rap(), _jets[i].phi_02pi());
00254 coords[coord_index+1] = Coord2D(_jets[i].rap(), _jets[i].phi_02pi()+twopi);
00255 jetIDs[coord_index] = i;
00256 jetIDs[coord_index+1] = i;
00257 minrap = min(coords[coord_index].x,minrap);
00258 maxrap = max(coords[coord_index].x,maxrap);
00259 coord_index += 2;
00260 }
00261 }
00262
00263 for (unsigned i = n; i < 2*n; i++) {coordIDs[i].orig = Invalid;}
00264
00265
00266 coords.resize(coord_index);
00267
00268
00269 Coord2D left_edge(minrap-1.0, 0.0);
00270 Coord2D right_edge(maxrap+1.0, 2*twopi);
00271
00272
00273 ClosestPair2D cp(coords, left_edge, right_edge);
00274
00275
00276 vector<Coord2D> new_points(2);
00277 vector<unsigned int> cIDs_to_remove(4);
00278 vector<unsigned int> new_cIDs(2);
00279 do {
00280
00281 unsigned int cID1, cID2;
00282 double distance2;
00283 cp.closest_pair(cID1,cID2,distance2);
00284 distance2 *= _invR2;
00285
00286
00287 if (distance2 > 1.0) {break;}
00288
00289
00290 int jet_i = jetIDs[cID1];
00291 int jet_j = jetIDs[cID2];
00292 assert (jet_i != jet_j);
00293 int newjet_k;
00294 _do_ij_recombination_step(jet_i, jet_j, distance2, newjet_k);
00295
00296
00297 cIDs_to_remove[0] = coordIDs[jet_i].orig;
00298 cIDs_to_remove[1] = coordIDs[jet_i].mirror;
00299 cIDs_to_remove[2] = coordIDs[jet_j].orig;
00300 cIDs_to_remove[3] = coordIDs[jet_j].mirror;
00301 new_points[0] = Coord2D(_jets[newjet_k].rap(),_jets[newjet_k].phi_02pi());
00302 new_points[1] = Coord2D(_jets[newjet_k].rap(),_jets[newjet_k].phi_02pi()+twopi);
00303
00304
00305
00306 new_cIDs[0] = cp.replace(cIDs_to_remove[0], cIDs_to_remove[2], new_points[0]);
00307 new_cIDs[1] = cp.replace(cIDs_to_remove[1], cIDs_to_remove[3], new_points[1]);
00308
00309 coordIDs[jet_i].orig = Invalid;
00310 coordIDs[jet_j].orig = Invalid;
00311
00312 coordIDs[newjet_k] = MirrorInfo(new_cIDs[0], new_cIDs[1]);
00313 jetIDs[new_cIDs[0]] = newjet_k;
00314 jetIDs[new_cIDs[1]] = newjet_k;
00315
00316
00317 n--;
00318 if (n == 1) {break;}
00319
00320 } while(true);
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 _do_Cambridge_inclusive_jets();
00334
00335
00336
00337
00338
00339
00340
00341
00342 }
00343
00344
00345
00346 void ClusterSequence::_do_Cambridge_inclusive_jets () {
00347 unsigned int n = _history.size();
00348 for (unsigned int hist_i = 0; hist_i < n; hist_i++) {
00349 if (_history[hist_i].child == Invalid) {
00350 _do_iB_recombination_step(_history[hist_i].jetp_index, 1.0);
00351 }
00352 }
00353 }
00354
00355 FASTJET_END_NAMESPACE
00356