//STARTHEADER // $Id: PseudoJet.hh 1510 2009-04-13 08:48:41Z salam $ // // Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam // //---------------------------------------------------------------------- // This file is part of FastJet. // // FastJet is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // The algorithms that underlie FastJet have required considerable // development and are described in hep-ph/0512210. If you use // FastJet as part of work towards a scientific publication, please // include a citation to the FastJet paper. // // FastJet is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with FastJet; if not, write to the Free Software // Foundation, Inc.: // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //---------------------------------------------------------------------- //ENDHEADER #ifndef __FASTJET_PSEUDOJET_HH__ #define __FASTJET_PSEUDOJET_HH__ #include #include #include #include #include #include "fastjet/internal/numconsts.hh" namespace fastjet { // defined in fastjet/internal/base.hh //using namespace std; /// Used to protect against parton-level events where pt can be zero /// for some partons, giving rapidity=infinity. KtJet fails in those cases. const double MaxRap = 1e5; /// Class to contain pseudojets, including minimal information of use to /// to jet-clustering routines. class PseudoJet { public: PseudoJet() {}; /// construct a pseudojet from explicit components PseudoJet(const double px, const double py, const double pz, const double E); /// constructor from any object that has px,py,pz,E = some_four_vector[0--3], template PseudoJet(const L & some_four_vector) ; // first "const double &" says that result is a reference to the // stored value and that we will not change that stored value. // // second "const" says that "this" will not be modified by these // functions. inline double E() const {return _E;} inline double e() const {return _E;} // like CLHEP inline double px() const {return _px;} inline double py() const {return _py;} inline double pz() const {return _pz;} /// returns phi (in the range 0..2pi) inline double phi() const {return phi_02pi();} /// returns phi in the range -pi..pi inline double phi_std() const { return _phi > pi ? _phi-twopi : _phi;} /// returns phi in the range 0..2pi inline double phi_02pi() const {return _phi;} /// returns the rapidity or some large value when the rapidity /// is infinite inline double rap() const {return _rap;} /// the same as rap() inline double rapidity() const {return _rap;} // like CLHEP /// returns the pseudo-rapidity or some large value when the /// rapidity is infinite double pseudorapidity() const; double eta() const {return pseudorapidity();} /// returns the squared transverse momentum inline double kt2() const {return _kt2;} /// returns the squared transverse momentum inline double perp2() const {return _kt2;} // like CLHEP /// returns the scalar transverse momentum inline double perp() const {return sqrt(_kt2);} // like CLHEP /// returns the squared invariant mass // like CLHEP inline double m2() const {return (_E+_pz)*(_E-_pz)-_kt2;} /// returns the squared transverse mass = kt^2+m^2 inline double mperp2() const {return (_E+_pz)*(_E-_pz);} /// returns the transverse mass = sqrt(kt^2+m^2) inline double mperp() const {return sqrt(std::abs(mperp2()));} /// returns the invariant mass /// (If m2() is negative then -sqrt(-m2()) is returned, as in CLHEP) inline double m() const; /// return px^2+py^2+pz^2 inline double modp2() const {return _kt2+_pz*_pz;} /// return the transverse energy inline double Et() const {return (_kt2==0) ? 0.0 : _E/sqrt(1.0+_pz*_pz/_kt2);} /// return the transverse energy squared inline double Et2() const {return (_kt2==0) ? 0.0 : _E*_E/(1.0+_pz*_pz/_kt2);} /// returns component i, where X==0, Y==1, Z==2, E==3 double operator () (int i) const ; /// returns component i, where X==0, Y==1, Z==2, E==3 inline double operator [] (int i) const { return (*this)(i); }; // this too // taken from CLHEP enum { X=0, Y=1, Z=2, T=3, NUM_COORDINATES=4, SIZE=NUM_COORDINATES }; /// transform this jet (given in the rest frame of prest) into a jet /// in the lab frame [NOT FULLY TESTED] PseudoJet & boost(const PseudoJet & prest); /// transform this jet (given in lab) into a jet in the rest /// frame of prest [NOT FULLY TESTED] PseudoJet & unboost(const PseudoJet & prest); /// return the cluster_hist_index, intended to be used by clustering /// routines. inline int cluster_hist_index() const {return _cluster_hist_index;} /// set the cluster_hist_index, intended to be used by clustering routines. inline void set_cluster_hist_index(const int index) {_cluster_hist_index = index;} /// alternative name for cluster_hist_index() [perhaps more meaningful] inline int cluster_sequence_history_index() const { return cluster_hist_index();} /// alternative name for set_cluster_hist_index(...) [perhaps more /// meaningful] inline void set_cluster_sequence_history_index(const int index) { set_cluster_hist_index(index);} /// return the user_index, intended to allow the user to "add" information inline int user_index() const {return _user_index;} /// set the user_index, intended to allow the user to "add" information inline void set_user_index(const int index) {_user_index = index;} /// return a valarray containing the four-momentum (components 0-2 /// are 3-mom, component 3 is energy). std::valarray four_mom() const; /// returns kt distance (R=1) between this jet and another double kt_distance(const PseudoJet & other) const; /// returns squared cylinder (rap-phi) distance between this jet and another double plain_distance(const PseudoJet & other) const; /// returns squared cylinder (rap-phi) distance between this jet and /// another inline double squared_distance(const PseudoJet & other) const { return plain_distance(other);} /// returns other.phi() - this.phi(), constrained to be in /// range -pi .. pi double delta_phi_to(const PseudoJet & other) const; //// this seemed to compile except if it was used //friend inline double // kt_distance(const PseudoJet & jet1, const PseudoJet & jet2) { // return jet1.kt_distance(jet2);} /// returns distance between this jet and the beam inline double beam_distance() const {return _kt2;} void operator*=(double); void operator/=(double); void operator+=(const PseudoJet &); void operator-=(const PseudoJet &); /// reset the 4-momentum according to the supplied components and /// put the user and history indices back to their default values inline void reset(double px, double py, double pz, double E); /// reset the PseudoJet to be equal to psjet (including its /// indices); NB if the argument is derived from a PseudoJet then /// the "reset" used will be the templated version (which does not /// know about indices...) inline void reset(const PseudoJet & psjet) { (*this) = psjet; } /// reset the 4-momentum according to the supplied generic 4-vector /// (accessible via indexing, [0]==px,...[3]==E) and put the user /// and history indices back to their default values. template inline void reset(const L & some_four_vector) { reset(some_four_vector[0], some_four_vector[1], some_four_vector[2], some_four_vector[3]); } private: // NB: following order must be kept for things to behave sensibly... double _px,_py,_pz,_E; double _phi, _rap, _kt2; int _cluster_hist_index, _user_index; /// calculate phi, rap, kt2 based on the 4-momentum components void _finish_init(); /// set the indices to default values void _reset_indices(); //vertex_type * vertex0, vertex1; }; //---------------------------------------------------------------------- // routines for basic binary operations PseudoJet operator+(const PseudoJet &, const PseudoJet &); PseudoJet operator-(const PseudoJet &, const PseudoJet &); PseudoJet operator*(double, const PseudoJet &); PseudoJet operator*(const PseudoJet &, double); PseudoJet operator/(const PseudoJet &, double); inline double dot_product(const PseudoJet & a, const PseudoJet & b) { return a.E()*b.E() - a.px()*b.px() - a.py()*b.py() - a.pz()*b.pz(); } /// returns true if the momenta of the two input jets are identical bool have_same_momentum(const PseudoJet &, const PseudoJet &); /// return a pseudojet with the given pt, y, phi and mass PseudoJet PtYPhiM(double pt, double y, double phi, double m = 0.0); //---------------------------------------------------------------------- // Routines to do with providing sorted arrays of vectors. /// return a vector of jets sorted into decreasing transverse momentum std::vector sorted_by_pt(const std::vector & jets); /// return a vector of jets sorted into increasing rapidity std::vector sorted_by_rapidity(const std::vector & jets); /// return a vector of jets sorted into decreasing energy std::vector sorted_by_E(const std::vector & jets); /// return a vector of jets sorted into increasing pz std::vector sorted_by_pz(const std::vector & jets); //---------------------------------------------------------------------- // some code to help sorting /// sort the indices so that values[indices[0->n-1]] is sorted /// into increasing order void sort_indices(std::vector & indices, const std::vector & values); /// given a vector of values with a one-to-one correspondence with the /// vector of objects, sort objects into an order such that the /// associated values would be in increasing order (but don't actually /// touch the values vector in the process). template std::vector objects_sorted_by_values(const std::vector & objects, const std::vector & values); /// a class that helps us carry out indexed sorting. class IndexedSortHelper { public: inline IndexedSortHelper (const std::vector * reference_values) { _ref_values = reference_values; }; inline int operator() (const int & i1, const int & i2) const { return (*_ref_values)[i1] < (*_ref_values)[i2]; }; private: const std::vector * _ref_values; }; //---------------------------------------------------------------------- /// constructor from any object that has px,py,pz,E = some_four_vector[0--3], // NB: do not know if it really needs to be inline, but when it wasn't // linking failed with g++ (who knows what was wrong...) template inline PseudoJet::PseudoJet(const L & some_four_vector) { _px = some_four_vector[0]; _py = some_four_vector[1]; _pz = some_four_vector[2]; _E = some_four_vector[3]; _finish_init(); // some default values for these two indices _reset_indices(); } //---------------------------------------------------------------------- inline void PseudoJet::_reset_indices() { set_cluster_hist_index(-1); set_user_index(-1); } //---------------------------------------------------------------------- /// specialization of the "reset" template for case where something /// is reset to a pseudojet -- it then takes the user and history /// indices from the psjet // template<> inline void PseudoJet::reset(const PseudoJet & psjet) { // (*this) = psjet; // } ////// fun and games... ////template class FJVector : public L { ////// /** Default Constructor: create jet with no constituents */ ////// Vector(); //// ////}; //// // taken literally from CLHEP inline double PseudoJet::m() const { double mm = m2(); return mm < 0.0 ? -std::sqrt(-mm) : std::sqrt(mm); } inline void PseudoJet::reset(double px, double py, double pz, double E) { _px = px; _py = py; _pz = pz; _E = E; _finish_init(); _reset_indices(); } } // fastjet namespace #endif // __FASTJET_PSEUDOJET_HH__