1 #ifndef __FASTJET_NNFJN2TILED_HH__ 
    2 #define __FASTJET_NNFJN2TILED_HH__ 
   34 #include "fastjet/NNBase.hh" 
   35 #include "fastjet/internal/TilingExtent.hh" 
   37 FASTJET_BEGIN_NAMESPACE      
 
  118   NNFJN2Tiled(
const std::vector<PseudoJet> & jets, 
double requested_tile_size)
 
  119     : 
NNBase<I>(),     _requested_tile_size(requested_tile_size) {start(jets);}
 
  120   NNFJN2Tiled(
const std::vector<PseudoJet> & jets, 
double requested_tile_size, I * info)
 
  121     : 
NNBase<I>(info), _requested_tile_size(requested_tile_size) {start(jets);}
 
  123   void start(
const std::vector<PseudoJet> & jets);
 
  127   double dij_min(
int & iA, 
int & iB);
 
  130   void remove_jet(
int iA);
 
  134   void merge_jets(
int iA, 
int iB, 
const PseudoJet & jet, 
int jet_index);
 
  148   void _initialise_tiles(
const std::vector<PseudoJet> & particles);
 
  151   inline double _compute_diJ(
const TiledJet * 
const jet)
 const {
 
  152     double mom_fact = jet->momentum_factor();
 
  153     if (jet->NN != NULL) {
 
  154       double other_mom_fact = jet->NN->momentum_factor();
 
  155       if (other_mom_fact < mom_fact) {mom_fact = other_mom_fact;}
 
  157     return jet->NN_dist * mom_fact;
 
  162   inline int _tile_index (
int irap, 
int iphi)
 const {
 
  165     return (irap-_tiles_irap_min)*_n_tiles_phi
 
  166                   + (iphi+_n_tiles_phi) % _n_tiles_phi;
 
  169   int  _tile_index(
const double rap, 
const double phi) 
const;
 
  170   void _tiledjet_set_jetinfo ( TiledJet * 
const tiled_jet, 
const PseudoJet &jet, 
int index);
 
  171   void _bj_remove_from_tiles(TiledJet * 
const jet);
 
  172   void _initialise_tiles();
 
  173   void _print_tiles(TiledJet * briefjets ) 
const;
 
  174   void _add_neighbours_to_tile_union(
const int tile_index, 
int & n_near_tiles) 
const;
 
  175   void _add_untagged_neighbours_to_tile_union(
const int tile_index, 
int & n_near_tiles);
 
  179   TiledJet * briefjets;
 
  188   std::vector<TiledJet *> where_is;
 
  191   std::vector<int> tile_union;
 
  197   std::vector<Tile> _tiles;
 
  198   double _requested_tile_size;
 
  199   double _tiles_rap_min, _tiles_rap_max;
 
  200   double _tile_size_rap, _tile_size_phi;
 
  201   int    _n_tiles_phi,_tiles_irap_min,_tiles_irap_max;
 
  205   class TiledJet : 
public BJ {
 
  207     void init(
const PseudoJet & jet, 
int index_in) {
 
  209       other_init(index_in);
 
  211     void init(
const PseudoJet & jet, 
int index_in, I * info) {
 
  213       other_init(index_in);
 
  215     void other_init(
int index_in) {
 
  217       NN_dist = BJ::geometrical_beam_distance();
 
  220     int jet_index()
 const {
return _index;}
 
  223     TiledJet * NN, *previous, * next;
 
  224     int tile_index, diJ_posn;
 
  229     inline void label_minheap_update_needed() {diJ_posn = 1;}
 
  230     inline void label_minheap_update_done()   {diJ_posn = 0;}
 
  231     inline bool minheap_update_needed()
 const {
return diJ_posn==1;}
 
  239   static const int n_tile_neighbours = 9;
 
  246     Tile *   begin_tiles[n_tile_neighbours]; 
 
  248     Tile **  surrounding_tiles; 
 
  260   class diJ_plus_link {
 
  274   _initialise_tiles(jets);
 
  278   briefjets = 
new TiledJet[n];
 
  279   where_is.resize(2*n);
 
  281   TiledJet * jetA = briefjets, * jetB;
 
  285   tile_union.resize(3*n_tile_neighbours);
 
  288   for (
int i = 0; i< n; i++) {
 
  289     _tiledjet_set_jetinfo(jetA, jets[i], i);
 
  297   typename std::vector<Tile>::const_iterator tile;
 
  298   for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
 
  300     for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  301       for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
 
  302         double dist = jetA->geometrical_distance(jetB);
 
  303         if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  304         if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  308     for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
 
  309       for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
 
  310         for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
 
  311           double dist = jetA->geometrical_distance(jetB);
 
  312           if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
 
  313           if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
 
  321   diJ = 
new diJ_plus_link[n];
 
  323   for (
int i = 0; i < n; i++) {
 
  324     diJ[i].diJ = _compute_diJ(jetA); 
 
  336   diJ_plus_link * best, *stop; 
 
  342   double diJ_min = diJ[0].diJ; 
 
  345   for (diJ_plus_link * here = diJ+1; here != stop; here++) {
 
  346     if (here->diJ < diJ_min) {best = here; diJ_min  = here->diJ;}
 
  350   TiledJet * jetA = best->jet;
 
  351   iA = jetA->jet_index();
 
  352   iB = jetA->NN ? jetA->NN->jet_index() : -1;
 
  360   TiledJet * jetA = where_is[iA];
 
  362   _bj_remove_from_tiles(jetA);
 
  368   int n_near_tiles = 0;
 
  369   _add_untagged_neighbours_to_tile_union(jetA->tile_index, n_near_tiles);
 
  376   diJ[n].jet->diJ_posn = jetA->diJ_posn;
 
  377   diJ[jetA->diJ_posn] = diJ[n];
 
  381   for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  382     Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  383     tile_ptr->tagged = 
false; 
 
  385     for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  387       if (jetI->NN == jetA) {
 
  388         jetI->NN_dist = jetI->geometrical_beam_distance();
 
  391         for (Tile ** near_tile  = tile_ptr->begin_tiles; 
 
  392              near_tile != tile_ptr->end_tiles; near_tile++) {
 
  394           for (TiledJet * jetJ  = (*near_tile)->head; jetJ != NULL; jetJ = jetJ->next) {
 
  395             double dist = jetI->geometrical_distance(jetJ);
 
  396             if (dist < jetI->NN_dist && jetJ != jetI) {
 
  397               jetI->NN_dist = dist; jetI->NN = jetJ;
 
  401         diJ[jetI->diJ_posn].diJ = _compute_diJ(jetI); 
 
  413   TiledJet * jetA = where_is[iA];
 
  414   TiledJet * jetB = where_is[iB];
 
  421   if (jetA < jetB) {std::swap(jetA,jetB);}
 
  424   _bj_remove_from_tiles(jetA);
 
  425   TiledJet oldB = * jetB;  
 
  426   _bj_remove_from_tiles(jetB);
 
  427   _tiledjet_set_jetinfo(jetB, jet, index); 
 
  429   where_is[index] = jetB;
 
  435   int n_near_tiles = 0;
 
  436   _add_untagged_neighbours_to_tile_union(jetA->tile_index, n_near_tiles);
 
  437   if (jetB->tile_index != jetA->tile_index) {
 
  438     _add_untagged_neighbours_to_tile_union(jetB->tile_index, n_near_tiles);
 
  440   if (oldB.tile_index != jetA->tile_index && 
 
  441       oldB.tile_index != jetB->tile_index) {
 
  442     _add_untagged_neighbours_to_tile_union(oldB.tile_index, n_near_tiles);
 
  450   diJ[n].jet->diJ_posn = jetA->diJ_posn;
 
  451   diJ[jetA->diJ_posn] = diJ[n];
 
  456   for (
int itile = 0; itile < n_near_tiles; itile++) {
 
  457     Tile * tile_ptr = &_tiles[tile_union[itile]];
 
  458     tile_ptr->tagged = 
false; 
 
  460     for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
 
  462       if ((jetI->NN == jetA) || (jetI->NN == jetB)) {
 
  463         jetI->NN_dist = jetI->geometrical_beam_distance();
 
  466         for (Tile ** near_tile  = tile_ptr->begin_tiles; near_tile != tile_ptr->end_tiles; near_tile++) {
 
  468           for (TiledJet * jetJ  = (*near_tile)->head; jetJ != NULL; jetJ = jetJ->next) {
 
  469             double dist = jetI->geometrical_distance(jetJ);
 
  470             if (dist < jetI->NN_dist && jetJ != jetI) {
 
  471               jetI->NN_dist = dist; jetI->NN = jetJ;
 
  475         diJ[jetI->diJ_posn].diJ = _compute_diJ(jetI); 
 
  480       double dist = jetI->geometrical_distance(jetB);
 
  481       if (dist < jetI->NN_dist) {
 
  483           jetI->NN_dist = dist;
 
  485           diJ[jetI->diJ_posn].diJ = _compute_diJ(jetI); 
 
  488       if (dist < jetB->NN_dist) {
 
  490           jetB->NN_dist = dist;
 
  497   diJ[jetB->diJ_posn].diJ = _compute_diJ(jetB);
 
  520 template <
class BJ, 
class I>
 
  525   double default_size = _requested_tile_size>0.1 ? _requested_tile_size : 0.1;
 
  526   _tile_size_rap = default_size;
 
  530   _n_tiles_phi   = int(floor(twopi/default_size));
 
  531   if (_n_tiles_phi<3) _n_tiles_phi = 3;
 
  532   _tile_size_phi = twopi / _n_tiles_phi; 
 
  535   _tiles_rap_min = tiling_analysis.minrap();
 
  536   _tiles_rap_max = tiling_analysis.maxrap();
 
  539   _tiles_irap_min = int(floor(_tiles_rap_min/_tile_size_rap));
 
  540   _tiles_irap_max = int(floor( _tiles_rap_max/_tile_size_rap));
 
  541   _tiles_rap_min = _tiles_irap_min * _tile_size_rap;
 
  542   _tiles_rap_max = _tiles_irap_max * _tile_size_rap;
 
  545   _tiles.resize((_tiles_irap_max-_tiles_irap_min+1)*_n_tiles_phi);
 
  548   for (
int irap = _tiles_irap_min; irap <= _tiles_irap_max; irap++) {
 
  549     for (
int iphi = 0; iphi < _n_tiles_phi; iphi++) {
 
  550       Tile * tile = & _tiles[_tile_index(irap,iphi)];
 
  553       tile->begin_tiles[0] =  tile;
 
  554       Tile ** pptile = & (tile->begin_tiles[0]);
 
  558       tile->surrounding_tiles = pptile;
 
  559       if (irap > _tiles_irap_min) {
 
  563         for (
int idphi = -1; idphi <=+1; idphi++) {
 
  564           *pptile = & _tiles[_tile_index(irap-1,iphi+idphi)];
 
  569       *pptile = & _tiles[_tile_index(irap,iphi-1)];
 
  572       tile->RH_tiles = pptile;
 
  573       *pptile = & _tiles[_tile_index(irap,iphi+1)];
 
  576       if (irap < _tiles_irap_max) {
 
  577         for (
int idphi = -1; idphi <= +1; idphi++) {
 
  578           *pptile = & _tiles[_tile_index(irap+1,iphi+idphi)];
 
  583       tile->end_tiles = pptile;
 
  585       tile->tagged = 
false;
 
  593 template <
class BJ, 
class I>
 
  594 int NNFJN2Tiled<BJ,I>::_tile_index(
const double rap, 
const double phi)
 const {
 
  596   if      (rap <= _tiles_rap_min) {irap = 0;}
 
  597   else if (rap >= _tiles_rap_max) {irap = _tiles_irap_max-_tiles_irap_min;}
 
  600     irap = int(((rap - _tiles_rap_min) / _tile_size_rap));
 
  602     if (irap > _tiles_irap_max-_tiles_irap_min) {
 
  603       irap = _tiles_irap_max-_tiles_irap_min;} 
 
  609   iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
 
  610   return (iphi + irap * _n_tiles_phi);
 
  614 template <
class BJ, 
class I>
 
  615 void NNFJN2Tiled<BJ,I>::_bj_remove_from_tiles(TiledJet * 
const jet) {
 
  616   Tile * tile = & _tiles[jet->tile_index];
 
  618   if (jet->previous == NULL) {
 
  621     tile->head = jet->next;
 
  624     jet->previous->next = jet->next;
 
  626   if (jet->next != NULL) {
 
  628     jet->next->previous = jet->previous;
 
  636 template <
class BJ, 
class I>
 
  637 inline void NNFJN2Tiled<BJ,I>::_tiledjet_set_jetinfo(TiledJet * 
const tile_jet,
 
  638                                                    const PseudoJet &jet, 
 
  642   this->init_jet(tile_jet, jet, index); 
 
  647   tile_jet->tile_index = _tile_index(tile_jet->rap(), tile_jet->phi());
 
  650   Tile * tile = &_tiles[tile_jet->tile_index];
 
  651   tile_jet->previous   = NULL;
 
  652   tile_jet->next       = tile->head;
 
  653   if (tile_jet->next != NULL) {tile_jet->next->previous = tile_jet;}
 
  654   tile->head      = tile_jet;
 
  664 template <
class BJ, 
class I>
 
  665 void NNFJN2Tiled<BJ,I>::_add_neighbours_to_tile_union(
const int tile_index, 
 
  666                                                     int & n_near_tiles)
 const {
 
  667   for (Tile * 
const * near_tile = _tiles[tile_index].begin_tiles; 
 
  668        near_tile != _tiles[tile_index].end_tiles; near_tile++){
 
  670     tile_union[n_near_tiles] = *near_tile - & _tiles[0];
 
  696 template <
class BJ, 
class I>
 
  697 inline void NNFJN2Tiled<BJ,I>::_add_untagged_neighbours_to_tile_union(
 
  698                const int tile_index, 
 
  699                int & n_near_tiles)  {
 
  700   for (Tile ** near_tile = _tiles[tile_index].begin_tiles; 
 
  701        near_tile != _tiles[tile_index].end_tiles; near_tile++){
 
  702     if (! (*near_tile)->tagged) {
 
  703       (*near_tile)->tagged = 
true;
 
  705       tile_union[n_near_tiles] = *near_tile - & _tiles[0];
 
  713 FASTJET_END_NAMESPACE      
 
  716 #endif // __FASTJET_NNFJN2TILED_HH__