|
SISCone
2.0.5
|
00001 00002 // File: hash.cpp // 00003 // Description: source file for classes hash_element and hash_cones // 00004 // This file is part of the SISCone project. // 00005 // For more details, see http://projects.hepforge.org/siscone // 00006 // // 00007 // Copyright (c) 2006 Gavin Salam and Gregory Soyez // 00008 // // 00009 // This program 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 // This program is distributed in the hope that it will be useful, // 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of // 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 00017 // GNU General Public License for more details. // 00018 // // 00019 // You should have received a copy of the GNU General Public License // 00020 // along with this program; if not, write to the Free Software // 00021 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // 00022 // // 00023 // $Revision:: 225 $// 00024 // $Date:: 2008-05-20 16:59:47 +0200 (Tue, 20 May 2008) $// 00026 00027 #include <math.h> 00028 #include <stdio.h> 00029 #include "hash.h" 00030 #include <iostream> 00031 00032 namespace siscone{ 00033 00034 using namespace std; 00035 00036 /************************************************************** 00037 * implementation of hash_cones * 00038 * list of cones candidates. * 00039 * We store in this class all the hash_elements and give * 00040 * functions to manipulate them. * 00041 **************************************************************/ 00042 00043 // constructor with initialisation 00044 // - _Np number of particles 00045 // - _R2 cone radius (squared) 00046 //----------------------------------- 00047 hash_cones::hash_cones(int _Np, double _R2){ 00048 int i; 00049 00050 n_cones = 0; 00051 #ifdef DEBUG_STABLE_CONES 00052 n_occupied_cells = 0; 00053 #endif 00054 00055 // determine hash size 00056 // for a ymax=5 and R=0.7, we observed an occupancy around 1/8 N^2 ~ N2 R2/4 00057 //mask = 1 << (int) (2*log(double(_Np))/log(2.0)); 00058 //if (mask<=1) mask=2; 00059 int nbits = (int) (log(_Np*_R2*_Np/4.0)/log(2.0)); 00060 if (nbits<1) nbits=1; 00061 mask = 1 << nbits; 00062 00063 // create hash 00064 hash_array = new hash_element*[mask]; 00065 mask--; 00066 00067 // set the array to 0 00068 //? needed ? 00069 for (i=0;i<mask+1;i++) 00070 hash_array[i] = NULL; 00071 00072 R2 = _R2; 00073 } 00074 00075 // destructor 00076 //------------ 00077 hash_cones::~hash_cones(){ 00078 int i; 00079 hash_element *elm; 00080 00081 for (i=0;i<mask+1;i++){ 00082 while (hash_array[i]!=NULL){ 00083 elm = hash_array[i]; 00084 hash_array[i] = hash_array[i]->next; 00085 delete elm; 00086 } 00087 } 00088 00089 delete[] hash_array; 00090 } 00091 00092 00093 /* 00094 * insert a new candidate into the hash. 00095 * - v 4-momentum of the cone to add 00096 * - parent parent particle defining the cone 00097 * - child child particle defining the cone 00098 * - p_io whether the parent has to belong to the cone or not 00099 * - c_io whether the child has to belong to the cone or not 00100 * return 0 on success, 1 on error 00101 ***********************************************************************/ 00102 int hash_cones::insert(Cmomentum *v, Cmomentum *parent, Cmomentum *child, bool p_io, bool c_io){ 00103 hash_element *elm; 00104 int index = (v->ref.ref[0]) & mask; 00105 00106 // check the array cell corresponding to our reference 00107 elm = hash_array[index]; 00108 00109 #ifdef DEBUG_STABLE_CONES 00110 if (elm==NULL) 00111 n_occupied_cells++; 00112 #endif 00113 00114 do{ 00115 // if it is not present, add it 00116 if (elm==NULL){ 00117 // create element 00118 elm = new hash_element; 00119 00120 // set its varibles 00121 // Note: at this level, eta and phi have already been computed 00122 // through Cmomentum::build_etaphi. 00123 elm->ref = v->ref; 00124 00125 //compute vectors centre 00126 v->build_etaphi(); 00127 elm->eta = v->eta; 00128 elm->phi = v->phi; 00129 // if at least one of the two is_inside tests gives a result != from the expected, 00130 // the || will be true hence !(...) false as wanted 00131 elm->is_stable = !((is_inside(v, parent)^p_io)||(is_inside(v, child)^c_io)); 00132 //cout << "-- new status of " << v->ref[0] << ":" << elm->is_stable << endl; 00133 00134 // update hash 00135 elm->next = hash_array[index]; 00136 hash_array[index] = elm; 00137 00138 n_cones++; 00139 return 0; 00140 } 00141 00142 // if the cone is already there, simply update stability status 00143 if (v->ref == elm->ref){ 00144 // there is only an update to perform to see if the cone is still stable 00145 if (elm->is_stable){ 00146 v->build_etaphi(); 00147 elm->is_stable = !((is_inside(v, parent)^p_io)||(is_inside(v, child)^c_io)); 00148 //cout << " parent/child: " 00149 // << parent->ref[0] << ":" << is_inside(v, parent) << ":" << p_io << " " 00150 // << child->ref[0] << ":" << is_inside(v, child) << ":" << c_io << endl; 00151 //cout << "-- rep status of " << v->ref[0] << ":" << elm->is_stable << endl; 00152 //cout << v->eta << " " << v->phi << endl; 00153 //cout << (child->eta) << " " << child->phi << endl; 00154 } 00155 return 0; 00156 } 00157 00158 elm = elm->next; 00159 } while (1); 00160 00161 return 1; 00162 } 00163 00164 /* 00165 * insert a new candidate into the hash. 00166 * - v 4-momentum of te cone to add 00167 * Note, in this case, we assume stability. We also assume 00168 * that eta and phi are computed for v 00169 * return 0 on success, 1 on error 00170 ***********************************************************************/ 00171 int hash_cones::insert(Cmomentum *v){ 00172 hash_element *elm; 00173 int index = (v->ref.ref[0]) & mask; 00174 //cout << "-- stable candidate: " << v->ref[0] << ":" << endl; 00175 00176 // check the array cell corresponding to our reference 00177 elm = hash_array[index]; 00178 do{ 00179 // if it is not present, add it 00180 if (elm==NULL){ 00181 // create element 00182 elm = new hash_element; 00183 00184 // set its varibles 00185 // Note: at this level, eta and phi have already been computed 00186 // through Cmomentum::build_etaphi. 00187 elm->ref = v->ref; 00188 elm->eta = v->eta; 00189 elm->phi = v->phi; 00190 elm->is_stable = true; 00191 00192 // update hash 00193 elm->next = hash_array[index]; 00194 hash_array[index] = elm; 00195 00196 n_cones++; 00197 return 0; 00198 } 00199 00200 // if the cone is already there, we have nothing to do 00201 if (v->ref == elm->ref){ 00202 return 0; 00203 } 00204 00205 elm = elm->next; 00206 } while (1); 00207 00208 return 1; 00209 } 00210 00211 /* 00212 * test if a particle is inside a cone of given centre. 00213 * check if the particle of coordinates 'v' is inside the circle of radius R 00214 * centered at 'centre'. 00215 * - centre centre of the circle 00216 * - v particle to test 00217 * return true if inside, false if outside 00218 ******************************************************************************/ 00219 inline bool hash_cones::is_inside(Cmomentum *centre, Cmomentum *v){ 00220 double dx, dy; 00221 00222 dx = centre->eta - v->eta; 00223 dy = fabs(centre->phi - v->phi); 00224 if (dy>M_PI) 00225 dy -= 2.0*M_PI; 00226 00227 return dx*dx+dy*dy<R2; 00228 } 00229 00230 }