fastjet 2.4.5
|
00001 //STARTHEADER 00002 // $Id: Dnn2piCylinder.cc 431 2007-01-20 10:44:55Z salam $ 00003 // 00004 // Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam 00005 // 00006 //---------------------------------------------------------------------- 00007 // This file is part of FastJet. 00008 // 00009 // FastJet is free software; you can redistribute it and/or modify 00010 // it under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation; either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // The algorithms that underlie FastJet have required considerable 00015 // development and are described in hep-ph/0512210. If you use 00016 // FastJet as part of work towards a scientific publication, please 00017 // include a citation to the FastJet paper. 00018 // 00019 // FastJet is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 // GNU General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with FastJet; if not, write to the Free Software 00026 // Foundation, Inc.: 00027 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00028 //---------------------------------------------------------------------- 00029 //ENDHEADER 00030 00031 00032 #ifndef DROP_CGAL // in case we do not have the code for CGAL 00033 #include <set> 00034 #include "fastjet/internal/Dnn2piCylinder.hh" 00035 using namespace std; 00036 00037 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00038 00039 //---------------------------------------------------------------------- 00041 Dnn2piCylinder::Dnn2piCylinder( 00042 const vector<EtaPhi> & input_points, 00043 const bool & ignore_nearest_is_mirror, 00044 const bool & verbose) { 00045 00046 _verbose = verbose; 00047 _ignore_nearest_is_mirror = ignore_nearest_is_mirror; 00048 vector<EtaPhi> plane_points; 00049 vector<int> plane_point_indices(input_points.size()); 00050 //plane_points.reserve(2*input_points.size()); 00051 00052 for (unsigned int i=0; i < input_points.size(); i++) { 00053 _RegisterCylinderPoint(input_points[i], plane_points); 00054 plane_point_indices[i] = i; 00055 } 00056 00057 if (_verbose) cout << "============== Preparing _DNN" << endl; 00058 _DNN = new DnnPlane(plane_points, verbose); 00059 00060 00061 vector<int> updated_point_indices; // we'll not use information from this 00062 _CreateNecessaryMirrorPoints(plane_point_indices,updated_point_indices); 00063 } 00064 00065 00066 //---------------------------------------------------------------------- 00073 void Dnn2piCylinder::_RegisterCylinderPoint (const EtaPhi & cylinder_point, 00074 vector<EtaPhi> & plane_points) { 00075 double phi = cylinder_point.second; 00076 assert(phi >= 0.0 && phi < 2*pi); 00077 00078 // do main point 00079 MirrorVertexInfo mvi; 00080 mvi.main_index = _cylinder_index_of_plane_vertex.size(); 00081 _cylinder_index_of_plane_vertex.push_back(_mirror_info.size()); 00082 plane_points.push_back(cylinder_point); 00083 mvi.mirror_index = INEXISTENT_VERTEX; 00084 00085 // 00086 _mirror_info.push_back(mvi); 00087 } 00088 00089 00090 00091 //---------------------------------------------------------------------- 00107 void Dnn2piCylinder::_CreateNecessaryMirrorPoints( 00108 const vector<int> & plane_indices, 00109 vector<int> & updated_plane_points) { 00110 00111 vector<EtaPhi> new_plane_points; 00112 00113 for (size_t i = 0; i < plane_indices.size(); i++) { 00114 00115 int ip = plane_indices[i]; // plane index 00116 EtaPhi position = _DNN->etaphi(ip); 00117 double phi = position.second; 00118 00119 //BAD // require phi < pi 00120 //BAD if (phi >= pi) {continue;} 00121 00122 // require absence of mirror 00123 int ic = _cylinder_index_of_plane_vertex[ip]; 00124 if (_mirror_info[ic].mirror_index != INEXISTENT_VERTEX) {continue;} 00125 00126 //printf("%3d %3d %10.5f %10.5f %3d\n",ic, ip, phi, 00127 // _DNN->NearestNeighbourDistance(ip),_DNN->NearestNeighbourIndex(ip)); 00128 00129 00130 // check that we are sufficiently close to the border -- 00131 // i.e. closer than nearest neighbour distance. But RECALL: 00132 // nearest neighbourDistance actually returns a squared distance 00133 // (this was really stupid on our part -- caused considerable loss 00134 // of time ... ) 00135 double nndist = _DNN->NearestNeighbourDistance(ip); 00136 if (phi*phi >= nndist && (twopi-phi)*(twopi-phi) >= nndist) {continue;} 00137 00138 // now proceed to prepare the point for addition 00139 new_plane_points.push_back(_remap_phi(position)); 00140 _mirror_info[ic].mirror_index = _cylinder_index_of_plane_vertex.size(); 00141 _cylinder_index_of_plane_vertex.push_back(ic); 00142 } 00143 00144 vector<int> indices_to_remove; // empty 00145 vector<int> indices_added; // will be filled as result of call 00146 _DNN->RemoveAndAddPoints(indices_to_remove,new_plane_points,indices_added, 00147 updated_plane_points); 00148 00149 // occasionally, addition of points might cause a change in the 00150 // nearest neighbour of a point in the 0--pi range? (But should be 00151 // impossible -- we add points beyond 2pi, so they can only be 00152 // nearest neighbours of points in the range pi--2pi; there is one 00153 // exception -- the nearest neighbour of one's self -- but in that 00154 // case this will already have been discovered, so there should be 00155 // nothing left to do). 00156 00157 // To be on the safe side, check to see if we have updated points 00158 // with phi<pi and no current mirror point. BUT: this check, as 00159 // written, only makes sense when the mirror image was created only 00160 // beyond 2pi, which is no longer the case. Only apparent 00161 // alternative is to run separate insertions for beyond 2pi and 00162 // below phi=0, with separate checks in the two cases. But, given 00163 // that across a large number of recombinations and events in the 00164 // old method (single mirror), we never ran into this problem, it's 00165 // probably safe to assume that the arguments given above are OK! So 00166 // comment out the check... 00167 //NOTNEEDED for (size_t i = 0; i < updated_plane_points.size(); i++) { 00168 //NOTNEEDED int ip = updated_plane_points[i]; 00169 //NOTNEEDED double phi = _DNN->phi(ip); 00170 //NOTNEEDED int ic = _cylinder_index_of_plane_vertex[ip]; 00171 //NOTNEEDED assert (!(phi < pi && _mirror_info[ic].mirror_index == INEXISTENT_VERTEX)); 00172 //NOTNEEDED } 00173 // alternative recursive code 00174 //vector<int> extra_updated_plane_points; 00175 //_CreateNecessaryMirrorPoints(updated_plane_points,extra_updated_plane_points) 00176 //updated_plane_points.push_back(extra_updated_plane_points); 00177 } 00178 00179 00180 00181 //---------------------------------------------------------------------- 00183 void Dnn2piCylinder::RemoveAndAddPoints(const vector<int> & indices_to_remove, 00184 const vector<EtaPhi> & points_to_add, 00185 vector<int> & indices_added, 00186 vector<int> & indices_of_updated_neighbours) { 00187 00188 // translate from "cylinder" indices of points to remove to the 00189 // plane indices of points to remove, bearing in mind that sometimes 00190 // there are multple plane points to remove. 00191 vector<int> plane_indices_to_remove; 00192 for (unsigned int i=0; i < indices_to_remove.size(); i++) { 00193 MirrorVertexInfo * mvi; 00194 mvi = & _mirror_info[indices_to_remove[i]]; 00195 plane_indices_to_remove.push_back(mvi->main_index); 00196 if (mvi->mirror_index != INEXISTENT_VERTEX) { 00197 plane_indices_to_remove.push_back(mvi->mirror_index); 00198 } 00199 } 00200 00201 // given "cylinder" points to add get hold of the list of 00202 // plane-points to add. 00203 vector<EtaPhi> plane_points_to_add; 00204 indices_added.clear(); 00205 for (unsigned int i=0; i < points_to_add.size(); i++) { 00206 indices_added.push_back(_mirror_info.size()); 00207 _RegisterCylinderPoint(points_to_add[i], plane_points_to_add); 00208 } 00209 00210 // now get the hard work done (note that we need to supply the 00211 // plane_indices_added vector but that we will not actually check 00212 // its contents in any way -- the indices_added that is actually 00213 // returned has been calculated above). 00214 vector<int> updated_plane_neighbours, plane_indices_added; 00215 _DNN->RemoveAndAddPoints(plane_indices_to_remove, plane_points_to_add, 00216 plane_indices_added, updated_plane_neighbours); 00217 00218 vector<int> extra_updated_plane_neighbours; 00219 _CreateNecessaryMirrorPoints(updated_plane_neighbours, 00220 extra_updated_plane_neighbours); 00221 00222 // extract, from the updated_plane_neighbours, and 00223 // extra_updated_plane_neighbours, the set of cylinder neighbours 00224 // that have changed 00225 set<int> index_set; 00226 unsigned int i; 00227 for (i=0; i < updated_plane_neighbours.size(); i++) { 00228 index_set.insert( 00229 _cylinder_index_of_plane_vertex[updated_plane_neighbours[i]]);} 00230 for (i=0; i < extra_updated_plane_neighbours.size(); i++) { 00231 index_set.insert( 00232 _cylinder_index_of_plane_vertex[extra_updated_plane_neighbours[i]]);} 00233 00234 // decant the set into the vector that needs to be returned 00235 indices_of_updated_neighbours.clear(); 00236 for (set<int>::iterator iter = index_set.begin(); 00237 iter != index_set.end(); iter++) { 00238 indices_of_updated_neighbours.push_back(*iter); 00239 } 00240 } 00241 00242 FASTJET_END_NAMESPACE 00243 00244 #endif // DROP_CGAL