819
815
FJCORE_END_NAMESPACE
820
816
#endif // __FJCORE_CLOSESTPAIR2D__HH__
817
#ifndef __FJCORE_LAZYTILING9ALT_HH__
818
#define __FJCORE_LAZYTILING9ALT_HH__
819
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
820
const double tile_edge_security_margin=1.0e-7;
823
double eta, phi, kt2, NN_dist;
824
TiledJet * NN, *previous, * next;
825
int _jets_index, tile_index;
826
bool _minheap_update_needed;
827
inline void label_minheap_update_needed() {_minheap_update_needed = true;}
828
inline void label_minheap_update_done() {_minheap_update_needed = false;}
829
inline bool minheap_update_needed() const {return _minheap_update_needed;}
831
const int n_tile_neighbours = 9;
834
typedef double (Tile::*DistToTileFn)(const TiledJet*) const;
835
typedef std::pair<Tile *, DistToTileFn> TileFnPair;
836
TileFnPair begin_tiles[n_tile_neighbours];
837
TileFnPair * surrounding_tiles;
838
TileFnPair * RH_tiles;
839
TileFnPair * end_tiles;
842
bool use_periodic_delta_phi;
844
double eta_min, eta_max, phi_min, phi_max;
845
double distance_to_centre(const TiledJet *) const {return 0;}
846
double distance_to_left(const TiledJet * jet) const {
847
double deta = jet->eta - eta_min;
850
double distance_to_right(const TiledJet * jet) const {
851
double deta = jet->eta - eta_max;
854
double distance_to_bottom(const TiledJet * jet) const {
855
double dphi = jet->phi - phi_min;
858
double distance_to_top(const TiledJet * jet) const {
859
double dphi = jet->phi - phi_max;
862
double distance_to_left_top(const TiledJet * jet) const {
863
double deta = jet->eta - eta_min;
864
double dphi = jet->phi - phi_max;
865
return deta*deta + dphi*dphi;
867
double distance_to_left_bottom(const TiledJet * jet) const {
868
double deta = jet->eta - eta_min;
869
double dphi = jet->phi - phi_min;
870
return deta*deta + dphi*dphi;
872
double distance_to_right_top(const TiledJet * jet) const {
873
double deta = jet->eta - eta_max;
874
double dphi = jet->phi - phi_max;
875
return deta*deta + dphi*dphi;
877
double distance_to_right_bottom(const TiledJet * jet) const {
878
double deta = jet->eta - eta_max;
879
double dphi = jet->phi - phi_min;
880
return deta*deta + dphi*dphi;
883
class LazyTiling9Alt {
885
LazyTiling9Alt(ClusterSequence & cs);
888
ClusterSequence & _cs;
889
const std::vector<PseudoJet> & _jets;
890
std::vector<Tile> _tiles;
891
double _Rparam, _R2, _invR2;
892
double _tiles_eta_min, _tiles_eta_max;
893
double _tile_size_eta, _tile_size_phi;
894
double _tile_half_size_eta, _tile_half_size_phi;
895
int _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
896
std::vector<TiledJet *> _jets_for_minheap;
897
void _initialise_tiles();
898
inline int _tile_index (int ieta, int iphi) const {
899
return (ieta-_tiles_ieta_min)*_n_tiles_phi
900
+ (iphi+_n_tiles_phi) % _n_tiles_phi;
902
void _bj_remove_from_tiles(TiledJet * const jet);
903
int _tile_index(const double eta, const double phi) const;
904
void _tj_set_jetinfo(TiledJet * const jet, const int _jets_index);
905
void _print_tiles(TiledJet * briefjets ) const;
906
void _add_neighbours_to_tile_union(const int tile_index,
907
std::vector<int> & tile_union, int & n_near_tiles) const;
908
void _add_untagged_neighbours_to_tile_union(const int tile_index,
909
std::vector<int> & tile_union, int & n_near_tiles);
910
void _add_untagged_neighbours_to_tile_union_using_max_info(const TiledJet * const jet,
911
std::vector<int> & tile_union, int & n_near_tiles);
912
void _update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
913
void _set_NN(TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
914
template <class J> double _bj_diJ(const J * const jet) const {
915
double kt2 = jet->kt2;
916
if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
917
return jet->NN_dist * kt2;
919
template <class J> inline void _bj_set_jetinfo(
920
J * const jetA, const int _jets_index) const {
921
jetA->eta = _jets[_jets_index].rap();
922
jetA->phi = _jets[_jets_index].phi_02pi();
923
jetA->kt2 = _cs.jet_scale_for_algorithm(_jets[_jets_index]);
924
jetA->_jets_index = _jets_index;
928
template <class J> inline double _bj_dist(
929
const J * const jetA, const J * const jetB) const {
930
double dphi = std::abs(jetA->phi - jetB->phi);
931
double deta = (jetA->eta - jetB->eta);
932
if (dphi > pi) {dphi = twopi - dphi;}
933
return dphi*dphi + deta*deta;
935
template <class J> inline double _bj_dist_not_periodic(
936
const J * const jetA, const J * const jetB) const {
937
double dphi = jetA->phi - jetB->phi;
938
double deta = (jetA->eta - jetB->eta);
939
return dphi*dphi + deta*deta;
943
#endif // __FJCORE_LAZYTILING9ALT_HH__
944
#ifndef __FJCORE_LAZYTILING9_HH__
945
#define __FJCORE_LAZYTILING9_HH__
946
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
950
Tile2Base * begin_tiles[NN];
951
Tile2Base ** surrounding_tiles;
952
Tile2Base ** RH_tiles;
953
Tile2Base ** end_tiles;
956
bool use_periodic_delta_phi;
958
double eta_centre, phi_centre;
959
int jet_count() const {
961
const TiledJet * jet = head;
969
typedef Tile2Base<9> Tile2;
972
LazyTiling9(ClusterSequence & cs);
975
ClusterSequence & _cs;
976
const std::vector<PseudoJet> & _jets;
977
std::vector<Tile2> _tiles;
979
int _ncall; // GPS tmp
980
int _ncall_dtt; // GPS tmp
981
#endif // INSTRUMENT2
982
double _Rparam, _R2, _invR2;
983
double _tiles_eta_min, _tiles_eta_max;
984
double _tile_size_eta, _tile_size_phi;
985
double _tile_half_size_eta, _tile_half_size_phi;
986
int _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
987
std::vector<TiledJet *> _jets_for_minheap;
988
void _initialise_tiles();
989
inline int _tile_index (int ieta, int iphi) const {
990
return (ieta-_tiles_ieta_min)*_n_tiles_phi
991
+ (iphi+_n_tiles_phi) % _n_tiles_phi;
993
void _bj_remove_from_tiles(TiledJet * const jet);
994
int _tile_index(const double eta, const double phi) const;
995
void _tj_set_jetinfo(TiledJet * const jet, const int _jets_index);
996
void _print_tiles(TiledJet * briefjets ) const;
997
void _add_neighbours_to_tile_union(const int tile_index,
998
std::vector<int> & tile_union, int & n_near_tiles) const;
999
void _add_untagged_neighbours_to_tile_union(const int tile_index,
1000
std::vector<int> & tile_union, int & n_near_tiles);
1001
void _add_untagged_neighbours_to_tile_union_using_max_info(const TiledJet * const jet,
1002
std::vector<int> & tile_union, int & n_near_tiles);
1003
double _distance_to_tile(const TiledJet * bj, const Tile2 *)
1009
void _update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
1010
void _set_NN(TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
1011
template <class J> double _bj_diJ(const J * const jet) const {
1012
double kt2 = jet->kt2;
1013
if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
1014
return jet->NN_dist * kt2;
1016
template <class J> inline void _bj_set_jetinfo(
1017
J * const jetA, const int _jets_index) const {
1018
jetA->eta = _jets[_jets_index].rap();
1019
jetA->phi = _jets[_jets_index].phi_02pi();
1020
jetA->kt2 = _cs.jet_scale_for_algorithm(_jets[_jets_index]);
1021
jetA->_jets_index = _jets_index;
1022
jetA->NN_dist = _R2;
1025
template <class J> inline double _bj_dist(
1026
const J * const jetA, const J * const jetB)
1029
_ncall++; // GPS tmp
1033
double dphi = std::abs(jetA->phi - jetB->phi);
1034
double deta = (jetA->eta - jetB->eta);
1035
if (dphi > pi) {dphi = twopi - dphi;}
1036
return dphi*dphi + deta*deta;
1038
template <class J> inline double _bj_dist_not_periodic(
1039
const J * const jetA, const J * const jetB)
1042
_ncall++; // GPS tmp
1046
double dphi = jetA->phi - jetB->phi;
1047
double deta = (jetA->eta - jetB->eta);
1048
return dphi*dphi + deta*deta;
1051
FJCORE_END_NAMESPACE
1052
#endif // __FJCORE_LAZYTILING9_HH__
1053
#ifndef __FJCORE_LAZYTILING25_HH__
1054
#define __FJCORE_LAZYTILING25_HH__
1055
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
1056
typedef Tile2Base<25> Tile25;
1057
class LazyTiling25 {
1059
LazyTiling25(ClusterSequence & cs);
1062
ClusterSequence & _cs;
1063
const std::vector<PseudoJet> & _jets;
1064
std::vector<Tile25> _tiles;
1066
int _ncall; // GPS tmp
1067
int _ncall_dtt; // GPS tmp
1068
#endif // INSTRUMENT2
1069
double _Rparam, _R2, _invR2;
1070
double _tiles_eta_min, _tiles_eta_max;
1071
double _tile_size_eta, _tile_size_phi;
1072
double _tile_half_size_eta, _tile_half_size_phi;
1073
int _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
1074
std::vector<TiledJet *> _jets_for_minheap;
1075
void _initialise_tiles();
1076
inline int _tile_index (int ieta, int iphi) const {
1077
return (ieta-_tiles_ieta_min)*_n_tiles_phi
1078
+ (iphi+_n_tiles_phi) % _n_tiles_phi;
1080
void _bj_remove_from_tiles(TiledJet * const jet);
1081
int _tile_index(const double eta, const double phi) const;
1082
void _tj_set_jetinfo(TiledJet * const jet, const int _jets_index);
1083
void _print_tiles(TiledJet * briefjets ) const;
1084
void _add_neighbours_to_tile_union(const int tile_index,
1085
std::vector<int> & tile_union, int & n_near_tiles) const;
1086
void _add_untagged_neighbours_to_tile_union(const int tile_index,
1087
std::vector<int> & tile_union, int & n_near_tiles);
1088
void _add_untagged_neighbours_to_tile_union_using_max_info(const TiledJet * const jet,
1089
std::vector<int> & tile_union, int & n_near_tiles);
1090
double _distance_to_tile(const TiledJet * bj, const Tile25 *)
1096
void _update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
1097
void _set_NN(TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
1098
template <class J> double _bj_diJ(const J * const jet) const {
1099
double kt2 = jet->kt2;
1100
if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
1101
return jet->NN_dist * kt2;
1103
template <class J> inline void _bj_set_jetinfo(
1104
J * const jetA, const int _jets_index) const {
1105
jetA->eta = _jets[_jets_index].rap();
1106
jetA->phi = _jets[_jets_index].phi_02pi();
1107
jetA->kt2 = _cs.jet_scale_for_algorithm(_jets[_jets_index]);
1108
jetA->_jets_index = _jets_index;
1109
jetA->NN_dist = _R2;
1112
template <class J> inline double _bj_dist(
1113
const J * const jetA, const J * const jetB)
1116
_ncall++; // GPS tmp
1120
double dphi = std::abs(jetA->phi - jetB->phi);
1121
double deta = (jetA->eta - jetB->eta);
1122
if (dphi > pi) {dphi = twopi - dphi;}
1123
return dphi*dphi + deta*deta;
1125
template <class J> inline double _bj_dist_not_periodic(
1126
const J * const jetA, const J * const jetB)
1129
_ncall++; // GPS tmp
1133
double dphi = jetA->phi - jetB->phi;
1134
double deta = (jetA->eta - jetB->eta);
1135
return dphi*dphi + deta*deta;
1138
FJCORE_END_NAMESPACE
1139
#endif // __FJCORE_LAZYTILING25_HH__
1140
#ifndef __FJCORE_TILINGEXTENT_HH__
1141
#define __FJCORE_TILINGEXTENT_HH__
1142
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
1143
class TilingExtent {
1145
TilingExtent(ClusterSequence & cs);
1146
double minrap() const {return _minrap;}
1147
double maxrap() const {return _maxrap;}
1148
double sum_of_binned_squared_multiplicity() const {return _cumul2;}
1150
double _minrap, _maxrap, _cumul2;
1151
void _determine_rapidity_extent(const std::vector<PseudoJet> & particles);
1153
FJCORE_END_NAMESPACE // defined in fastjet/internal/base.hh
1154
#endif // __FJCORE_TILINGEXTENT_HH__
821
1155
#include<limits>
822
1156
#include<iostream>
823
1157
#include<iomanip>
824
1158
#include<algorithm>
825
1159
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
826
const unsigned int huge_unsigned = 4294967295U;
827
1160
const unsigned int twopow31 = 2147483648U;
828
1161
using namespace std;
829
1162
void ClosestPair2D::_point2shuffle(Point & point, Shuffle & shuffle,
4403
4947
FJCORE_END_NAMESPACE // defined in fastjet/internal/base.hh
4949
using namespace std;
4950
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
4951
LazyTiling25::LazyTiling25(ClusterSequence & cs) :
4952
_cs(cs), _jets(cs.jets())
4955
_ncall = 0; // gps tmp
4956
_ncall_dtt = 0; // gps tmp
4957
#endif // INSTRUMENT2
4958
_Rparam = cs.jet_def().R();
4959
_R2 = _Rparam * _Rparam;
4961
_initialise_tiles();
4963
void LazyTiling25::_initialise_tiles() {
4964
double default_size = max(0.1,_Rparam)/2;
4965
_tile_size_eta = default_size;
4966
_n_tiles_phi = max(5,int(floor(twopi/default_size)));
4967
_tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
4968
#define _FASTJET_TILING25_USE_TILING_ANALYSIS_
4969
#ifdef _FASTJET_TILING25_USE_TILING_ANALYSIS_
4970
TilingExtent tiling_analysis(_cs);
4971
_tiles_eta_min = tiling_analysis.minrap();
4972
_tiles_eta_max = tiling_analysis.maxrap();
4973
#else // not _FASTJET_TILING25_USE_TILING_ANALYSIS_
4974
_tiles_eta_min = 0.0;
4975
_tiles_eta_max = 0.0;
4976
const double maxrap = 7.0;
4977
for(unsigned int i = 0; i < _jets.size(); i++) {
4978
double eta = _jets[i].rap();
4979
if (abs(eta) < maxrap) {
4980
if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
4981
if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
4984
#endif // _FASTJET_TILING25_USE_TILING_ANALYSIS_
4985
#define FASTJET_LAZY25_MIN3TILESY
4986
#ifdef FASTJET_LAZY25_MIN3TILESY
4987
if (_tiles_eta_max - _tiles_eta_min < 3*_tile_size_eta) {
4988
_tile_size_eta = (_tiles_eta_max - _tiles_eta_min)/3;
4989
_tiles_ieta_min = 0;
4990
_tiles_ieta_max = 2;
4991
_tiles_eta_max -= _tile_size_eta;
4993
#endif //FASTJET_LAZY25_MIN3TILESY
4994
_tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
4995
_tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
4996
_tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
4997
_tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
4998
#ifdef FASTJET_LAZY25_MIN3TILESY
5001
_tile_half_size_eta = _tile_size_eta * 0.5;
5002
_tile_half_size_phi = _tile_size_phi * 0.5;
5003
vector<bool> use_periodic_delta_phi(_n_tiles_phi, false);
5004
if (_n_tiles_phi <= 5) {
5005
fill(use_periodic_delta_phi.begin(), use_periodic_delta_phi.end(), true);
5007
use_periodic_delta_phi[0] = true;
5008
use_periodic_delta_phi[1] = true;
5009
use_periodic_delta_phi[_n_tiles_phi-2] = true;
5010
use_periodic_delta_phi[_n_tiles_phi-1] = true;
5012
_tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
5013
for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
5014
for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
5015
Tile25 * tile = & _tiles[_tile_index(ieta,iphi)];
5016
tile->head = NULL; // first element of tiles points to itself
5017
tile->begin_tiles[0] = tile;
5018
Tile25 ** pptile = & (tile->begin_tiles[0]);
5020
tile->surrounding_tiles = pptile;
5021
if (ieta > _tiles_ieta_min) {
5022
// with the itile subroutine, we can safely run tiles from
5023
// idphi=-1 to idphi=+1, because it takes care of
5024
// negative and positive boundaries
5025
for (int idphi = -2; idphi <=+2; idphi++) {
5026
*pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
5030
if (ieta > _tiles_ieta_min + 1) {
5031
// with the itile subroutine, we can safely run tiles from
5032
// idphi=-1 to idphi=+1, because it takes care of
5033
// negative and positive boundaries
5034
for (int idphi = -2; idphi <= +2; idphi++) {
5035
*pptile = & _tiles[_tile_index(ieta-2,iphi+idphi)];
5039
*pptile = & _tiles[_tile_index(ieta,iphi-1)];
5041
*pptile = & _tiles[_tile_index(ieta,iphi-2)];
5043
tile->RH_tiles = pptile;
5044
*pptile = & _tiles[_tile_index(ieta,iphi+1)];
5046
*pptile = & _tiles[_tile_index(ieta,iphi+2)];
5048
if (ieta < _tiles_ieta_max) {
5049
for (int idphi = -2; idphi <= +2; idphi++) {
5050
*pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
5054
if (ieta < _tiles_ieta_max - 1) {
5055
for (int idphi = -2; idphi <= +2; idphi++) {
5056
*pptile = & _tiles[_tile_index(ieta+2,iphi+idphi)];
5060
tile->end_tiles = pptile;
5061
tile->tagged = false;
5062
tile->use_periodic_delta_phi = use_periodic_delta_phi[iphi];
5063
tile->max_NN_dist = 0;
5064
tile->eta_centre = (ieta-_tiles_ieta_min+0.5)*_tile_size_eta + _tiles_eta_min;
5065
tile->phi_centre = (iphi+0.5)*_tile_size_phi;
5069
int LazyTiling25::_tile_index(const double eta, const double phi) const {
5071
if (eta <= _tiles_eta_min) {ieta = 0;}
5072
else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
5074
ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
5075
if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
5076
ieta = _tiles_ieta_max-_tiles_ieta_min;}
5078
iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
5079
return (iphi + ieta * _n_tiles_phi);
5081
inline void LazyTiling25::_tj_set_jetinfo( TiledJet * const jet,
5082
const int _jets_index) {
5083
_bj_set_jetinfo<>(jet, _jets_index);
5084
jet->tile_index = _tile_index(jet->eta, jet->phi);
5085
Tile25 * tile = &_tiles[jet->tile_index];
5086
jet->previous = NULL;
5087
jet->next = tile->head;
5088
if (jet->next != NULL) {jet->next->previous = jet;}
5091
void LazyTiling25::_bj_remove_from_tiles(TiledJet * const jet) {
5092
Tile25 * tile = & _tiles[jet->tile_index];
5093
if (jet->previous == NULL) {
5094
tile->head = jet->next;
5096
jet->previous->next = jet->next;
5098
if (jet->next != NULL) {
5099
jet->next->previous = jet->previous;
5102
void LazyTiling25::_print_tiles(TiledJet * briefjets ) const {
5103
for (vector<Tile25>::const_iterator tile = _tiles.begin();
5104
tile < _tiles.end(); tile++) {
5105
cout << "Tile " << tile - _tiles.begin()
5106
<< " at " << setw(10) << tile->eta_centre << "," << setw(10) << tile->phi_centre
5109
for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
5110
list.push_back(jetI-briefjets);
5112
sort(list.begin(),list.end());
5113
for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
5117
void LazyTiling25::_add_neighbours_to_tile_union(const int tile_index,
5118
vector<int> & tile_union, int & n_near_tiles) const {
5119
for (Tile25 * const * near_tile = _tiles[tile_index].begin_tiles;
5120
near_tile != _tiles[tile_index].end_tiles; near_tile++){
5121
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5125
inline void LazyTiling25::_add_untagged_neighbours_to_tile_union(
5126
const int tile_index,
5127
vector<int> & tile_union, int & n_near_tiles) {
5128
for (Tile25 ** near_tile = _tiles[tile_index].begin_tiles;
5129
near_tile != _tiles[tile_index].end_tiles; near_tile++){
5130
if (! (*near_tile)->tagged) {
5131
(*near_tile)->tagged = true;
5132
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5137
inline void LazyTiling25::_add_untagged_neighbours_to_tile_union_using_max_info(
5138
const TiledJet * jet,
5139
vector<int> & tile_union, int & n_near_tiles) {
5140
Tile25 & tile = _tiles[jet->tile_index];
5141
for (Tile25 ** near_tile = tile.begin_tiles; near_tile != tile.end_tiles; near_tile++){
5142
if ((*near_tile)->tagged) continue;
5143
double dist = _distance_to_tile(jet, *near_tile) - tile_edge_security_margin;
5144
if (dist > (*near_tile)->max_NN_dist) continue;
5145
(*near_tile)->tagged = true;
5146
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5150
inline double LazyTiling25::_distance_to_tile(const TiledJet * bj, const Tile25 * tile)
5153
_ncall_dtt++; // GPS tmp
5156
#endif // INSTRUMENT2
5158
if (_tiles[bj->tile_index].eta_centre == tile->eta_centre) deta = 0;
5159
else deta = std::abs(bj->eta - tile->eta_centre) - _tile_half_size_eta;
5160
double dphi = std::abs(bj->phi - tile->phi_centre);
5161
if (dphi > pi) dphi = twopi-dphi;
5162
dphi -= _tile_half_size_phi;
5163
if (dphi < 0) dphi = 0;
5164
return dphi*dphi + deta*deta;
5166
inline void LazyTiling25::_update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, vector<TiledJet *> & jets_for_minheap) {
5167
double dist = _bj_dist(jetI,jetX);
5168
if (dist < jetI->NN_dist) {
5170
jetI->NN_dist = dist;
5172
if (!jetI->minheap_update_needed()) {
5173
jetI->label_minheap_update_needed();
5174
jets_for_minheap.push_back(jetI);
5178
if (dist < jetX->NN_dist) {
5180
jetX->NN_dist = dist;
5184
inline void LazyTiling25::_set_NN(TiledJet * jetI,
5185
vector<TiledJet *> & jets_for_minheap) {
5186
jetI->NN_dist = _R2;
5188
if (!jetI->minheap_update_needed()) {
5189
jetI->label_minheap_update_needed();
5190
jets_for_minheap.push_back(jetI);}
5191
Tile25 * tile_ptr = &_tiles[jetI->tile_index];
5192
for (Tile25 ** near_tile = tile_ptr->begin_tiles;
5193
near_tile != tile_ptr->end_tiles; near_tile++) {
5194
if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
5195
for (TiledJet * jetJ = (*near_tile)->head;
5196
jetJ != NULL; jetJ = jetJ->next) {
5197
double dist = _bj_dist(jetI,jetJ);
5198
if (dist < jetI->NN_dist && jetJ != jetI) {
5199
jetI->NN_dist = dist; jetI->NN = jetJ;
5204
void LazyTiling25::run() {
5205
int n = _jets.size();
5207
TiledJet * briefjets = new TiledJet[n];
5208
TiledJet * jetA = briefjets, * jetB;
5209
TiledJet oldB = briefjets[0];
5210
vector<int> tile_union(3*25);
5211
for (int i = 0; i< n; i++) {
5212
_tj_set_jetinfo(jetA, i);
5213
jetA++; // move on to next entry of briefjets
5215
TiledJet * head = briefjets; // a nicer way of naming start
5216
vector<Tile25>::iterator tile;
5217
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5218
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5219
for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
5220
double dist = _bj_dist_not_periodic(jetA,jetB);
5221
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5222
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
5225
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5226
if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
5229
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5230
if (tile->use_periodic_delta_phi) {
5231
for (Tile25 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
5232
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5233
double dist_to_tile = _distance_to_tile(jetA, *RTile);
5234
bool relevant_for_jetA = dist_to_tile <= jetA->NN_dist;
5235
bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
5236
if (relevant_for_jetA || relevant_for_RTile) {
5237
for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
5238
double dist = _bj_dist(jetA,jetB);
5239
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5240
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
5246
for (Tile25 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
5247
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5248
double dist_to_tile = _distance_to_tile(jetA, *RTile);
5249
bool relevant_for_jetA = dist_to_tile <= jetA->NN_dist;
5250
bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
5251
if (relevant_for_jetA || relevant_for_RTile) {
5252
for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
5253
double dist = _bj_dist_not_periodic(jetA,jetB);
5254
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5255
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
5262
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5263
tile->max_NN_dist = 0;
5264
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5265
if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
5269
cout << "intermediate ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
5270
#endif // INSTRUMENT2
5271
vector<double> diJs(n);
5272
for (int i = 0; i < n; i++) {
5273
diJs[i] = _bj_diJ(&briefjets[i]);
5274
briefjets[i].label_minheap_update_done();
5276
MinHeap minheap(diJs);
5277
vector<TiledJet *> jets_for_minheap;
5278
jets_for_minheap.reserve(n);
5279
int history_location = n-1;
5281
double diJ_min = minheap.minval() *_invR2;
5282
jetA = head + minheap.minloc();
5286
if (jetA < jetB) {std::swap(jetA,jetB);}
5287
int nn; // new jet index
5288
_cs.plugin_record_ij_recombination(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
5289
_bj_remove_from_tiles(jetA);
5290
oldB = * jetB; // take a copy because we will need it...
5291
_bj_remove_from_tiles(jetB);
5292
_tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
5294
_cs.plugin_record_iB_recombination(jetA->_jets_index, diJ_min);
5295
_bj_remove_from_tiles(jetA);
5297
minheap.remove(jetA-head);
5298
int n_near_tiles = 0;
5300
Tile25 & jetB_tile = _tiles[jetB->tile_index];
5301
for (Tile25 ** near_tile = jetB_tile.begin_tiles;
5302
near_tile != jetB_tile.end_tiles; near_tile++) {
5303
double dist_to_tile = _distance_to_tile(jetB, *near_tile);
5304
bool relevant_for_jetB = dist_to_tile <= jetB->NN_dist;
5305
bool relevant_for_near_tile = dist_to_tile <= (*near_tile)->max_NN_dist;
5306
bool relevant = relevant_for_jetB || relevant_for_near_tile;
5307
if (! relevant) continue;
5308
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5309
(*near_tile)->tagged = true;
5311
for (TiledJet * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
5312
if (jetI->NN == jetA || jetI->NN == jetB) _set_NN(jetI, jets_for_minheap);
5313
_update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
5317
int n_done_tiles = n_near_tiles;
5318
_add_untagged_neighbours_to_tile_union_using_max_info(jetA,
5319
tile_union, n_near_tiles);
5321
_add_untagged_neighbours_to_tile_union_using_max_info(&oldB,
5322
tile_union,n_near_tiles);
5323
jetB->label_minheap_update_needed();
5324
jets_for_minheap.push_back(jetB);
5326
for (int itile = 0; itile < n_done_tiles; itile++) {
5327
_tiles[tile_union[itile]].tagged = false;
5329
for (int itile = n_done_tiles; itile < n_near_tiles; itile++) {
5330
Tile25 * tile_ptr = &_tiles[tile_union[itile]];
5331
tile_ptr->tagged = false;
5332
for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
5333
if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
5334
_set_NN(jetI, jets_for_minheap);
5338
while (jets_for_minheap.size() > 0) {
5339
TiledJet * jetI = jets_for_minheap.back();
5340
jets_for_minheap.pop_back();
5341
minheap.update(jetI-head, _bj_diJ(jetI));
5342
jetI->label_minheap_update_done();
5343
Tile25 & tile_I = _tiles[jetI->tile_index];
5344
if (tile_I.max_NN_dist < jetI->NN_dist) tile_I.max_NN_dist = jetI->NN_dist;
5350
cout << "ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
5351
#endif // INSTRUMENT2
5353
FJCORE_END_NAMESPACE
5357
using namespace std;
5358
#define _FASTJET_TILING2_USE_TILING_ANALYSIS_
5359
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
5360
LazyTiling9::LazyTiling9(ClusterSequence & cs) :
5361
_cs(cs), _jets(cs.jets())
5364
_ncall = 0; // gps tmp
5365
_ncall_dtt = 0; // gps tmp
5366
#endif // INSTRUMENT2
5367
_Rparam = cs.jet_def().R();
5368
_R2 = _Rparam * _Rparam;
5370
_initialise_tiles();
5372
void LazyTiling9::_initialise_tiles() {
5373
double default_size = max(0.1,_Rparam);
5374
_tile_size_eta = default_size;
5375
_n_tiles_phi = max(3,int(floor(twopi/default_size)));
5376
_tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
5377
#ifdef _FASTJET_TILING2_USE_TILING_ANALYSIS_
5378
TilingExtent tiling_analysis(_cs);
5379
_tiles_eta_min = tiling_analysis.minrap();
5380
_tiles_eta_max = tiling_analysis.maxrap();
5382
_tiles_eta_min = 0.0;
5383
_tiles_eta_max = 0.0;
5384
const double maxrap = 7.0;
5385
for(unsigned int i = 0; i < _jets.size(); i++) {
5386
double eta = _jets[i].rap();
5387
if (abs(eta) < maxrap) {
5388
if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
5389
if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
5393
#define FASTJET_LAZY9_MIN2TILESY
5394
#ifdef FASTJET_LAZY9_MIN2TILESY
5395
if (_tiles_eta_max - _tiles_eta_min < 2*_tile_size_eta) {
5396
_tile_size_eta = (_tiles_eta_max - _tiles_eta_min)/2;
5397
_tiles_ieta_min = 0;
5398
_tiles_ieta_max = 1;
5399
_tiles_eta_max -= _tile_size_eta;
5401
#endif //FASTJET_LAZY9_MIN2TILESY
5402
_tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
5403
_tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
5404
_tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
5405
_tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
5406
#ifdef FASTJET_LAZY9_MIN2TILESY
5409
_tile_half_size_eta = _tile_size_eta * 0.5;
5410
_tile_half_size_phi = _tile_size_phi * 0.5;
5411
vector<bool> use_periodic_delta_phi(_n_tiles_phi, false);
5412
if (_n_tiles_phi <= 3) {
5413
fill(use_periodic_delta_phi.begin(), use_periodic_delta_phi.end(), true);
5415
use_periodic_delta_phi[0] = true;
5416
use_periodic_delta_phi[_n_tiles_phi-1] = true;
5418
_tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
5419
for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
5420
for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
5421
Tile2 * tile = & _tiles[_tile_index(ieta,iphi)];
5422
tile->head = NULL; // first element of tiles points to itself
5423
tile->begin_tiles[0] = tile;
5424
Tile2 ** pptile = & (tile->begin_tiles[0]);
5426
tile->surrounding_tiles = pptile;
5427
if (ieta > _tiles_ieta_min) {
5428
// with the itile subroutine, we can safely run tiles from
5429
// idphi=-1 to idphi=+1, because it takes care of
5430
// negative and positive boundaries
5431
for (int idphi = -1; idphi <=+1; idphi++) {
5432
*pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
5436
*pptile = & _tiles[_tile_index(ieta,iphi-1)];
5438
tile->RH_tiles = pptile;
5439
*pptile = & _tiles[_tile_index(ieta,iphi+1)];
5441
if (ieta < _tiles_ieta_max) {
5442
for (int idphi = -1; idphi <= +1; idphi++) {
5443
*pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
5447
tile->end_tiles = pptile;
5448
tile->tagged = false;
5449
tile->use_periodic_delta_phi = use_periodic_delta_phi[iphi];
5450
tile->max_NN_dist = 0;
5451
tile->eta_centre = (ieta-_tiles_ieta_min+0.5)*_tile_size_eta + _tiles_eta_min;
5452
tile->phi_centre = (iphi+0.5)*_tile_size_phi;
5456
int LazyTiling9::_tile_index(const double eta, const double phi) const {
5458
if (eta <= _tiles_eta_min) {ieta = 0;}
5459
else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
5461
ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
5462
if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
5463
ieta = _tiles_ieta_max-_tiles_ieta_min;}
5465
iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
5466
return (iphi + ieta * _n_tiles_phi);
5468
inline void LazyTiling9::_tj_set_jetinfo( TiledJet * const jet,
5469
const int _jets_index) {
5470
_bj_set_jetinfo<>(jet, _jets_index);
5471
jet->tile_index = _tile_index(jet->eta, jet->phi);
5472
Tile2 * tile = &_tiles[jet->tile_index];
5473
jet->previous = NULL;
5474
jet->next = tile->head;
5475
if (jet->next != NULL) {jet->next->previous = jet;}
5478
void LazyTiling9::_bj_remove_from_tiles(TiledJet * const jet) {
5479
Tile2 * tile = & _tiles[jet->tile_index];
5480
if (jet->previous == NULL) {
5481
tile->head = jet->next;
5483
jet->previous->next = jet->next;
5485
if (jet->next != NULL) {
5486
jet->next->previous = jet->previous;
5489
void LazyTiling9::_print_tiles(TiledJet * briefjets ) const {
5490
for (vector<Tile2>::const_iterator tile = _tiles.begin();
5491
tile < _tiles.end(); tile++) {
5492
cout << "Tile " << tile - _tiles.begin()<<" = ";
5494
for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
5495
list.push_back(jetI-briefjets);
5497
sort(list.begin(),list.end());
5498
for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
5502
void LazyTiling9::_add_neighbours_to_tile_union(const int tile_index,
5503
vector<int> & tile_union, int & n_near_tiles) const {
5504
for (Tile2 * const * near_tile = _tiles[tile_index].begin_tiles;
5505
near_tile != _tiles[tile_index].end_tiles; near_tile++){
5506
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5510
inline void LazyTiling9::_add_untagged_neighbours_to_tile_union(
5511
const int tile_index,
5512
vector<int> & tile_union, int & n_near_tiles) {
5513
for (Tile2 ** near_tile = _tiles[tile_index].begin_tiles;
5514
near_tile != _tiles[tile_index].end_tiles; near_tile++){
5515
if (! (*near_tile)->tagged) {
5516
(*near_tile)->tagged = true;
5517
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5522
inline void LazyTiling9::_add_untagged_neighbours_to_tile_union_using_max_info(
5523
const TiledJet * jet,
5524
vector<int> & tile_union, int & n_near_tiles) {
5525
Tile2 & tile = _tiles[jet->tile_index];
5526
for (Tile2 ** near_tile = tile.begin_tiles; near_tile != tile.end_tiles; near_tile++){
5527
if ((*near_tile)->tagged) continue;
5528
double dist = _distance_to_tile(jet, *near_tile) - tile_edge_security_margin;
5529
if (dist > (*near_tile)->max_NN_dist) continue;
5530
(*near_tile)->tagged = true;
5531
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5535
inline double LazyTiling9::_distance_to_tile(const TiledJet * bj, const Tile2 * tile)
5538
_ncall_dtt++; // GPS tmp
5541
#endif // INSTRUMENT2
5543
if (_tiles[bj->tile_index].eta_centre == tile->eta_centre) deta = 0;
5544
else deta = std::abs(bj->eta - tile->eta_centre) - _tile_half_size_eta;
5545
double dphi = std::abs(bj->phi - tile->phi_centre);
5546
if (dphi > pi) dphi = twopi-dphi;
5547
dphi -= _tile_half_size_phi;
5548
if (dphi < 0) dphi = 0;
5549
return dphi*dphi + deta*deta;
5551
inline void LazyTiling9::_update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, vector<TiledJet *> & jets_for_minheap) {
5552
double dist = _bj_dist(jetI,jetX);
5553
if (dist < jetI->NN_dist) {
5555
jetI->NN_dist = dist;
5557
if (!jetI->minheap_update_needed()) {
5558
jetI->label_minheap_update_needed();
5559
jets_for_minheap.push_back(jetI);
5563
if (dist < jetX->NN_dist) {
5565
jetX->NN_dist = dist;
5569
inline void LazyTiling9::_set_NN(TiledJet * jetI,
5570
vector<TiledJet *> & jets_for_minheap) {
5571
jetI->NN_dist = _R2;
5573
if (!jetI->minheap_update_needed()) {
5574
jetI->label_minheap_update_needed();
5575
jets_for_minheap.push_back(jetI);}
5576
Tile2 * tile_ptr = &_tiles[jetI->tile_index];
5577
for (Tile2 ** near_tile = tile_ptr->begin_tiles;
5578
near_tile != tile_ptr->end_tiles; near_tile++) {
5579
if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
5580
for (TiledJet * jetJ = (*near_tile)->head;
5581
jetJ != NULL; jetJ = jetJ->next) {
5582
double dist = _bj_dist(jetI,jetJ);
5583
if (dist < jetI->NN_dist && jetJ != jetI) {
5584
jetI->NN_dist = dist; jetI->NN = jetJ;
5589
void LazyTiling9::run() {
5590
int n = _jets.size();
5592
TiledJet * briefjets = new TiledJet[n];
5593
TiledJet * jetA = briefjets, * jetB;
5594
TiledJet oldB = briefjets[0];
5595
vector<int> tile_union(3*n_tile_neighbours);
5596
for (int i = 0; i< n; i++) {
5597
_tj_set_jetinfo(jetA, i);
5598
jetA++; // move on to next entry of briefjets
5600
TiledJet * head = briefjets; // a nicer way of naming start
5601
vector<Tile2>::iterator tile;
5602
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5603
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5604
for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
5605
double dist = _bj_dist_not_periodic(jetA,jetB);
5606
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5607
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
5610
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5611
if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
5614
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5615
if (tile->use_periodic_delta_phi) {
5616
for (Tile2 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
5617
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5618
double dist_to_tile = _distance_to_tile(jetA, *RTile);
5619
bool relevant_for_jetA = dist_to_tile <= jetA->NN_dist;
5620
bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
5621
if (relevant_for_jetA || relevant_for_RTile) {
5622
for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
5623
double dist = _bj_dist(jetA,jetB);
5624
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5625
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
5631
for (Tile2 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
5632
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5633
double dist_to_tile = _distance_to_tile(jetA, *RTile);
5634
bool relevant_for_jetA = dist_to_tile <= jetA->NN_dist;
5635
bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
5636
if (relevant_for_jetA || relevant_for_RTile) {
5637
for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
5638
double dist = _bj_dist_not_periodic(jetA,jetB);
5639
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5640
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
5647
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5648
tile->max_NN_dist = 0;
5649
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5650
if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
5654
cout << "intermediate ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
5655
#endif // INSTRUMENT2
5656
vector<double> diJs(n);
5657
for (int i = 0; i < n; i++) {
5658
diJs[i] = _bj_diJ(&briefjets[i]);
5659
briefjets[i].label_minheap_update_done();
5661
MinHeap minheap(diJs);
5662
vector<TiledJet *> jets_for_minheap;
5663
jets_for_minheap.reserve(n);
5664
int history_location = n-1;
5666
double diJ_min = minheap.minval() *_invR2;
5667
jetA = head + minheap.minloc();
5671
if (jetA < jetB) {std::swap(jetA,jetB);}
5672
int nn; // new jet index
5673
_cs.plugin_record_ij_recombination(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
5674
_bj_remove_from_tiles(jetA);
5675
oldB = * jetB; // take a copy because we will need it...
5676
_bj_remove_from_tiles(jetB);
5677
_tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
5679
_cs.plugin_record_iB_recombination(jetA->_jets_index, diJ_min);
5680
_bj_remove_from_tiles(jetA);
5682
minheap.remove(jetA-head);
5683
int n_near_tiles = 0;
5685
Tile2 & jetB_tile = _tiles[jetB->tile_index];
5686
for (Tile2 ** near_tile = jetB_tile.begin_tiles;
5687
near_tile != jetB_tile.end_tiles; near_tile++) {
5688
double dist_to_tile = _distance_to_tile(jetB, *near_tile);
5689
bool relevant_for_jetB = dist_to_tile <= jetB->NN_dist;
5690
bool relevant_for_near_tile = dist_to_tile <= (*near_tile)->max_NN_dist;
5691
bool relevant = relevant_for_jetB || relevant_for_near_tile;
5692
if (! relevant) continue;
5693
tile_union[n_near_tiles] = *near_tile - & _tiles[0];
5694
(*near_tile)->tagged = true;
5696
for (TiledJet * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
5697
if (jetI->NN == jetA || jetI->NN == jetB) _set_NN(jetI, jets_for_minheap);
5698
_update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
5702
int n_done_tiles = n_near_tiles;
5703
_add_untagged_neighbours_to_tile_union_using_max_info(jetA,
5704
tile_union, n_near_tiles);
5706
_add_untagged_neighbours_to_tile_union_using_max_info(&oldB,
5707
tile_union,n_near_tiles);
5708
jetB->label_minheap_update_needed();
5709
jets_for_minheap.push_back(jetB);
5711
for (int itile = 0; itile < n_done_tiles; itile++) {
5712
_tiles[tile_union[itile]].tagged = false;
5714
for (int itile = n_done_tiles; itile < n_near_tiles; itile++) {
5715
Tile2 * tile_ptr = &_tiles[tile_union[itile]];
5716
tile_ptr->tagged = false;
5717
for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
5718
if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
5719
_set_NN(jetI, jets_for_minheap);
5723
while (jets_for_minheap.size() > 0) {
5724
TiledJet * jetI = jets_for_minheap.back();
5725
jets_for_minheap.pop_back();
5726
minheap.update(jetI-head, _bj_diJ(jetI));
5727
jetI->label_minheap_update_done();
5728
Tile2 & tile_I = _tiles[jetI->tile_index];
5729
if (tile_I.max_NN_dist < jetI->NN_dist) tile_I.max_NN_dist = jetI->NN_dist;
5735
cout << "ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
5736
#endif // INSTRUMENT2
5738
FJCORE_END_NAMESPACE
5740
using namespace std;
5741
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
5742
LazyTiling9Alt::LazyTiling9Alt(ClusterSequence & cs) :
5743
_cs(cs), _jets(cs.jets())
5745
_Rparam = cs.jet_def().R();
5746
_R2 = _Rparam * _Rparam;
5748
_initialise_tiles();
5750
void LazyTiling9Alt::_initialise_tiles() {
5751
double default_size = max(0.1,_Rparam);
5752
_tile_size_eta = default_size;
5753
_n_tiles_phi = max(3,int(floor(twopi/default_size)));
5754
_tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
5755
_tiles_eta_min = 0.0;
5756
_tiles_eta_max = 0.0;
5757
const double maxrap = 7.0;
5758
for(unsigned int i = 0; i < _jets.size(); i++) {
5759
double eta = _jets[i].rap();
5760
if (abs(eta) < maxrap) {
5761
if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
5762
if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
5765
_tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
5766
_tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
5767
_tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
5768
_tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
5769
_tile_half_size_eta = _tile_size_eta * 0.5;
5770
_tile_half_size_phi = _tile_size_phi * 0.5;
5771
vector<bool> use_periodic_delta_phi(_n_tiles_phi, false);
5772
if (_n_tiles_phi <= 3) {
5773
fill(use_periodic_delta_phi.begin(), use_periodic_delta_phi.end(), true);
5775
use_periodic_delta_phi[0] = true;
5776
use_periodic_delta_phi[_n_tiles_phi-1] = true;
5778
_tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
5779
for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
5780
for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
5781
Tile * tile = & _tiles[_tile_index(ieta,iphi)];
5782
tile->head = NULL; // first element of tiles points to itself
5783
tile->begin_tiles[0] = Tile::TileFnPair(tile,&Tile::distance_to_centre);
5784
Tile::TileFnPair * pptile = & (tile->begin_tiles[0]);
5786
tile->surrounding_tiles = pptile;
5787
if (ieta > _tiles_ieta_min) {
5788
// with the itile subroutine, we can safely run tiles from
5789
// idphi=-1 to idphi=+1, because it takes care of
5790
// negative and positive boundaries
5791
//for (int idphi = -1; idphi <=+1; idphi++) {
5792
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta-1,iphi-1)],
5793
&Tile::distance_to_left_bottom);
5795
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta-1,iphi)],
5796
&Tile::distance_to_left);
5798
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta-1,iphi+1)],
5799
&Tile::distance_to_left_top);
5802
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta,iphi-1)],
5803
&Tile::distance_to_bottom);
5805
tile->RH_tiles = pptile;
5806
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta,iphi+1)],
5807
&Tile::distance_to_top);
5809
if (ieta < _tiles_ieta_max) {
5810
//for (int idphi = -1; idphi <= +1; idphi++) {
5811
// *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
5814
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta+1,iphi-1)],
5815
&Tile::distance_to_right_bottom);
5817
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta+1,iphi)],
5818
&Tile::distance_to_right);
5820
*pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta+1,iphi+1)],
5821
&Tile::distance_to_right_top);
5824
tile->end_tiles = pptile;
5825
tile->tagged = false;
5826
tile->use_periodic_delta_phi = use_periodic_delta_phi[iphi];
5827
tile->max_NN_dist = 0;
5828
tile->eta_min = ieta*_tile_size_eta;
5829
tile->eta_max = (ieta+1)*_tile_size_eta;
5830
tile->phi_min = iphi*_tile_size_phi;
5831
tile->phi_max = (iphi+1)*_tile_size_phi;
5835
int LazyTiling9Alt::_tile_index(const double eta, const double phi) const {
5837
if (eta <= _tiles_eta_min) {ieta = 0;}
5838
else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
5840
ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
5841
if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
5842
ieta = _tiles_ieta_max-_tiles_ieta_min;}
5844
iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
5845
return (iphi + ieta * _n_tiles_phi);
5847
inline void LazyTiling9Alt::_tj_set_jetinfo( TiledJet * const jet,
5848
const int _jets_index) {
5849
_bj_set_jetinfo<>(jet, _jets_index);
5850
jet->tile_index = _tile_index(jet->eta, jet->phi);
5851
Tile * tile = &_tiles[jet->tile_index];
5852
jet->previous = NULL;
5853
jet->next = tile->head;
5854
if (jet->next != NULL) {jet->next->previous = jet;}
5857
void LazyTiling9Alt::_bj_remove_from_tiles(TiledJet * const jet) {
5858
Tile * tile = & _tiles[jet->tile_index];
5859
if (jet->previous == NULL) {
5860
tile->head = jet->next;
5862
jet->previous->next = jet->next;
5864
if (jet->next != NULL) {
5865
jet->next->previous = jet->previous;
5868
void LazyTiling9Alt::_print_tiles(TiledJet * briefjets ) const {
5869
for (vector<Tile>::const_iterator tile = _tiles.begin();
5870
tile < _tiles.end(); tile++) {
5871
cout << "Tile " << tile - _tiles.begin()<<" = ";
5873
for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
5874
list.push_back(jetI-briefjets);
5876
sort(list.begin(),list.end());
5877
for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
5881
void LazyTiling9Alt::_add_neighbours_to_tile_union(const int tile_index,
5882
vector<int> & tile_union, int & n_near_tiles) const {
5883
for (Tile::TileFnPair const * near_tile = _tiles[tile_index].begin_tiles;
5884
near_tile != _tiles[tile_index].end_tiles; near_tile++){
5885
tile_union[n_near_tiles] = near_tile->first - & _tiles[0];
5889
inline void LazyTiling9Alt::_add_untagged_neighbours_to_tile_union(
5890
const int tile_index,
5891
vector<int> & tile_union, int & n_near_tiles) {
5892
for (Tile::TileFnPair * near_tile = _tiles[tile_index].begin_tiles;
5893
near_tile != _tiles[tile_index].end_tiles; near_tile++){
5894
if (! (near_tile->first)->tagged) {
5895
(near_tile->first)->tagged = true;
5896
tile_union[n_near_tiles] = near_tile->first - & _tiles[0];
5901
inline void LazyTiling9Alt::_add_untagged_neighbours_to_tile_union_using_max_info(
5902
const TiledJet * jet,
5903
vector<int> & tile_union, int & n_near_tiles) {
5904
Tile & tile = _tiles[jet->tile_index];
5905
for (Tile::TileFnPair * near_tile = tile.begin_tiles; near_tile != tile.end_tiles; near_tile++){
5906
if ((near_tile->first)->tagged) continue;
5907
double dist = (tile.*(near_tile->second))(jet) - tile_edge_security_margin;
5908
if (dist > (near_tile->first)->max_NN_dist) continue;
5909
(near_tile->first)->tagged = true;
5910
tile_union[n_near_tiles] = near_tile->first - & _tiles[0];
5914
ostream & operator<<(ostream & ostr, const TiledJet & jet) {
5915
ostr << "j" << setw(3) << jet._jets_index << ":pt2,rap,phi=" ; ostr.flush();
5916
ostr << jet.kt2 << ","; ostr.flush();
5917
ostr << jet.eta << ","; ostr.flush();
5918
ostr << jet.phi; ostr.flush();
5919
ostr << ", tile=" << jet.tile_index; ostr.flush();
5922
inline void LazyTiling9Alt::_update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, vector<TiledJet *> & jets_for_minheap) {
5923
double dist = _bj_dist(jetI,jetX);
5924
if (dist < jetI->NN_dist) {
5926
jetI->NN_dist = dist;
5928
if (!jetI->minheap_update_needed()) {
5929
jetI->label_minheap_update_needed();
5930
jets_for_minheap.push_back(jetI);
5934
if (dist < jetX->NN_dist) {
5936
jetX->NN_dist = dist;
5940
inline void LazyTiling9Alt::_set_NN(TiledJet * jetI,
5941
vector<TiledJet *> & jets_for_minheap) {
5942
jetI->NN_dist = _R2;
5944
if (!jetI->minheap_update_needed()) {
5945
jetI->label_minheap_update_needed();
5946
jets_for_minheap.push_back(jetI);}
5947
Tile * tile_ptr = &_tiles[jetI->tile_index];
5948
for (Tile::TileFnPair * near_tile = tile_ptr->begin_tiles;
5949
near_tile != tile_ptr->end_tiles; near_tile++) {
5950
if (jetI->NN_dist < (tile_ptr->*(near_tile->second))(jetI)) continue;
5951
for (TiledJet * jetJ = (near_tile->first)->head;
5952
jetJ != NULL; jetJ = jetJ->next) {
5953
double dist = _bj_dist(jetI,jetJ);
5954
if (dist < jetI->NN_dist && jetJ != jetI) {
5955
jetI->NN_dist = dist; jetI->NN = jetJ;
5960
void LazyTiling9Alt::run() {
5961
int n = _jets.size();
5962
TiledJet * briefjets = new TiledJet[n];
5963
TiledJet * jetA = briefjets, * jetB;
5965
vector<int> tile_union(3*n_tile_neighbours);
5966
for (int i = 0; i< n; i++) {
5967
_tj_set_jetinfo(jetA, i);
5968
jetA++; // move on to next entry of briefjets
5970
TiledJet * head = briefjets; // a nicer way of naming start
5971
vector<Tile>::iterator tile;
5972
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5973
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5974
for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
5975
double dist = _bj_dist_not_periodic(jetA,jetB);
5976
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5977
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
5980
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5981
if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
5984
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
5985
if (tile->use_periodic_delta_phi) {
5986
for (Tile::TileFnPair * RTileFnPair = tile->RH_tiles;
5987
RTileFnPair != tile->end_tiles; RTileFnPair++) {
5988
Tile *RTile = RTileFnPair->first;
5989
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
5990
double dist_to_tile = ((*tile).*(RTileFnPair->second))(jetA);
5991
bool relevant_for_jetA = dist_to_tile <= jetA->NN_dist;
5992
bool relevant_for_RTile = dist_to_tile <= RTile->max_NN_dist;
5993
if (relevant_for_jetA || relevant_for_RTile) {
5994
for (jetB = RTile->head; jetB != NULL; jetB = jetB->next) {
5995
double dist = _bj_dist(jetA,jetB);
5996
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
5997
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
6003
for (Tile::TileFnPair* RTileFnPair = tile->RH_tiles;
6004
RTileFnPair != tile->end_tiles; RTileFnPair++) {
6005
Tile *RTile = RTileFnPair->first;
6006
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
6007
double dist_to_tile = ((*tile).*(RTileFnPair->second))(jetA);
6008
bool relevant_for_jetA = dist_to_tile <= jetA->NN_dist;
6009
bool relevant_for_RTile = dist_to_tile <= RTile->max_NN_dist;
6010
if (relevant_for_jetA || relevant_for_RTile) {
6011
for (jetB = RTile->head; jetB != NULL; jetB = jetB->next) {
6012
double dist = _bj_dist_not_periodic(jetA,jetB);
6013
if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
6014
if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
6021
for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
6022
tile->max_NN_dist = 0;
6023
for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
6024
if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
6027
vector<double> diJs(n);
6028
for (int i = 0; i < n; i++) {
6029
diJs[i] = _bj_diJ(&briefjets[i]);
6030
briefjets[i].label_minheap_update_done();
6032
MinHeap minheap(diJs);
6033
vector<TiledJet *> jets_for_minheap;
6034
jets_for_minheap.reserve(n);
6035
int history_location = n-1;
6037
double diJ_min = minheap.minval() *_invR2;
6038
jetA = head + minheap.minloc();
6042
if (jetA < jetB) {std::swap(jetA,jetB);}
6043
int nn; // new jet index
6044
_cs.plugin_record_ij_recombination(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
6045
_bj_remove_from_tiles(jetA);
6046
oldB = * jetB; // take a copy because we will need it...
6047
_bj_remove_from_tiles(jetB);
6048
_tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
6050
_cs.plugin_record_iB_recombination(jetA->_jets_index, diJ_min);
6051
_bj_remove_from_tiles(jetA);
6053
minheap.remove(jetA-head);
6054
int n_near_tiles = 0;
6055
_add_untagged_neighbours_to_tile_union_using_max_info(jetA,
6056
tile_union, n_near_tiles);
6058
_add_untagged_neighbours_to_tile_union_using_max_info(&oldB,
6059
tile_union,n_near_tiles);
6060
jetB->label_minheap_update_needed();
6061
jets_for_minheap.push_back(jetB);
6064
Tile & jetB_tile = _tiles[jetB->tile_index];
6065
for (Tile::TileFnPair * near_tile_fn_pair = jetB_tile.begin_tiles;
6066
near_tile_fn_pair != jetB_tile.end_tiles; near_tile_fn_pair++) {
6067
Tile * near_tile = near_tile_fn_pair->first;
6068
double dist_to_tile = (jetB_tile.*(near_tile_fn_pair->second))(jetB);
6069
bool relevant_for_jetB = dist_to_tile <= jetB->NN_dist;
6070
bool relevant_for_near_tile = dist_to_tile <= near_tile->max_NN_dist;
6071
bool relevant = relevant_for_jetB || relevant_for_near_tile;
6073
if (near_tile->tagged) {
6074
for (TiledJet * jetI = near_tile->head; jetI != NULL; jetI = jetI->next) {
6075
if (jetI->NN == jetA || jetI->NN == jetB) _set_NN(jetI, jets_for_minheap);
6076
_update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
6078
near_tile->tagged = false;
6080
for (TiledJet * jetI = near_tile->head; jetI != NULL; jetI = jetI->next) {
6081
_update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
6085
// // -- Keep this old inline code for later speed tests
6088
for (int itile = 0; itile < n_near_tiles; itile++) {
6089
Tile * tile_ptr = &_tiles[tile_union[itile]];
6090
if (!tile_ptr->tagged) continue; // because earlier loop may have undone the tag
6091
tile_ptr->tagged = false;
6092
for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
6093
if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
6094
_set_NN(jetI, jets_for_minheap);
6098
while (jets_for_minheap.size() > 0) {
6099
TiledJet * jetI = jets_for_minheap.back();
6100
jets_for_minheap.pop_back();
6101
minheap.update(jetI-head, _bj_diJ(jetI));
6102
jetI->label_minheap_update_done();
6103
Tile & tile_I = _tiles[jetI->tile_index];
6104
if (tile_I.max_NN_dist < jetI->NN_dist) tile_I.max_NN_dist = jetI->NN_dist;
6110
FJCORE_END_NAMESPACE
6114
using namespace std;
6115
FJCORE_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
6116
TilingExtent::TilingExtent(ClusterSequence & cs) {
6117
_determine_rapidity_extent(cs.jets());
6119
void TilingExtent::_determine_rapidity_extent(const vector<PseudoJet> & particles) {
6122
vector<double> counts(nbins, 0);
6123
_minrap = numeric_limits<double>::max();
6124
_maxrap = -numeric_limits<double>::max();
6126
for (unsigned i = 0; i < particles.size(); i++) {
6127
if (particles[i].E() == abs(particles[i].pz())) continue;
6128
double rap = particles[i].rap();
6129
if (rap < _minrap) _minrap = rap;
6130
if (rap > _maxrap) _maxrap = rap;
6131
ibin = int(rap+nrap);
6132
if (ibin < 0) ibin = 0;
6133
if (ibin >= nbins) ibin = nbins - 1;
6136
double max_in_bin = 0;
6137
for (ibin = 0; ibin < nbins; ibin++) {
6138
if (max_in_bin < counts[ibin]) max_in_bin = counts[ibin];
6140
const double allowed_max_fraction = 0.25;
6141
const double min_multiplicity = 4;
6142
double allowed_max_cumul = floor(max(max_in_bin * allowed_max_fraction, min_multiplicity));
6143
if (allowed_max_cumul > max_in_bin) allowed_max_cumul = max_in_bin;
6144
double cumul_lo = 0;
6146
for (ibin = 0; ibin < nbins; ibin++) {
6147
cumul_lo += counts[ibin];
6148
if (cumul_lo >= allowed_max_cumul) {
6149
double y = ibin-nrap;
6150
if (y > _minrap) _minrap = y;
6154
assert(ibin != nbins); // internal consistency check that you found a bin
6155
_cumul2 += cumul_lo*cumul_lo;
6157
double cumul_hi = 0;
6158
for (ibin = nbins-1; ibin >= 0; ibin--) {
6159
cumul_hi += counts[ibin];
6160
if (cumul_hi >= allowed_max_cumul) {
6161
double y = ibin-nrap+1; // +1 here is the rapidity bin width
6162
if (y < _maxrap) _maxrap = y;
6166
assert(ibin >= 0); // internal consistency check that you found a bin
6168
assert(ibin_hi >= ibin_lo);
6169
if (ibin_hi == ibin_lo) {
6170
_cumul2 = pow(double(cumul_lo + cumul_hi - counts[ibin_hi]), 2);
6172
_cumul2 += cumul_hi*cumul_hi;
6173
for (ibin = ibin_lo+1; ibin < ibin_hi; ibin++) {
6174
_cumul2 += counts[ibin]*counts[ibin];
6178
FJCORE_END_NAMESPACE