SISCone  2.0.5
siscone/hash.cpp
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 }
The SISCone project has been developed by Gavin Salam and Gregory Soyez
Documentation generated on Mon Jun 4 2012 18:23:38 for SISCone by  Doxygen 1.7.6.1