32 #include "fastjet/Error.hh"    33 #include "fastjet/PseudoJet.hh"    34 #include "fastjet/ClusterSequence.hh"    36 #include "fastjet/ClusterSequenceAreaBase.hh"    38 #include "fastjet/CompositeJetStructure.hh"    46 FASTJET_BEGIN_NAMESPACE      
    53 PseudoJet::PseudoJet(
const double px_in, 
const double py_in, 
const double pz_in, 
const double E_in) {
    70 void PseudoJet::_finish_init () {
    71   _kt2 = this->px()*this->px() + this->py()*this->py();
    80   _rap = pseudojet_invalid_rap;
    84 void PseudoJet::_set_rap_phi()
 const {
    89     _phi = atan2(this->py(),this->px());
    91   if (_phi < 0.0) {_phi += twopi;}
    92   if (_phi >= twopi) {_phi -= twopi;} 
    93   if (this->E() == abs(this->pz()) && _kt2 == 0) {
    98     double MaxRapHere = 
MaxRap + abs(this->pz());
    99     if (this->pz() >= 0.0) {_rap = MaxRapHere;} 
else {_rap = -MaxRapHere;}
   104     double effective_m2 = max(0.0,m2()); 
   105     double E_plus_pz    = _E + abs(_pz); 
   107     _rap = 0.5*log((_kt2 + effective_m2)/(E_plus_pz*E_plus_pz));
   108     if (_pz > 0) {_rap = - _rap;}
   116 valarray<double> PseudoJet::four_mom()
 const {
   117   valarray<double> mom(4);
   128 double PseudoJet::operator () (
int i)
 const {
   140     err << 
"PseudoJet subscripting: bad index (" << i << 
")";
   141     throw Error(err.str());
   148 double PseudoJet::pseudorapidity()
 const {
   149   if (px() == 0.0 && py() ==0.0) 
return MaxRap;
   150   if (pz() == 0.0) 
return 0.0;
   152   double theta = atan(perp()/pz());
   153   if (theta < 0) theta += pi;
   154   return -log(tan(theta/2));
   164                    jet1.E() +jet2.E()  );
   174                    jet1.E() -jet2.E()  );
   183   jet._ensure_valid_rap_phi(); 
   187   coeff_times_jet *= coeff;
   188   return coeff_times_jet;
   200   return (1.0/coeff)*jet;
   205 void PseudoJet::operator*=(
double coeff) {
   213   _ensure_valid_rap_phi(); 
   224 void PseudoJet::operator/=(
double coeff) {
   225   (*this) *= 1.0/coeff;
   231 void PseudoJet::operator+=(
const PseudoJet & other_jet) {
   232   _px += other_jet._px;
   233   _py += other_jet._py;
   234   _pz += other_jet._pz;
   242 void PseudoJet::operator-=(
const PseudoJet & other_jet) {
   243   _px -= other_jet._px;
   244   _py -= other_jet._py;
   245   _pz -= other_jet._pz;
   252   if (a.px() != b.px()) 
return false;
   253   if (a.py() != b.py()) 
return false;
   254   if (a.pz() != b.pz()) 
return false;
   255   if (a.E () != b.E ()) 
return false;
   269     throw Error(
"comparing a PseudoJet with a non-zero constant (double) is not allowed.");
   270   return (jet.px() == 0 && jet.py() == 0 && 
   271           jet.pz() == 0 && jet.E() == 0);
   284   if (prest.px() == 0.0 && prest.py() == 0.0 && prest.pz() == 0.0) 
   287   double m_local = prest.
m();
   288   assert(m_local != 0);
   290   double pf4  = (  px()*prest.px() + py()*prest.py()
   291                  + pz()*prest.pz() + E()*prest.E() )/m_local;
   292   double fn   = (pf4 + E()) / (prest.E() + m_local);
   293   _px +=  fn*prest.px();
   294   _py +=  fn*prest.py();
   295   _pz +=  fn*prest.pz();
   311   if (prest.px() == 0.0 && prest.py() == 0.0 && prest.pz() == 0.0) 
   314   double m_local = prest.
m();
   315   assert(m_local != 0);
   317   double pf4  = ( -px()*prest.px() - py()*prest.py()
   318                  - pz()*prest.pz() + E()*prest.E() )/m_local;
   319   double fn   = (pf4 + E()) / (prest.E() + m_local);
   320   _px -=  fn*prest.px();
   321   _py -=  fn*prest.py();
   322   _pz -=  fn*prest.pz();
   333   return jeta.px() == jetb.px()
   334     &&   jeta.py() == jetb.py()
   335     &&   jeta.pz() == jetb.pz()
   336     &&   jeta.E()  == jetb.E();
   340 void PseudoJet::set_cached_rap_phi(
double rap_in, 
double phi_in) {
   341   _rap = rap_in; _phi = phi_in;
   342   if (_phi >= twopi) _phi -= twopi;
   343   if (_phi < 0)      _phi += twopi;
   347 void PseudoJet::reset_momentum_PtYPhiM(
double pt_in, 
double y_in, 
double phi_in, 
double m_in) {
   348   assert(phi_in < 2*twopi && phi_in > -twopi);
   349   double ptm = (m_in == 0) ? pt_in : sqrt(pt_in*pt_in+m_in*m_in);
   350   double exprap = exp(y_in);
   351   double pminus = ptm/exprap;
   352   double pplus  = ptm*exprap;
   353   double px_local = pt_in*cos(phi_in);
   354   double py_local = pt_in*sin(phi_in);
   355   reset_momentum(px_local,py_local,0.5*(pplus-pminus),0.5*(pplus+pminus));
   356   set_cached_rap_phi(y_in,phi_in);
   362   assert(phi < 2*twopi && phi > -twopi);
   363   double ptm = (m == 0) ? pt : sqrt(pt*pt+m*m);
   364   double exprap = exp(y);
   365   double pminus = ptm/exprap;
   366   double pplus  = ptm*exprap;
   367   double px = pt*cos(phi);
   368   double py = pt*sin(phi);
   369   PseudoJet mom(px,py,0.5*(pplus-pminus),0.5*(pplus+pminus));
   378 double PseudoJet::kt_distance(
const PseudoJet & other)
 const {
   380   double distance = min(_kt2, other._kt2);
   381   double dphi = abs(phi() - other.
phi());
   382   if (dphi > pi) {dphi = twopi - dphi;}
   383   double drap = rap() - other.
rap();
   384   distance = distance * (dphi*dphi + drap*drap);
   391 double PseudoJet::plain_distance(
const PseudoJet & other)
 const {
   392   double dphi = abs(phi() - other.
phi());
   393   if (dphi > pi) {dphi = twopi - dphi;}
   394   double drap = rap() - other.
rap();
   395   return (dphi*dphi + drap*drap);
   401 double PseudoJet::delta_phi_to(
const PseudoJet & other)
 const {
   402   double dphi = other.
phi() - phi();
   403   if (dphi >  pi) dphi -= twopi;
   404   if (dphi < -pi) dphi += twopi;
   409 string PseudoJet::description()
 const{
   412     return "standard PseudoJet (with no associated clustering information)";
   415   return _structure->description();
   430 bool PseudoJet::has_associated_cluster_sequence()
 const{
   431   return (_structure) && (_structure->has_associated_cluster_sequence());
   438   if (! has_associated_cluster_sequence()) 
return NULL;
   440   return _structure->associated_cluster_sequence();
   447 bool PseudoJet::has_valid_cluster_sequence()
 const{
   448   return (_structure) && (_structure->has_valid_cluster_sequence());
   458   return validated_structure_ptr()->validated_cs();
   465   _structure = structure_in;
   470 bool PseudoJet::has_structure()
 const{
   471   return bool(_structure);
   481   return _structure.get();
   496   return _structure.get();
   506     throw Error(
"Trying to access the structure of a PseudoJet which has no associated structure");
   507   return _structure.get();
   526   return validated_structure_ptr()->has_partner(*
this, partner);
   537   return validated_structure_ptr()->has_child(*
this, child);
   548   return validated_structure_ptr()->has_parents(*
this, parent1, parent2);
   557 bool PseudoJet::contains(
const PseudoJet &constituent)
 const{
   558   return validated_structure_ptr()->object_in_jet(constituent, *
this);
   568   return validated_structure_ptr()->object_in_jet(*
this, jet);
   574 bool PseudoJet::has_constituents()
 const{
   575   return (_structure) && (_structure->has_constituents());
   580 vector<PseudoJet> PseudoJet::constituents()
 const{
   581   return validated_structure_ptr()->constituents(*
this);
   587 bool PseudoJet::has_exclusive_subjets()
 const{
   588   return (_structure) && (_structure->has_exclusive_subjets());
   603 std::vector<PseudoJet> PseudoJet::exclusive_subjets (
const double dcut)
 const {
   604   return validated_structure_ptr()->exclusive_subjets(*
this, dcut);
   614 int PseudoJet::n_exclusive_subjets(
const double dcut)
 const {
   615   return validated_structure_ptr()->n_exclusive_subjets(*
this, dcut);
   627 std::vector<PseudoJet> PseudoJet::exclusive_subjets_up_to (
int nsub)
 const {
   628   return validated_structure_ptr()->exclusive_subjets_up_to(*
this, nsub);
   634 std::vector<PseudoJet> PseudoJet::exclusive_subjets (
int nsub)
 const {
   635   vector<PseudoJet> subjets = exclusive_subjets_up_to(nsub);
   636   if (
int(subjets.size()) < nsub) {
   638     err << 
"Requested " << nsub << 
" exclusive subjets, but there were only "    639         << subjets.size() << 
" particles in the jet";
   640     throw Error(err.str());
   651 double PseudoJet::exclusive_subdmerge(
int nsub)
 const {
   652   return validated_structure_ptr()->exclusive_subdmerge(*
this, nsub);
   662 double PseudoJet::exclusive_subdmerge_max(
int nsub)
 const {
   663   return validated_structure_ptr()->exclusive_subdmerge_max(*
this, nsub);
   671 bool PseudoJet::has_pieces()
 const{
   672   return ((_structure) && (_structure->has_pieces(*
this)));
   680 std::vector<PseudoJet> PseudoJet::pieces()
 const{
   681   return validated_structure_ptr()->pieces(*
this);
   701   if (csab == NULL) 
throw Error(
"you requested jet-area related information, but the PseudoJet does not have associated area information.");
   708 bool PseudoJet::has_area()
 const{
   710   if (! has_structure()) 
return false;
   711   return (validated_structure_ptr()->has_area() != 0);
   717 double PseudoJet::area()
 const{
   718   return validated_structure_ptr()->
area(*
this);
   725 double PseudoJet::area_error()
 const{
   726   return validated_structure_ptr()->area_error(*
this);
   739 bool PseudoJet::is_pure_ghost()
 const{
   754 PseudoJet::InexistentUserInfo::InexistentUserInfo() : 
Error(
"you attempted to perform a dynamic cast of a PseudoJet's extra info, but the extra info pointer was null")
   761 void sort_indices(vector<int> & indices, 
   762                          const vector<double> & values) {
   763   IndexedSortHelper index_sort_helper(&values);
   764   sort(indices.begin(), indices.end(), index_sort_helper);
   771   vector<double> minus_kt2(jets.size());
   772   for (
size_t i = 0; i < jets.size(); i++) {minus_kt2[i] = -jets[i].kt2();}
   779   vector<double> rapidities(jets.size());
   780   for (
size_t i = 0; i < jets.size(); i++) {rapidities[i] = jets[i].rap();}
   787   vector<double> energies(jets.size());
   788   for (
size_t i = 0; i < jets.size(); i++) {energies[i] = -jets[i].E();}
   795   vector<double> pz(jets.size());
   796   for (
size_t i = 0; i < jets.size(); i++) {pz[i] = jets[i].pz();}
   814   for (
unsigned int i=0; i<pieces.size(); i++)
   828   return join(vector<PseudoJet>(1,j1));
   835   pieces.push_back(j1);
   836   pieces.push_back(j2);
   844   pieces.push_back(j1);
   845   pieces.push_back(j2);
   846   pieces.push_back(j3);
   854   pieces.push_back(j1);
   855   pieces.push_back(j2);
   856   pieces.push_back(j3);
   857   pieces.push_back(j4);
   864 FASTJET_END_NAMESPACE
 PseudoJet PtYPhiM(double pt, double y, double phi, double m)
return a pseudojet with the given pt, y, phi and mass 
double rap() const 
returns the rapidity or some large value when the rapidity is infinite 
void set_cached_rap_phi(double rap, double phi)
in some cases when setting a 4-momentum, the user/program knows what rapidity and azimuth are associa...
vector< PseudoJet > sorted_by_pt(const vector< PseudoJet > &jets)
return a vector of jets sorted into decreasing kt2 
const UserInfoBase * user_info_ptr() const 
retrieve a pointer to the (const) user information 
std::vector< T > objects_sorted_by_values(const std::vector< T > &objects, const std::vector< double > &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). 
const double MaxRap
Used to protect against parton-level events where pt can be zero for some partons, giving rapidity=infinity. 
int cluster_hist_index() const 
return the cluster_hist_index, intended to be used by clustering routines. 
Selector operator*(const Selector &s1, const Selector &s2)
successive application of 2 selectors 
vector< PseudoJet > sorted_by_pz(const vector< PseudoJet > &jets)
return a vector of jets sorted into increasing pz 
vector< PseudoJet > sorted_by_rapidity(const vector< PseudoJet > &jets)
return a vector of jets sorted into increasing rapidity 
The structure for a jet made of pieces. 
Contains any information related to the clustering that should be directly accessible to PseudoJet...
virtual std::vector< PseudoJet > pieces() const 
retrieve the pieces that make up the jet. 
bool operator==(const PseudoJet &a, const PseudoJet &b)
returns true if the 4 momentum components of the two PseudoJets are identical and all the internal in...
virtual double area(const PseudoJet &) const 
return the area associated with the given jet; this base class returns 0. 
base class that sets interface for extensions of ClusterSequence that provide information about the a...
vector< PseudoJet > sorted_by_E(const vector< PseudoJet > &jets)
return a vector of jets sorted into decreasing energy 
base class corresponding to errors that can be thrown by FastJet 
an implementation of C++0x shared pointers (or boost's) 
virtual bool is_pure_ghost() const 
true if this jet is made exclusively of ghosts. 
bool have_same_momentum(const PseudoJet &jeta, const PseudoJet &jetb)
returns true if the momenta of the two input jets are identical 
double phi() const 
returns phi (in the range 0..2pi) 
int user_index() const 
return the user_index, 
void set_structure_shared_ptr(const SharedPtr< PseudoJetStructureBase > &structure)
set the associated structure 
double m() const 
returns the invariant mass (If m2() is negative then -sqrt(-m2()) is returned, as in CLHEP) ...
const double pseudojet_invalid_phi
default value for phi, meaning it (and rapidity) have yet to be calculated) 
Class to contain pseudojets, including minimal information of use to jet-clustering routines...
const PseudoJetStructureBase * structure_ptr() const 
return a pointer to the structure (of type PseudoJetStructureBase*) associated with this PseudoJet...
virtual PseudoJet area_4vector() const 
return the jet 4-vector area.