![]() |
|
|||
File indexing completed on 2025-09-13 08:56:20
0001 //FJSTARTHEADER 0002 // $Id$ 0003 // 0004 // Copyright (c) 2005-2025, Matteo Cacciari, Gavin P. Salam and Gregory Soyez 0005 // 0006 //---------------------------------------------------------------------- 0007 // This file is part of FastJet. 0008 // 0009 // FastJet is free software; you can redistribute it and/or modify 0010 // it under the terms of the GNU General Public License as published by 0011 // the Free Software Foundation; either version 2 of the License, or 0012 // (at your option) any later version. 0013 // 0014 // The algorithms that underlie FastJet have required considerable 0015 // development. They are described in the original FastJet paper, 0016 // hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use 0017 // FastJet as part of work towards a scientific publication, please 0018 // quote the version you use and include a citation to the manual and 0019 // optionally also to hep-ph/0512210. 0020 // 0021 // FastJet is distributed in the hope that it will be useful, 0022 // but WITHOUT ANY WARRANTY; without even the implied warranty of 0023 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0024 // GNU General Public License for more details. 0025 // 0026 // You should have received a copy of the GNU General Public License 0027 // along with FastJet. If not, see <http://www.gnu.org/licenses/>. 0028 //---------------------------------------------------------------------- 0029 //FJENDHEADER 0030 0031 #include "fastjet/config.h" 0032 0033 #ifndef DROP_CGAL // in case we do not have the code for CGAL 0034 #ifndef __FASTJET_DNN3PICYLINDER_HH__ 0035 #define __FASTJET_DNN3PICYLINDER_HH__ 0036 0037 #include "fastjet/internal/DynamicNearestNeighbours.hh" 0038 #include "fastjet/internal/DnnPlane.hh" 0039 #include "fastjet/internal/numconsts.hh" 0040 0041 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 0042 0043 /// \if internal_doc 0044 /// @ingroup internal 0045 /// \class Dnn3piCylinder 0046 /// class derived from DynamicNearestNeighbours that provides an 0047 /// implementation for the surface of cylinder (using one 0048 /// DnnPlane object spanning 0--3pi). 0049 /// \endif 0050 class Dnn3piCylinder : public DynamicNearestNeighbours { 0051 public: 0052 /// empty initaliser 0053 Dnn3piCylinder() {} 0054 0055 /// Initialiser from a set of points on an Eta-Phi plane, where 0056 /// eta can have an arbitrary ranges and phi must be in range 0057 /// 0 <= phi < 2pi; 0058 /// 0059 /// NB: this class is more efficient than the plain Dnn4piCylinder 0060 /// class, but can give wrong answers when the nearest neighbour is 0061 /// further away than 2pi (in this case a point's nearest neighbour 0062 /// becomes itself, because it is considered to be a distance 2pi 0063 /// away). For the kt-algorithm (e.g.) this is actually not a 0064 /// problem (the distance need only be accurate when it is less than 0065 /// R), so we can tell the routine to ignore this problem -- 0066 /// alternatively the routine will crash if it detects it occurring 0067 /// (only when finding the nearest neighbour index, not its 0068 /// distance). 0069 Dnn3piCylinder(const std::vector<EtaPhi> &, 0070 const bool & ignore_nearest_is_mirror = false, 0071 const bool & verbose = false ); 0072 0073 /// Returns the index of the nearest neighbour of point labelled 0074 /// by ii (assumes ii is valid) 0075 int NearestNeighbourIndex(const int ii) const ; 0076 0077 /// Returns the distance to the nearest neighbour of point labelled 0078 /// by index ii (assumes ii is valid) 0079 double NearestNeighbourDistance(const int ii) const ; 0080 0081 /// Returns true iff the given index corresponds to a point that 0082 /// exists in the DNN structure (meaning that it has been added, and 0083 /// not removed in the meantime) 0084 bool Valid(const int index) const; 0085 0086 void RemoveAndAddPoints(const std::vector<int> & indices_to_remove, 0087 const std::vector<EtaPhi> & points_to_add, 0088 std::vector<int> & indices_added, 0089 std::vector<int> & indices_of_updated_neighbours); 0090 0091 ~Dnn3piCylinder(); 0092 0093 private: 0094 0095 // our extras to help us navigate, find distance, etc. 0096 const static int INEXISTENT_VERTEX=-3; 0097 0098 bool _verbose; 0099 0100 bool _ignore_nearest_is_mirror; 0101 0102 /// Picture of how things will work... Copy 0--pi part of the 0--2pi 0103 /// cylinder into a region 2pi--3pi of a Euclidean plane. Below we 0104 /// show points labelled by + that have a mirror image in this 0105 /// manner, while points labelled by * do not have a mirror image. 0106 /// 0107 /// | . | 0108 /// | . | 0109 /// | . | 0110 /// | . | 0111 /// | 2 . | 0112 /// | * . | 0113 /// | + . + | 0114 /// | 0 . 1 | 0115 /// | . | 0116 /// 0 2pi 3pi 0117 /// 0118 /// Each "true" point has its true "cylinder" index (the index that 0119 /// is known externally to this class) as well as euclidean plane 0120 /// indices (main_index and mirror index in the MirrorVertexInfo 0121 /// structure), which are private concepts of this class. 0122 /// 0123 /// In above picture our structures would hold the following info 0124 /// (the picture shows the euclidean-plane numbering) 0125 /// 0126 /// _mirror_info[cylinder_index = 0] = (0, 1) 0127 /// _mirror_info[cylinder_index = 1] = (2, INEXISTENT_VERTEX) 0128 /// 0129 /// We also need to be able to go from the euclidean plane indices 0130 /// back to the "true" cylinder index, and for this purpose we use 0131 /// the vector _cylinder_index_of_plane_vertex[...], which in the above example has 0132 /// the following contents 0133 /// 0134 /// _cylinder_index_of_plane_vertex[0] = 0 0135 /// _cylinder_index_of_plane_vertex[1] = 0 0136 /// _cylinder_index_of_plane_vertex[2] = 1 0137 /// 0138 0139 /// 0140 struct MirrorVertexInfo { 0141 /// index of the given point (appearing in the range 0--2pi) in the 0142 /// 0--3pi euclidean plane structure (position will coincide with 0143 /// that on the 0--2pi cylinder, but index labelling it will be 0144 /// different) 0145 int main_index; 0146 /// index of the mirror point (appearing in the range 2pi--3pi) in the 0147 /// 0--3pi euclidean plane structure 0148 int mirror_index; 0149 }; 0150 0151 // for each "true" vertex we have reference to indices in the euclidean 0152 // plane structure 0153 std::vector<MirrorVertexInfo> _mirror_info; 0154 // for each index in the euclidean 0--3pi plane structure we want to 0155 // be able to get back to the "true" vertex index on the overall 0156 // 0--2pi cylinder structure 0157 std::vector<int> _cylinder_index_of_plane_vertex; 0158 0159 // NB: we define POINTERS here because the initialisation gave 0160 // us problems (things crashed!), perhaps because in practice 0161 // we were making a copy without being careful and defining 0162 // a proper copy constructor. 0163 DnnPlane * _DNN; 0164 0165 /// given a phi value in the 0--2pi range return one 0166 /// in the pi--3pi range. 0167 inline EtaPhi _remap_phi(const EtaPhi & point) { 0168 double phi = point.second; 0169 if (phi < pi) { phi += twopi ;} 0170 return EtaPhi(point.first, phi);} 0171 0172 0173 //---------------------------------------------------------------------- 0174 /// What on earth does this do? 0175 /// 0176 /// Example: last true "cylinder" index was 15 0177 /// last plane index was 23 0178 /// 0179 /// Then: _cylinder_index_of_plane_vertex.size() = 24 and 0180 /// _mirror_info.size() = 16 0181 /// 0182 /// IF cylinder_point's phi < pi then 0183 /// create: _mirror_info[16] = (main_index = 24, mirror_index=25) 0184 /// _cylinder_index_of_plane_vertex[24] = 16 0185 /// _cylinder_index_of_plane_vertex[25] = 16 0186 /// ELSE 0187 /// create: _mirror_info[16] = (main_index = 24, mirror_index=INEXISTENT..) 0188 /// _cylinder_index_of_plane_vertex[24] = 16 0189 /// 0190 /// ADDITIONALLY push the cylinder_point (and if it exists the mirror 0191 /// copy) onto the vector plane_points. 0192 void _RegisterCylinderPoint (const EtaPhi & cylinder_point, 0193 std::vector<EtaPhi> & plane_points); 0194 }; 0195 0196 0197 // here follow some inline implementations of the simpler of the 0198 // functions defined above 0199 0200 //---------------------------------------------------------------------- 0201 /// Note: one of the difficulties of the 0--3pi mapping is that 0202 /// a point may have its mirror copy as its own nearest neighbour 0203 /// (if no other point is within a distance of 2pi). This does 0204 /// not matter for the kt_algorithm with 0205 /// reasonable values of radius, but might matter for a general use 0206 /// of this algorithm -- depending on whether or not the user has 0207 /// initialised the class with instructions to ignore this problem the 0208 /// program will detect and ignore it, or crash. 0209 inline int Dnn3piCylinder::NearestNeighbourIndex(const int current) const { 0210 int main_index = _mirror_info[current].main_index; 0211 int mirror_index = _mirror_info[current].mirror_index; 0212 int plane_index; 0213 if (mirror_index == INEXISTENT_VERTEX ) { 0214 plane_index = _DNN->NearestNeighbourIndex(main_index); 0215 } else { 0216 plane_index = ( 0217 _DNN->NearestNeighbourDistance(main_index) < 0218 _DNN->NearestNeighbourDistance(mirror_index)) ? 0219 _DNN->NearestNeighbourIndex(main_index) : 0220 _DNN->NearestNeighbourIndex(mirror_index) ; 0221 } 0222 int this_cylinder_index = _cylinder_index_of_plane_vertex[plane_index]; 0223 // either the user has acknowledged the fact that they may get the 0224 // mirror copy as the closest point, or crash if it should occur 0225 // that mirror copy is the closest point. 0226 assert(_ignore_nearest_is_mirror || this_cylinder_index != current); 0227 //if (this_cylinder_index == current) { 0228 // std::cerr << "WARNING point "<<current<< 0229 // " has its mirror copy as its own nearest neighbour"<<endl; 0230 //} 0231 return this_cylinder_index; 0232 } 0233 0234 inline double Dnn3piCylinder::NearestNeighbourDistance(const int current) const { 0235 int main_index = _mirror_info[current].main_index; 0236 int mirror_index = _mirror_info[current].mirror_index; 0237 if (mirror_index == INEXISTENT_VERTEX ) { 0238 return _DNN->NearestNeighbourDistance(main_index); 0239 } else { 0240 return ( 0241 _DNN->NearestNeighbourDistance(main_index) < 0242 _DNN->NearestNeighbourDistance(mirror_index)) ? 0243 _DNN->NearestNeighbourDistance(main_index) : 0244 _DNN->NearestNeighbourDistance(mirror_index) ; 0245 } 0246 0247 } 0248 0249 inline bool Dnn3piCylinder::Valid(const int index) const { 0250 return (_DNN->Valid(_mirror_info[index].main_index)); 0251 } 0252 0253 0254 inline Dnn3piCylinder::~Dnn3piCylinder() { 0255 delete _DNN; 0256 } 0257 0258 0259 FASTJET_END_NAMESPACE 0260 0261 #endif // __FASTJET_DNN3PICYLINDER_HH__ 0262 #endif // DROP_CGAL
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |