40#include "fastjet/PseudoJet.hh" 
   41#include "fastjet/ClusterSequence.hh" 
   42#include "fastjet/internal/MinHeap.hh" 
   43#include "fastjet/internal/TilingExtent.hh" 
   45FASTJET_BEGIN_NAMESPACE      
 
   51void 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;
 
   87void 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;
 
  176int 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);
 
  199inline 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;}
 
  220void 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];}
 
  243void 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];
 
  275inline 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];
 
  292void 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  while (tail != head) {
 
  351    double diJ_min = diJ[0];
 
  353    for (
int i = 1; i < n; i++) {
 
  354      if (diJ[i] < diJ_min) {diJ_min_jet = i; diJ_min  = diJ[i];}
 
  358    jetA = & briefjets[diJ_min_jet];
 
  373      if (jetA < jetB) {std::swap(jetA,jetB);}
 
  376      _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
 
  379      _bj_remove_from_tiles(jetA);
 
  381      _bj_remove_from_tiles(jetB);
 
  382      _tj_set_jetinfo(jetB, nn); 
 
  385      _do_iB_recombination_step(jetA->_jets_index, diJ_min);
 
  387      _bj_remove_from_tiles(jetA);
 
  392    int n_near_tiles = 0;
 
  393    _add_neighbours_to_tile_union(jetA->tile_index, tile_union, n_near_tiles);
 
  395      bool sort_it = 
false;
 
  396      if (jetB->tile_index != jetA->tile_index) {
 
  398        _add_neighbours_to_tile_union(jetB->tile_index,tile_union,n_near_tiles);
 
  400      if (oldB.tile_index != jetA->tile_index && 
 
  401          oldB.tile_index != jetB->tile_index) {
 
  403        _add_neighbours_to_tile_union(oldB.tile_index,tile_union,n_near_tiles);
 
  408        sort(tile_union.begin(), tile_union.begin()+n_near_tiles);
 
  411        for (
int i = 1; i < n_near_tiles; i++) {
 
  412          if (tile_union[i] != tile_union[nnn-1]) {
 
  413            tile_union[nnn] = tile_union[i]; 
 
  429      diJ[jetA - head] = diJ[tail-head];
 
  433      if (jetA->previous == NULL) {
 
  434        _tiles[jetA->tile_index].head = jetA;
 
  436        jetA->previous->next = jetA;
 
  438      if (jetA->next != NULL) {jetA->next->previous = jetA;}
 
  443    for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  444      Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  445      for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  447        if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
 
  451          for (Tile ** near_tile  = tile_ptr->begin_tiles; 
 
  452                       near_tile != tile_ptr->end_tiles; near_tile++) {
 
  454            for (TiledJet * jetJ  = (*near_tile)->head; 
 
  455                            jetJ != NULL; jetJ = jetJ->next) {
 
  456              double dist = _bj_dist(jetI,jetJ);
 
  457              if (dist < jetI->NN_dist && jetJ != jetI) {
 
  458                jetI->NN_dist = dist; jetI->NN = jetJ;
 
  462          diJ[jetI-head] = _bj_diJ(jetI); 
 
  467          double dist = _bj_dist(jetI,jetB);
 
  468          if (dist < jetI->NN_dist) {
 
  470              jetI->NN_dist = dist;
 
  472              diJ[jetI-head] = _bj_diJ(jetI); 
 
  475          if (dist < jetB->NN_dist) {
 
  477              jetB->NN_dist = dist;
 
  485    if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
 
  489    for (Tile ** near_tile = _tiles[tail->tile_index].begin_tiles; 
 
  490                 near_tile!= _tiles[tail->tile_index].end_tiles; near_tile++){
 
  492      for (TiledJet * jetJ = (*near_tile)->head; 
 
  493                     jetJ != NULL; jetJ = jetJ->next) {
 
  494        if (jetJ->NN == tail) {jetJ->NN = jetA;}
 
  503    if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
 
  516void ClusterSequence::_faster_tiled_N2_cluster() {
 
  520  int n = _jets.size();
 
  521  TiledJet * briefjets = 
new TiledJet[n];
 
  522  TiledJet * jetA = briefjets, * jetB;
 
  528  vector<int> tile_union(3*n_tile_neighbours);
 
  531  for (
int i = 0; i< n; i++) {
 
  532    _tj_set_jetinfo(jetA, i);
 
  536  TiledJet * head = briefjets; 
 
  539  vector<Tile>::const_iterator tile;
 
  540  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
 
  542    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  543      for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
 
  544        double dist = _bj_dist(jetA,jetB);
 
  545        if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  546        if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  550    for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
 
  551      for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  552        for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
 
  553          double dist = _bj_dist(jetA,jetB);
 
  554          if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  555          if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  566  struct diJ_plus_link {
 
  571  diJ_plus_link * diJ = 
new diJ_plus_link[n];
 
  573  for (
int i = 0; i < n; i++) {
 
  574    diJ[i].diJ = _bj_diJ(jetA); 
 
  585    diJ_plus_link * best, *stop; 
 
  589    double diJ_min = diJ[0].diJ; 
 
  592    for (diJ_plus_link * here = diJ+1; here != stop; here++) {
 
  593      if (here->diJ < diJ_min) {best = here; diJ_min  = here->diJ;}
 
  608      if (jetA < jetB) {std::swap(jetA,jetB);}
 
  611      _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
 
  614      _bj_remove_from_tiles(jetA);
 
  616      _bj_remove_from_tiles(jetB);
 
  617      _tj_set_jetinfo(jetB, nn); 
 
  622      _do_iB_recombination_step(jetA->_jets_index, diJ_min);
 
  623      _bj_remove_from_tiles(jetA);
 
  630    int n_near_tiles = 0;
 
  631    _add_untagged_neighbours_to_tile_union(jetA->tile_index, 
 
  632                                           tile_union, n_near_tiles);
 
  634      if (jetB->tile_index != jetA->tile_index) {
 
  635        _add_untagged_neighbours_to_tile_union(jetB->tile_index,
 
  636                                               tile_union,n_near_tiles);
 
  638      if (oldB.tile_index != jetA->tile_index && 
 
  639          oldB.tile_index != jetB->tile_index) {
 
  640        _add_untagged_neighbours_to_tile_union(oldB.tile_index,
 
  641                                               tile_union,n_near_tiles);
 
  650    diJ[n].jet->diJ_posn = jetA->diJ_posn;
 
  651    diJ[jetA->diJ_posn] = diJ[n];
 
  656    for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  657      Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  658      tile_ptr->tagged = 
false; 
 
  660      for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  662        if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
 
  666          for (Tile ** near_tile  = tile_ptr->begin_tiles; 
 
  667                       near_tile != tile_ptr->end_tiles; near_tile++) {
 
  669            for (TiledJet * jetJ  = (*near_tile)->head; 
 
  670                            jetJ != NULL; jetJ = jetJ->next) {
 
  671              double dist = _bj_dist(jetI,jetJ);
 
  672              if (dist < jetI->NN_dist && jetJ != jetI) {
 
  673                jetI->NN_dist = dist; jetI->NN = jetJ;
 
  677          diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); 
 
  683          double dist = _bj_dist(jetI,jetB);
 
  684          if (dist < jetI->NN_dist) {
 
  686              jetI->NN_dist = dist;
 
  688              diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); 
 
  691          if (dist < jetB->NN_dist) {
 
  693              jetB->NN_dist = dist;
 
  701    if (jetB != NULL) {diJ[jetB->diJ_posn].diJ = _bj_diJ(jetB);}
 
  713void ClusterSequence::_minheap_faster_tiled_N2_cluster() {
 
  717  int n = _jets.size();
 
  718  TiledJet * briefjets = 
new TiledJet[n];
 
  719  TiledJet * jetA = briefjets, * jetB;
 
  725  vector<int> tile_union(3*n_tile_neighbours);
 
  728  for (
int i = 0; i< n; i++) {
 
  729    _tj_set_jetinfo(jetA, i);
 
  733  TiledJet * head = briefjets; 
 
  736  vector<Tile>::const_iterator tile;
 
  737  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
 
  739    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  740      for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
 
  741        double dist = _bj_dist(jetA,jetB);
 
  742        if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  743        if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  747    for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
 
  748      for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  749        for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
 
  750          double dist = _bj_dist(jetA,jetB);
 
  751          if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  752          if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  779  vector<double> diJs(n);
 
  780  for (
int i = 0; i < n; i++) {
 
  781    diJs[i] = _bj_diJ(&briefjets[i]);
 
  782    briefjets[i].label_minheap_update_done();
 
  784  MinHeap minheap(diJs);
 
  786  vector<TiledJet *> jets_for_minheap;
 
  787  jets_for_minheap.reserve(n); 
 
  792    double diJ_min = minheap.minval() *_invR2;
 
  793    jetA = head + minheap.minloc();
 
  804      if (jetA < jetB) {std::swap(jetA,jetB);}
 
  807      _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
 
  810      _bj_remove_from_tiles(jetA);
 
  812      _bj_remove_from_tiles(jetB);
 
  813      _tj_set_jetinfo(jetB, nn); 
 
  818      _do_iB_recombination_step(jetA->_jets_index, diJ_min);
 
  819      _bj_remove_from_tiles(jetA);
 
  823    minheap.remove(jetA-head);
 
  829    int n_near_tiles = 0;
 
  830    _add_untagged_neighbours_to_tile_union(jetA->tile_index, 
 
  831                                           tile_union, n_near_tiles);
 
  833      if (jetB->tile_index != jetA->tile_index) {
 
  834        _add_untagged_neighbours_to_tile_union(jetB->tile_index,
 
  835                                               tile_union,n_near_tiles);
 
  837      if (oldB.tile_index != jetA->tile_index && 
 
  838          oldB.tile_index != jetB->tile_index) {
 
  846        _add_untagged_neighbours_to_tile_union(oldB.tile_index,
 
  847                                               tile_union,n_near_tiles);
 
  850      jetB->label_minheap_update_needed();
 
  851      jets_for_minheap.push_back(jetB);
 
  858    for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  859      Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  860      tile_ptr->tagged = 
false; 
 
  862      for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  864        if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
 
  868          if (!jetI->minheap_update_needed()) {
 
  869            jetI->label_minheap_update_needed();
 
  870            jets_for_minheap.push_back(jetI);}
 
  872          for (Tile ** near_tile  = tile_ptr->begin_tiles; 
 
  873                       near_tile != tile_ptr->end_tiles; near_tile++) {
 
  875            for (TiledJet * jetJ  = (*near_tile)->head; 
 
  876                            jetJ != NULL; jetJ = jetJ->next) {
 
  877              double dist = _bj_dist(jetI,jetJ);
 
  878              if (dist < jetI->NN_dist && jetJ != jetI) {
 
  879                jetI->NN_dist = dist; jetI->NN = jetJ;
 
  888          double dist = _bj_dist(jetI,jetB);
 
  889          if (dist < jetI->NN_dist) {
 
  891              jetI->NN_dist = dist;
 
  894              if (!jetI->minheap_update_needed()) {
 
  895                jetI->label_minheap_update_needed();
 
  896                jets_for_minheap.push_back(jetI);}
 
  899          if (dist < jetB->NN_dist) {
 
  901              jetB->NN_dist = dist;
 
  909    while (jets_for_minheap.size() > 0) {
 
  910      TiledJet * jetI = jets_for_minheap.back(); 
 
  911      jets_for_minheap.pop_back();
 
  912      minheap.update(jetI-head, _bj_diJ(jetI));
 
  913      jetI->label_minheap_update_done();