Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

PseudoJet.cc

Go to the documentation of this file.
00001 //STARTHEADER
00002 // $Id: PseudoJet.cc 329 2006-10-09 12:29:46Z 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 #include "fastjet/Error.hh"
00033 #include "fastjet/PseudoJet.hh"
00034 #include<valarray>
00035 #include<iostream>
00036 #include<sstream>
00037 #include<cmath>
00038 
00039 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
00040 
00041 using namespace std;
00042 
00043 
00044 //----------------------------------------------------------------------
00045 // another constructor...
00046 PseudoJet::PseudoJet(const double px, const double py, const double pz, const double E) {
00047   
00048   _E  = E ;
00049   _px = px;
00050   _py = py;
00051   _pz = pz;
00052 
00053   this->_finish_init();
00054 };
00055 
00056 
00057 //----------------------------------------------------------------------
00059 void PseudoJet::_finish_init () {
00060   _kt2 = this->px()*this->px() + this->py()*this->py();
00061   if (_kt2 == 0.0) {
00062     _phi = 0.0; } 
00063   else {
00064     _phi = atan2(this->py(),this->px());
00065   }
00066   if (_phi < 0.0) {_phi += twopi;}
00067   if (_phi >= twopi) {_phi -= twopi;} // can happen if phi=-|eps<1e-15|?
00068   if (this->E() == abs(this->pz()) && _kt2 == 0) {
00069     // Point has infinite rapidity -- convert that into a very large
00070     // number, but in such a way that different 0-pt momenta will have
00071     // different rapidities (so as to lift the degeneracy between
00072     // them) [this can be relevant at parton-level]
00073     double MaxRapHere = MaxRap + abs(this->pz());
00074     if (this->pz() >= 0.0) {_rap = MaxRapHere;} else {_rap = -MaxRapHere;}
00075   } else {
00076     // get the rapidity in a way that's modestly insensitive to roundoff
00077     // error when things pz,E are large (actually the best we can do without
00078     // explicit knowledge of mass)
00079     double effective_m2 = max(0.0,m2()); // force non tachyonic mass
00080     double E_plus_pz    = _E + abs(_pz); // the safer of p+, p-
00081     // p+/p- = (p+ p-) / (p-)^2 = (kt^2+m^2)/(p-)^2
00082     _rap = 0.5*log((_kt2 + effective_m2)/(E_plus_pz*E_plus_pz));
00083     if (_pz > 0) {_rap = - _rap;}
00084   }
00086   //if (this->E() != abs(this->pz())) {
00087   //  _rap = 0.5*log((this->E() + this->pz())/(this->E() - this->pz()));
00088   //    } else {
00089   //  // Overlapping points can give problems. Let's lift the degeneracy
00090   //  // in case of multiple 0-pT points (can be found at parton-level)
00091   //  double MaxRapHere = MaxRap + abs(this->pz());
00092   //  if (this->pz() >= 0.0) {_rap = MaxRapHere;} else {_rap = -MaxRapHere;}
00093   //}
00094 }
00095 
00096 
00097 //----------------------------------------------------------------------
00098 // return a valarray four-momentum
00099 valarray<double> PseudoJet::four_mom() const {
00100   valarray<double> mom(4);
00101   mom[0] = _px;
00102   mom[1] = _py;
00103   mom[2] = _pz;
00104   mom[3] = _E ;
00105   return mom;
00106 }
00107 
00108 //----------------------------------------------------------------------
00109 // Return the component corresponding to the specified index.
00110 // taken from CLHEP
00111 double PseudoJet::operator () (int i) const {
00112   switch(i) {
00113   case X:
00114     return px();
00115   case Y:
00116     return py();
00117   case Z:
00118     return pz();
00119   case T:
00120     return e();
00121   default:
00122     ostringstream err;
00123     err << "PseudoJet subscripting: bad index (" << i << ")";
00124     throw Error(err.str());
00125   }
00126   return 0.;
00127 }  
00128 
00129 //----------------------------------------------------------------------
00130 // return "sum" of two pseudojets
00131 PseudoJet operator+ (const PseudoJet & jet1, const PseudoJet & jet2) {
00132   //return PseudoJet(jet1.four_mom()+jet2.four_mom());
00133   return PseudoJet(jet1.px()+jet2.px(),
00134                    jet1.py()+jet2.py(),
00135                    jet1.pz()+jet2.pz(),
00136                    jet1.E() +jet2.E()  );
00137 } 
00138 
00139 //----------------------------------------------------------------------
00140 // return difference of two pseudojets
00141 PseudoJet operator- (const PseudoJet & jet1, const PseudoJet & jet2) {
00142   //return PseudoJet(jet1.four_mom()-jet2.four_mom());
00143   return PseudoJet(jet1.px()-jet2.px(),
00144                    jet1.py()-jet2.py(),
00145                    jet1.pz()-jet2.pz(),
00146                    jet1.E() -jet2.E()  );
00147 } 
00148 
00149 //----------------------------------------------------------------------
00150 // return the product, coeff * jet
00151 PseudoJet operator* (double coeff, const PseudoJet & jet) {
00152   //return PseudoJet(coeff*jet.four_mom());
00153   // the following code is hopefully more efficient
00154   PseudoJet coeff_times_jet(jet);
00155   coeff_times_jet *= coeff;
00156   return coeff_times_jet;
00157 } 
00158 
00159 //----------------------------------------------------------------------
00160 // return the product, coeff * jet
00161 PseudoJet operator* (const PseudoJet & jet, double coeff) {
00162   return coeff*jet;
00163 } 
00164 
00165 //----------------------------------------------------------------------
00166 // return the ratio, jet / coeff
00167 PseudoJet operator/ (const PseudoJet & jet, double coeff) {
00168   return (1.0/coeff)*jet;
00169 } 
00170 
00171 //----------------------------------------------------------------------
00173 void PseudoJet::operator*=(double coeff) {
00174   _px *= coeff;
00175   _py *= coeff;
00176   _pz *= coeff;
00177   _E  *= coeff;
00178   _kt2*= coeff*coeff;
00179   // phi and rap are unchanged
00180 }
00181 
00182 //----------------------------------------------------------------------
00184 void PseudoJet::operator/=(double coeff) {
00185   (*this) *= 1.0/coeff;
00186 }
00187 
00188 
00189 //----------------------------------------------------------------------
00191 void PseudoJet::operator+=(const PseudoJet & other_jet) {
00192   _px += other_jet._px;
00193   _py += other_jet._py;
00194   _pz += other_jet._pz;
00195   _E  += other_jet._E ;
00196   _finish_init(); // we need to recalculate phi,rap,kt2  
00197 }
00198 
00199 
00200 //----------------------------------------------------------------------
00202 void PseudoJet::operator-=(const PseudoJet & other_jet) {
00203   _px -= other_jet._px;
00204   _py -= other_jet._py;
00205   _pz -= other_jet._pz;
00206   _E  -= other_jet._E ;
00207   _finish_init(); // we need to recalculate phi,rap,kt2  
00208 }
00209 
00210 
00211 //----------------------------------------------------------------------
00212 // return kt-distance between this jet and another one
00213 double PseudoJet::kt_distance(const PseudoJet & other) const {
00214   //double distance = min(this->kt2(), other.kt2());
00215   double distance = min(_kt2, other._kt2);
00216   double dphi = abs(_phi - other._phi);
00217   if (dphi > pi) {dphi = twopi - dphi;}
00218   double drap = _rap - other._rap;
00219   distance = distance * (dphi*dphi + drap*drap);
00220   return distance;
00221 }
00222 
00223 
00224 //----------------------------------------------------------------------
00225 // return squared cylinder (eta-phi) distance between this jet and another one
00226 double PseudoJet::plain_distance(const PseudoJet & other) const {
00227   double dphi = abs(_phi - other._phi);
00228   if (dphi > pi) {dphi = twopi - dphi;}
00229   double drap = _rap - other._rap;
00230   return (dphi*dphi + drap*drap);
00231 }
00232 
00233 //----------------------------------------------------------------------
00234 // sort the indices so that values[indices[0..n-1]] is sorted
00235 // into increasing order 
00236 void sort_indices(vector<int> & indices, 
00237                          const vector<double> & values) {
00238   IndexedSortHelper index_sort_helper(&values);
00239   sort(indices.begin(), indices.end(), index_sort_helper);
00240 }
00241 
00242 //----------------------------------------------------------------------
00246 template<class T> vector<T>  objects_sorted_by_values(
00247                        const vector<T> & objects, 
00248                        const vector<double> & values) {
00249 
00250   assert(objects.size() == values.size());
00251 
00252   // get a vector of indices
00253   vector<int> indices(values.size());
00254   for (size_t i = 0; i < indices.size(); i++) {indices[i] = i;}
00255   
00256   // sort the indices
00257   sort_indices(indices, values);
00258   
00259   // copy the objects 
00260   vector<T> objects_sorted(objects.size());
00261   
00262   // place the objects in the correct order
00263   for (size_t i = 0; i < indices.size(); i++) {
00264     objects_sorted[i] = objects[indices[i]];
00265   }
00266 
00267   return objects_sorted;
00268 }
00269 
00270 //----------------------------------------------------------------------
00272 vector<PseudoJet> sorted_by_pt(const vector<PseudoJet> & jets) {
00273   vector<double> minus_kt2(jets.size());
00274   for (size_t i = 0; i < jets.size(); i++) {minus_kt2[i] = -jets[i].kt2();}
00275   return objects_sorted_by_values(jets, minus_kt2);
00276 }
00277 
00278 //----------------------------------------------------------------------
00280 vector<PseudoJet> sorted_by_rapidity(const vector<PseudoJet> & jets) {
00281   vector<double> rapidities(jets.size());
00282   for (size_t i = 0; i < jets.size(); i++) {rapidities[i] = jets[i].rap();}
00283   return objects_sorted_by_values(jets, rapidities);
00284 }
00285 
00286 //----------------------------------------------------------------------
00288 vector<PseudoJet> sorted_by_E(const vector<PseudoJet> & jets) {
00289   vector<double> energies(jets.size());
00290   for (size_t i = 0; i < jets.size(); i++) {energies[i] = -jets[i].E();}
00291   return objects_sorted_by_values(jets, energies);
00292 }
00293 
00294 
00295 FASTJET_END_NAMESPACE
00296 

Generated on Thu Oct 12 17:36:34 2006 for fastjet by  doxygen 1.4.2