00001 #ifndef __NNH_HH__
00002 #define __NNH_HH__
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
00032
00033
00034 #include<fastjet/ClusterSequence.hh>
00035
00036
00037 FASTJET_BEGIN_NAMESPACE
00038
00042 class _NoInfo {};
00043
00047 template<class I> class NNHInfo {
00048 public:
00049 NNHInfo() : _info(NULL) {}
00050 NNHInfo(I * info) : _info(info) {}
00051 template<class NNBJ> void init_jet(NNBJ * briefjet, const fastjet::PseudoJet & jet, int index) { briefjet->init(jet, index, _info);}
00052 private:
00053 I * _info;
00054 };
00055
00058 template<> class NNHInfo<_NoInfo> {
00059 public:
00060 NNHInfo() {}
00061 NNHInfo(_NoInfo * info) {}
00062 template<class NNBJ> void init_jet(NNBJ * briefjet, const fastjet::PseudoJet & jet, int index) { briefjet->init(jet, index);}
00063 };
00064
00065
00066
00112
00113 template<class BJ, class I = _NoInfo> class NNH : public NNHInfo<I> {
00114 public:
00115
00118 NNH(const std::vector<PseudoJet> & jets) {start(jets);}
00119 NNH(const std::vector<PseudoJet> & jets, I * info) : NNHInfo<I>(info) {start(jets);}
00120
00121 void start(const std::vector<PseudoJet> & jets);
00122
00125 double dij_min(int & iA, int & iB);
00126
00128 void remove_jet(int iA);
00129
00132 void merge_jets(int iA, int iB, const PseudoJet & jet, int jet_index);
00133
00135 ~NNH() {
00136 delete[] briefjets;
00137 }
00138
00139 private:
00140 class NNBJ;
00141
00145 void set_NN_crosscheck(NNBJ * jet, NNBJ * begin, NNBJ * end);
00146
00149 void set_NN_nocross (NNBJ * jet, NNBJ * begin, NNBJ * end);
00150
00152 NNBJ * briefjets;
00153
00155 NNBJ * head, * tail;
00156
00158 int n;
00159
00161 std::vector<NNBJ *> where_is;
00162
00165 class NNBJ : public BJ {
00166 public:
00167 void init(const PseudoJet & jet, int index) {
00168 BJ::init(jet);
00169 other_init(index);
00170 }
00171 void init(const PseudoJet & jet, int index, I * info) {
00172 BJ::init(jet, info);
00173 other_init(index);
00174 }
00175 void other_init(int index) {
00176 _index = index;
00177 NN_dist = BJ::beam_distance();
00178 NN = NULL;
00179 }
00180 int index() const {return _index;}
00181
00182 double NN_dist;
00183 NNBJ * NN;
00184
00185 private:
00186 int _index;
00187 };
00188
00189 };
00190
00191
00192
00193
00194 template<class BJ, class I> void NNH<BJ,I>::start(const std::vector<PseudoJet> & jets) {
00195 n = jets.size();
00196 briefjets = new NNBJ[n];
00197 where_is.resize(2*n);
00198
00199 NNBJ * jetA = briefjets;
00200
00201
00202 for (int i = 0; i< n; i++) {
00203
00204 init_jet(jetA, jets[i], i);
00205 where_is[i] = jetA;
00206 jetA++;
00207 }
00208 tail = jetA;
00209 head = briefjets;
00210
00211
00212
00213 for (jetA = head + 1; jetA != tail; jetA++) {
00214
00215
00216
00217 set_NN_crosscheck(jetA, head, jetA);
00218 }
00219
00220 }
00221
00222
00223
00224 template<class BJ, class I> double NNH<BJ,I>::dij_min(int & iA, int & iB) {
00225
00226 double diJ_min = briefjets[0].NN_dist;
00227 int diJ_min_jet = 0;
00228 for (int i = 1; i < n; i++) {
00229 if (briefjets[i].NN_dist < diJ_min) {
00230 diJ_min_jet = i;
00231 diJ_min = briefjets[i].NN_dist;
00232 }
00233 }
00234
00235
00236 NNBJ * jetA = & briefjets[diJ_min_jet];
00237
00238 iA = jetA->index();
00239 iB = jetA->NN ? jetA->NN->index() : -1;
00240 return diJ_min;
00241 }
00242
00243
00244
00245
00246 template<class BJ, class I> void NNH<BJ,I>::remove_jet(int iA) {
00247 NNBJ * jetA = where_is[iA];
00248
00249
00250 tail--; n--;
00251
00252 *jetA = *tail;
00253
00254 where_is[jetA->index()] = jetA;
00255
00256 for (NNBJ * jetI = head; jetI != tail; jetI++) {
00257
00258 if (jetI->NN == jetA) set_NN_nocross(jetI, head, tail);
00259
00260
00261 if (jetI->NN == tail) {jetI->NN = jetA;}
00262 }
00263 }
00264
00265
00266
00267 template<class BJ, class I> void NNH<BJ,I>::merge_jets(int iA, int iB,
00268 const PseudoJet & jet, int index) {
00269
00270 NNBJ * jetA = where_is[iA];
00271 NNBJ * jetB = where_is[iB];
00272
00273
00274
00275
00276
00277 if (jetA < jetB) std::swap(jetA,jetB);
00278
00279
00280
00281 init_jet(jetB, jet, index);
00282
00283 if (index >= int(where_is.size())) where_is.resize(2*index);
00284 where_is[jetB->index()] = jetB;
00285
00286
00287
00288 tail--; n--;
00289
00290 *jetA = *tail;
00291
00292 where_is[jetA->index()] = jetA;
00293
00294 for (NNBJ * jetI = head; jetI != tail; jetI++) {
00295
00296 if (jetI->NN == jetA || jetI->NN == jetB) {
00297 set_NN_nocross(jetI, head, tail);
00298 }
00299
00300
00301
00302 double dist = jetI->distance(jetB);
00303 if (dist < jetI->NN_dist) {
00304 if (jetI != jetB) {
00305 jetI->NN_dist = dist;
00306 jetI->NN = jetB;
00307 }
00308 }
00309 if (dist < jetB->NN_dist) {
00310 if (jetI != jetB) {
00311 jetB->NN_dist = dist;
00312 jetB->NN = jetI;
00313 }
00314 }
00315
00316
00317 if (jetI->NN == tail) {jetI->NN = jetA;}
00318 }
00319 }
00320
00321
00322
00323
00324 template <class BJ, class I> void NNH<BJ,I>::set_NN_crosscheck(NNBJ * jet,
00325 NNBJ * begin, NNBJ * end) {
00326 double NN_dist = jet->beam_distance();
00327 NNBJ * NN = NULL;
00328 for (NNBJ * jetB = begin; jetB != end; jetB++) {
00329 double dist = jet->distance(jetB);
00330 if (dist < NN_dist) {
00331 NN_dist = dist;
00332 NN = jetB;
00333 }
00334 if (dist < jetB->NN_dist) {
00335 jetB->NN_dist = dist;
00336 jetB->NN = jet;
00337 }
00338 }
00339 jet->NN = NN;
00340 jet->NN_dist = NN_dist;
00341 }
00342
00343
00344
00345
00346
00347 template <class BJ, class I> void NNH<BJ,I>::set_NN_nocross(
00348 NNBJ * jet, NNBJ * begin, NNBJ * end) {
00349 double NN_dist = jet->beam_distance();
00350 NNBJ * NN = NULL;
00351 if (head < jet) {
00352 for (NNBJ * jetB = head; jetB != jet; jetB++) {
00353 double dist = jet->distance(jetB);
00354 if (dist < NN_dist) {
00355 NN_dist = dist;
00356 NN = jetB;
00357 }
00358 }
00359 }
00360 if (tail > jet) {
00361 for (NNBJ * jetB = jet+1; jetB != tail; jetB++) {
00362 double dist = jet->distance (jetB);
00363 if (dist < NN_dist) {
00364 NN_dist = dist;
00365 NN = jetB;
00366 }
00367 }
00368 }
00369 jet->NN = NN;
00370 jet->NN_dist = NN_dist;
00371 }
00372
00373
00374
00375
00376 FASTJET_END_NAMESPACE
00377
00378
00379 #endif // __NNH_HH__