40 #include "fastjet/PseudoJet.hh" 
   41 #include "fastjet/ClusterSequence.hh" 
   42 #include "fastjet/internal/MinHeap.hh" 
   43 #include "fastjet/internal/TilingExtent.hh" 
   45 FASTJET_BEGIN_NAMESPACE      
 
   51 void ClusterSequence::_bj_remove_from_tiles(TiledJet * 
const jet) {
 
   52   Tile * tile = & _tiles[jet->tile_index];
 
   54   if (jet->previous == NULL) {
 
   57     tile->head = jet->next;
 
   60     jet->previous->next = jet->next;
 
   62   if (jet->next != NULL) {
 
   64     jet->next->previous = jet->previous;
 
   87 void ClusterSequence::_initialise_tiles() {
 
   91   double default_size = max(0.1,_Rparam);
 
   92   _tile_size_eta = default_size;
 
   96   _n_tiles_phi   = max(3,
int(floor(twopi/default_size)));
 
   97   _tile_size_phi = twopi / _n_tiles_phi; 
 
   99   TilingExtent tiling_analysis(*
this);
 
  100   _tiles_eta_min = tiling_analysis.minrap();
 
  101   _tiles_eta_max = tiling_analysis.maxrap();
 
  121   _tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
 
  122   _tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
 
  123   _tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
 
  124   _tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
 
  127   _tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
 
  130   for (
int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
 
  131     for (
int iphi = 0; iphi < _n_tiles_phi; iphi++) {
 
  132       Tile * tile = & _tiles[_tile_index(ieta,iphi)];
 
  135       tile->begin_tiles[0] =  tile;
 
  136       Tile ** pptile = & (tile->begin_tiles[0]);
 
  140       tile->surrounding_tiles = pptile;
 
  141       if (ieta > _tiles_ieta_min) {
 
  145         for (
int idphi = -1; idphi <=+1; idphi++) {
 
  146           *pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
 
  151       *pptile = & _tiles[_tile_index(ieta,iphi-1)];
 
  154       tile->RH_tiles = pptile;
 
  155       *pptile = & _tiles[_tile_index(ieta,iphi+1)];
 
  158       if (ieta < _tiles_ieta_max) {
 
  159         for (
int idphi = -1; idphi <= +1; idphi++) {
 
  160           *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
 
  165       tile->end_tiles = pptile;
 
  167       tile->tagged = 
false;
 
  176 int ClusterSequence::_tile_index(
const double eta, 
const double phi)
 const {
 
  178   if      (eta <= _tiles_eta_min) {ieta = 0;}
 
  179   else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
 
  182     ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
 
  184     if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
 
  185       ieta = _tiles_ieta_max-_tiles_ieta_min;} 
 
  191   iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
 
  192   return (iphi + ieta * _n_tiles_phi);
 
  199 inline void ClusterSequence::_tj_set_jetinfo( TiledJet * 
const jet,
 
  200                                               const int _jets_index) {
 
  202   _bj_set_jetinfo<>(jet, _jets_index);
 
  207   jet->tile_index = _tile_index(jet->eta, jet->phi);
 
  210   Tile * tile = &_tiles[jet->tile_index];
 
  211   jet->previous   = NULL;
 
  212   jet->next       = tile->head;
 
  213   if (jet->next != NULL) {jet->next->previous = jet;}
 
  220 void ClusterSequence::_print_tiles(TiledJet * briefjets )
 const {
 
  221   for (vector<Tile>::const_iterator tile = _tiles.begin(); 
 
  222        tile < _tiles.end(); tile++) {
 
  223     cout << 
"Tile " << tile - _tiles.begin()<<
" = ";
 
  225     for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
 
  226       list.push_back(jetI-briefjets);
 
  229     sort(list.begin(),list.end());
 
  230     for (
unsigned int i = 0; i < list.size(); i++) {cout <<
" "<<list[i];}
 
  243 void ClusterSequence::_add_neighbours_to_tile_union(
const int tile_index, 
 
  244                vector<int> & tile_union, 
int & n_near_tiles)
 const {
 
  245   for (Tile * 
const * near_tile = _tiles[tile_index].begin_tiles; 
 
  246        near_tile != _tiles[tile_index].end_tiles; near_tile++){
 
  248     tile_union[n_near_tiles] = *near_tile - & _tiles[0];
 
  275 inline void ClusterSequence::_add_untagged_neighbours_to_tile_union(
 
  276                const int tile_index, 
 
  277                vector<int> & tile_union, 
int & n_near_tiles)  {
 
  278   for (Tile ** near_tile = _tiles[tile_index].begin_tiles; 
 
  279        near_tile != _tiles[tile_index].end_tiles; near_tile++){
 
  280     if (! (*near_tile)->tagged) {
 
  281       (*near_tile)->tagged = 
true;
 
  283       tile_union[n_near_tiles] = *near_tile - & _tiles[0];
 
  292 void ClusterSequence::_tiled_N2_cluster() {
 
  296   int n = _jets.size();
 
  297   TiledJet * briefjets = 
new TiledJet[n];
 
  298   TiledJet * jetA = briefjets, * jetB;
 
  304   vector<int> tile_union(3*n_tile_neighbours);
 
  307   for (
int i = 0; i< n; i++) {
 
  308     _tj_set_jetinfo(jetA, i);
 
  312   TiledJet * tail = jetA; 
 
  313   TiledJet * head = briefjets; 
 
  316   vector<Tile>::const_iterator tile;
 
  317   for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
 
  319     for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  320       for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
 
  321         double dist = _bj_dist(jetA,jetB);
 
  322         if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  323         if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  327     for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
 
  328       for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  329         for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
 
  330           double dist = _bj_dist(jetA,jetB);
 
  331           if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  332           if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  340   double * diJ = 
new double[n];
 
  342   for (
int i = 0; i < n; i++) {
 
  343     diJ[i] = _bj_diJ(jetA);
 
  348   int history_location = n-1;
 
  349   while (tail != head) {
 
  352     double diJ_min = diJ[0];
 
  354     for (
int i = 1; i < n; i++) {
 
  355       if (diJ[i] < diJ_min) {diJ_min_jet = i; diJ_min  = diJ[i];}
 
  360     jetA = & briefjets[diJ_min_jet];
 
  375       if (jetA < jetB) {std::swap(jetA,jetB);}
 
  378       _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
 
  394       _bj_remove_from_tiles(jetA);
 
  396       _bj_remove_from_tiles(jetB);
 
  397       _tj_set_jetinfo(jetB, nn); 
 
  400       _do_iB_recombination_step(jetA->_jets_index, diJ_min);
 
  406       _bj_remove_from_tiles(jetA);
 
  411     int n_near_tiles = 0;
 
  412     _add_neighbours_to_tile_union(jetA->tile_index, tile_union, n_near_tiles);
 
  414       bool sort_it = 
false;
 
  415       if (jetB->tile_index != jetA->tile_index) {
 
  417         _add_neighbours_to_tile_union(jetB->tile_index,tile_union,n_near_tiles);
 
  419       if (oldB.tile_index != jetA->tile_index && 
 
  420           oldB.tile_index != jetB->tile_index) {
 
  422         _add_neighbours_to_tile_union(oldB.tile_index,tile_union,n_near_tiles);
 
  427         sort(tile_union.begin(), tile_union.begin()+n_near_tiles);
 
  430         for (
int i = 1; i < n_near_tiles; i++) {
 
  431           if (tile_union[i] != tile_union[nnn-1]) {
 
  432             tile_union[nnn] = tile_union[i]; 
 
  448       diJ[jetA - head] = diJ[tail-head];
 
  452       if (jetA->previous == NULL) {
 
  453         _tiles[jetA->tile_index].head = jetA;
 
  455         jetA->previous->next = jetA;
 
  457       if (jetA->next != NULL) {jetA->next->previous = jetA;}
 
  462     for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  463       Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  464       for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  466         if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
 
  470           for (Tile ** near_tile  = tile_ptr->begin_tiles; 
 
  471                        near_tile != tile_ptr->end_tiles; near_tile++) {
 
  473             for (TiledJet * jetJ  = (*near_tile)->head; 
 
  474                             jetJ != NULL; jetJ = jetJ->next) {
 
  475               double dist = _bj_dist(jetI,jetJ);
 
  476               if (dist < jetI->NN_dist && jetJ != jetI) {
 
  477                 jetI->NN_dist = dist; jetI->NN = jetJ;
 
  481           diJ[jetI-head] = _bj_diJ(jetI); 
 
  486           double dist = _bj_dist(jetI,jetB);
 
  487           if (dist < jetI->NN_dist) {
 
  489               jetI->NN_dist = dist;
 
  491               diJ[jetI-head] = _bj_diJ(jetI); 
 
  494           if (dist < jetB->NN_dist) {
 
  496               jetB->NN_dist = dist;
 
  504     if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
 
  508     for (Tile ** near_tile = _tiles[tail->tile_index].begin_tiles; 
 
  509                  near_tile!= _tiles[tail->tile_index].end_tiles; near_tile++){
 
  511       for (TiledJet * jetJ = (*near_tile)->head; 
 
  512                      jetJ != NULL; jetJ = jetJ->next) {
 
  513         if (jetJ->NN == tail) {jetJ->NN = jetA;}
 
  522     if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
 
  535 void ClusterSequence::_faster_tiled_N2_cluster() {
 
  539   int n = _jets.size();
 
  540   TiledJet * briefjets = 
new TiledJet[n];
 
  541   TiledJet * jetA = briefjets, * jetB;
 
  547   vector<int> tile_union(3*n_tile_neighbours);
 
  550   for (
int i = 0; i< n; i++) {
 
  551     _tj_set_jetinfo(jetA, i);
 
  555   TiledJet * head = briefjets; 
 
  558   vector<Tile>::const_iterator tile;
 
  559   for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
 
  561     for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  562       for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
 
  563         double dist = _bj_dist(jetA,jetB);
 
  564         if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  565         if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  569     for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
 
  570       for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  571         for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
 
  572           double dist = _bj_dist(jetA,jetB);
 
  573           if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  574           if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  585   struct diJ_plus_link {
 
  590   diJ_plus_link * diJ = 
new diJ_plus_link[n];
 
  592   for (
int i = 0; i < n; i++) {
 
  593     diJ[i].diJ = _bj_diJ(jetA); 
 
  601   int history_location = n-1;
 
  605     diJ_plus_link * best, *stop; 
 
  609     double diJ_min = diJ[0].diJ; 
 
  612     for (diJ_plus_link * here = diJ+1; here != stop; here++) {
 
  613       if (here->diJ < diJ_min) {best = here; diJ_min  = here->diJ;}
 
  629       if (jetA < jetB) {std::swap(jetA,jetB);}
 
  632       _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
 
  647       _bj_remove_from_tiles(jetA);
 
  649       _bj_remove_from_tiles(jetB);
 
  650       _tj_set_jetinfo(jetB, nn); 
 
  655       _do_iB_recombination_step(jetA->_jets_index, diJ_min);
 
  659       _bj_remove_from_tiles(jetA);
 
  666     int n_near_tiles = 0;
 
  667     _add_untagged_neighbours_to_tile_union(jetA->tile_index, 
 
  668                                            tile_union, n_near_tiles);
 
  670       if (jetB->tile_index != jetA->tile_index) {
 
  671         _add_untagged_neighbours_to_tile_union(jetB->tile_index,
 
  672                                                tile_union,n_near_tiles);
 
  674       if (oldB.tile_index != jetA->tile_index && 
 
  675           oldB.tile_index != jetB->tile_index) {
 
  676         _add_untagged_neighbours_to_tile_union(oldB.tile_index,
 
  677                                                tile_union,n_near_tiles);
 
  686     diJ[n].jet->diJ_posn = jetA->diJ_posn;
 
  687     diJ[jetA->diJ_posn] = diJ[n];
 
  692     for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  693       Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  694       tile_ptr->tagged = 
false; 
 
  696       for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  698         if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
 
  702           for (Tile ** near_tile  = tile_ptr->begin_tiles; 
 
  703                        near_tile != tile_ptr->end_tiles; near_tile++) {
 
  705             for (TiledJet * jetJ  = (*near_tile)->head; 
 
  706                             jetJ != NULL; jetJ = jetJ->next) {
 
  707               double dist = _bj_dist(jetI,jetJ);
 
  708               if (dist < jetI->NN_dist && jetJ != jetI) {
 
  709                 jetI->NN_dist = dist; jetI->NN = jetJ;
 
  713           diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); 
 
  719           double dist = _bj_dist(jetI,jetB);
 
  720           if (dist < jetI->NN_dist) {
 
  722               jetI->NN_dist = dist;
 
  724               diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); 
 
  727           if (dist < jetB->NN_dist) {
 
  729               jetB->NN_dist = dist;
 
  737     if (jetB != NULL) {diJ[jetB->diJ_posn].diJ = _bj_diJ(jetB);}
 
  749 void ClusterSequence::_minheap_faster_tiled_N2_cluster() {
 
  753   int n = _jets.size();
 
  754   TiledJet * briefjets = 
new TiledJet[n];
 
  755   TiledJet * jetA = briefjets, * jetB;
 
  761   vector<int> tile_union(3*n_tile_neighbours);
 
  764   for (
int i = 0; i< n; i++) {
 
  765     _tj_set_jetinfo(jetA, i);
 
  769   TiledJet * head = briefjets; 
 
  772   vector<Tile>::const_iterator tile;
 
  773   for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
 
  775     for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  776       for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
 
  777         double dist = _bj_dist(jetA,jetB);
 
  778         if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  779         if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  783     for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
 
  784       for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  785         for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
 
  786           double dist = _bj_dist(jetA,jetB);
 
  787           if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  788           if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  815   vector<double> diJs(n);
 
  816   for (
int i = 0; i < n; i++) {
 
  817     diJs[i] = _bj_diJ(&briefjets[i]);
 
  818     briefjets[i].label_minheap_update_done();
 
  820   MinHeap minheap(diJs);
 
  822   vector<TiledJet *> jets_for_minheap;
 
  823   jets_for_minheap.reserve(n); 
 
  826   int history_location = n-1;
 
  829     double diJ_min = minheap.minval() *_invR2;
 
  830     jetA = head + minheap.minloc();
 
  842       if (jetA < jetB) {std::swap(jetA,jetB);}
 
  845       _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
 
  848       _bj_remove_from_tiles(jetA);
 
  850       _bj_remove_from_tiles(jetB);
 
  851       _tj_set_jetinfo(jetB, nn); 
 
  856       _do_iB_recombination_step(jetA->_jets_index, diJ_min);
 
  857       _bj_remove_from_tiles(jetA);
 
  861     minheap.remove(jetA-head);
 
  867     int n_near_tiles = 0;
 
  868     _add_untagged_neighbours_to_tile_union(jetA->tile_index, 
 
  869                                            tile_union, n_near_tiles);
 
  871       if (jetB->tile_index != jetA->tile_index) {
 
  872         _add_untagged_neighbours_to_tile_union(jetB->tile_index,
 
  873                                                tile_union,n_near_tiles);
 
  875       if (oldB.tile_index != jetA->tile_index && 
 
  876           oldB.tile_index != jetB->tile_index) {
 
  884         _add_untagged_neighbours_to_tile_union(oldB.tile_index,
 
  885                                                tile_union,n_near_tiles);
 
  888       jetB->label_minheap_update_needed();
 
  889       jets_for_minheap.push_back(jetB);
 
  896     for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  897       Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  898       tile_ptr->tagged = 
false; 
 
  900       for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  902         if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
 
  906           if (!jetI->minheap_update_needed()) {
 
  907             jetI->label_minheap_update_needed();
 
  908             jets_for_minheap.push_back(jetI);}
 
  910           for (Tile ** near_tile  = tile_ptr->begin_tiles; 
 
  911                        near_tile != tile_ptr->end_tiles; near_tile++) {
 
  913             for (TiledJet * jetJ  = (*near_tile)->head; 
 
  914                             jetJ != NULL; jetJ = jetJ->next) {
 
  915               double dist = _bj_dist(jetI,jetJ);
 
  916               if (dist < jetI->NN_dist && jetJ != jetI) {
 
  917                 jetI->NN_dist = dist; jetI->NN = jetJ;
 
  926           double dist = _bj_dist(jetI,jetB);
 
  927           if (dist < jetI->NN_dist) {
 
  929               jetI->NN_dist = dist;
 
  932               if (!jetI->minheap_update_needed()) {
 
  933                 jetI->label_minheap_update_needed();
 
  934                 jets_for_minheap.push_back(jetI);}
 
  937           if (dist < jetB->NN_dist) {
 
  939               jetB->NN_dist = dist;
 
  947     while (jets_for_minheap.size() > 0) {
 
  948       TiledJet * jetI = jets_for_minheap.back(); 
 
  949       jets_for_minheap.pop_back();
 
  950       minheap.update(jetI-head, _bj_diJ(jetI));
 
  951       jetI->label_minheap_update_done();
 
  961 FASTJET_END_NAMESPACE