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>
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>
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>
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>
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>
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__ 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...