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 struct diJ_plus_link {
273 _initialise_tiles(jets);
277 briefjets =
new TiledJet[n];
278 where_is.resize(2*n);
280 TiledJet * jetA = briefjets, * jetB;
284 tile_union.resize(3*n_tile_neighbours);
287 for (
int i = 0; i< n; i++) {
288 _tiledjet_set_jetinfo(jetA, jets[i], i);
296 typename std::vector<Tile>::const_iterator tile;
297 for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
299 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
300 for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
301 double dist = jetA->geometrical_distance(jetB);
302 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
303 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
307 for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
308 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
309 for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
310 double dist = jetA->geometrical_distance(jetB);
311 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
312 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
320 diJ =
new diJ_plus_link[n];
322 for (
int i = 0; i < n; i++) {
323 diJ[i].diJ = _compute_diJ(jetA);
335 diJ_plus_link * best, *stop;
341 double diJ_min = diJ[0].diJ;
344 for (diJ_plus_link * here = diJ+1; here != stop; here++) {
345 if (here->diJ < diJ_min) {best = here; diJ_min = here->diJ;}
349 TiledJet * jetA = best->jet;
350 iA = jetA->jet_index();
351 iB = jetA->NN ? jetA->NN->jet_index() : -1;
359 TiledJet * jetA = where_is[iA];
361 _bj_remove_from_tiles(jetA);
367 int n_near_tiles = 0;
368 _add_untagged_neighbours_to_tile_union(jetA->tile_index, n_near_tiles);
375 diJ[n].jet->diJ_posn = jetA->diJ_posn;
376 diJ[jetA->diJ_posn] = diJ[n];
380 for (
int itile = 0; itile < n_near_tiles; itile++) {
381 Tile * tile_ptr = &_tiles[tile_union[itile]];
382 tile_ptr->tagged =
false;
384 for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
386 if (jetI->NN == jetA) {
387 jetI->NN_dist = jetI->geometrical_beam_distance();
390 for (Tile ** near_tile = tile_ptr->begin_tiles;
391 near_tile != tile_ptr->end_tiles; near_tile++) {
393 for (TiledJet * jetJ = (*near_tile)->head; jetJ != NULL; jetJ = jetJ->next) {
394 double dist = jetI->geometrical_distance(jetJ);
395 if (dist < jetI->NN_dist && jetJ != jetI) {
396 jetI->NN_dist = dist; jetI->NN = jetJ;
400 diJ[jetI->diJ_posn].diJ = _compute_diJ(jetI);
412 TiledJet * jetA = where_is[iA];
413 TiledJet * jetB = where_is[iB];
420 if (jetA < jetB) {std::swap(jetA,jetB);}
423 _bj_remove_from_tiles(jetA);
424 TiledJet oldB = * jetB;
425 _bj_remove_from_tiles(jetB);
426 _tiledjet_set_jetinfo(jetB, jet, index);
428 where_is[index] = jetB;
434 int n_near_tiles = 0;
435 _add_untagged_neighbours_to_tile_union(jetA->tile_index, n_near_tiles);
436 if (jetB->tile_index != jetA->tile_index) {
437 _add_untagged_neighbours_to_tile_union(jetB->tile_index, n_near_tiles);
439 if (oldB.tile_index != jetA->tile_index &&
440 oldB.tile_index != jetB->tile_index) {
441 _add_untagged_neighbours_to_tile_union(oldB.tile_index, n_near_tiles);
449 diJ[n].jet->diJ_posn = jetA->diJ_posn;
450 diJ[jetA->diJ_posn] = diJ[n];
455 for (
int itile = 0; itile < n_near_tiles; itile++) {
456 Tile * tile_ptr = &_tiles[tile_union[itile]];
457 tile_ptr->tagged =
false;
459 for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
461 if ((jetI->NN == jetA) || (jetI->NN == jetB)) {
462 jetI->NN_dist = jetI->geometrical_beam_distance();
465 for (Tile ** near_tile = tile_ptr->begin_tiles; near_tile != tile_ptr->end_tiles; near_tile++) {
467 for (TiledJet * jetJ = (*near_tile)->head; jetJ != NULL; jetJ = jetJ->next) {
468 double dist = jetI->geometrical_distance(jetJ);
469 if (dist < jetI->NN_dist && jetJ != jetI) {
470 jetI->NN_dist = dist; jetI->NN = jetJ;
474 diJ[jetI->diJ_posn].diJ = _compute_diJ(jetI);
479 double dist = jetI->geometrical_distance(jetB);
480 if (dist < jetI->NN_dist) {
482 jetI->NN_dist = dist;
484 diJ[jetI->diJ_posn].diJ = _compute_diJ(jetI);
487 if (dist < jetB->NN_dist) {
489 jetB->NN_dist = dist;
496 diJ[jetB->diJ_posn].diJ = _compute_diJ(jetB);
519 template <
class BJ,
class I>
524 double default_size = _requested_tile_size>0.1 ? _requested_tile_size : 0.1;
525 _tile_size_rap = default_size;
529 _n_tiles_phi = int(floor(twopi/default_size));
530 if (_n_tiles_phi<3) _n_tiles_phi = 3;
531 _tile_size_phi = twopi / _n_tiles_phi;
534 _tiles_rap_min = tiling_analysis.
minrap();
535 _tiles_rap_max = tiling_analysis.
maxrap();
538 _tiles_irap_min = int(floor(_tiles_rap_min/_tile_size_rap));
539 _tiles_irap_max = int(floor( _tiles_rap_max/_tile_size_rap));
540 _tiles_rap_min = _tiles_irap_min * _tile_size_rap;
541 _tiles_rap_max = _tiles_irap_max * _tile_size_rap;
544 _tiles.resize((_tiles_irap_max-_tiles_irap_min+1)*_n_tiles_phi);
547 for (
int irap = _tiles_irap_min; irap <= _tiles_irap_max; irap++) {
548 for (
int iphi = 0; iphi < _n_tiles_phi; iphi++) {
549 Tile * tile = & _tiles[_tile_index(irap,iphi)];
552 tile->begin_tiles[0] = tile;
553 Tile ** pptile = & (tile->begin_tiles[0]);
557 tile->surrounding_tiles = pptile;
558 if (irap > _tiles_irap_min) {
562 for (
int idphi = -1; idphi <=+1; idphi++) {
563 *pptile = & _tiles[_tile_index(irap-1,iphi+idphi)];
568 *pptile = & _tiles[_tile_index(irap,iphi-1)];
571 tile->RH_tiles = pptile;
572 *pptile = & _tiles[_tile_index(irap,iphi+1)];
575 if (irap < _tiles_irap_max) {
576 for (
int idphi = -1; idphi <= +1; idphi++) {
577 *pptile = & _tiles[_tile_index(irap+1,iphi+idphi)];
582 tile->end_tiles = pptile;
584 tile->tagged =
false;
592 template <
class BJ,
class I>
595 if (rap <= _tiles_rap_min) {irap = 0;}
596 else if (rap >= _tiles_rap_max) {irap = _tiles_irap_max-_tiles_irap_min;}
599 irap = int(((rap - _tiles_rap_min) / _tile_size_rap));
601 if (irap > _tiles_irap_max-_tiles_irap_min) {
602 irap = _tiles_irap_max-_tiles_irap_min;}
608 iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
609 return (iphi + irap * _n_tiles_phi);
613 template <
class BJ,
class I>
615 Tile * tile = & _tiles[jet->tile_index];
617 if (jet->previous == NULL) {
620 tile->head = jet->next;
623 jet->previous->next = jet->next;
625 if (jet->next != NULL) {
627 jet->next->previous = jet->previous;
635 template <
class BJ,
class I>
641 this->init_jet(tile_jet, jet, index);
646 tile_jet->tile_index = _tile_index(tile_jet->rap(), tile_jet->phi());
649 Tile * tile = &_tiles[tile_jet->tile_index];
650 tile_jet->previous = NULL;
651 tile_jet->next = tile->head;
652 if (tile_jet->next != NULL) {tile_jet->next->previous = tile_jet;}
653 tile->head = tile_jet;
663 template <
class BJ,
class I>
665 int & n_near_tiles)
const {
666 for (Tile *
const * near_tile = _tiles[tile_index].begin_tiles;
667 near_tile != _tiles[tile_index].end_tiles; near_tile++){
669 tile_union[n_near_tiles] = *near_tile - & _tiles[0];
695 template <
class BJ,
class I>
697 const int tile_index,
698 int & n_near_tiles) {
699 for (Tile ** near_tile = _tiles[tile_index].begin_tiles;
700 near_tile != _tiles[tile_index].end_tiles; near_tile++){
701 if (! (*near_tile)->tagged) {
702 (*near_tile)->tagged =
true;
704 tile_union[n_near_tiles] = *near_tile - & _tiles[0];
712 FASTJET_END_NAMESPACE
715 #endif // __FASTJET_NNFJN2TILED_HH__ Helps solve closest pair problems with factorised interparticle and beam distances (ie satisfying the...
class to perform a fast analysis of the appropriate rapidity range in which to perform tiling ...
NNFJN2Tiled(const std::vector< PseudoJet > &jets, double requested_tile_size)
constructor with an initial set of jets (which will be assigned indices 0...jets.size()-1) ...
~NNFJN2Tiled()
a destructor
double minrap() const
returns the suggested minimum rapidity for the tiling
Helps solve closest pair problems with generic interparticle and particle-beam distances.
double maxrap() const
returns the suggested maximum rapidity for the tiling
Class to contain pseudojets, including minimal information of use to jet-clustering routines...