JetDefinition.cc

00001 //STARTHEADER
00002 // $Id: JetDefinition.cc 1816 2010-11-19 11:35:52Z salam $
00003 //
00004 // Copyright (c) 2005-2007, 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 #include "fastjet/JetDefinition.hh"
00032 #include "fastjet/Error.hh"
00033 #include<sstream>
00034 
00035 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
00036 
00037 using namespace std;
00038 
00039 //----------------------------------------------------------------------
00040 // [NB: implementation was getting complex, so in 2.4-devel moved it
00041 //  from .hh to .cc]
00042 JetDefinition::JetDefinition(JetAlgorithm jet_algorithm, 
00043                              double R, 
00044                              Strategy strategy,
00045                              RecombinationScheme recomb_scheme,
00046                              int nparameters) :
00047   _jet_algorithm(jet_algorithm), _Rparam(R), _strategy(strategy) {
00048 
00049   // set R parameter or ensure its sensibleness, as appropriate
00050   if (jet_algorithm == ee_kt_algorithm) {
00051     _Rparam = 4.0; // introduce a fictional R that ensures that
00052                    // our clustering sequence will not produce
00053                    // "beam" jets except when only a single particle remains.
00054                    // Any value > 2 would have done here
00055   } else {
00056     // We maintain some limit on R because particles with pt=0, m=0
00057     // can have rapidities O(10000) and one doesn't want the
00058     // clustering to start including them as if their rapidities were
00059     // physical.
00060     assert ( R < 1000.0);
00061   }
00062 
00063   // cross-check the number of parameters that were declared in setting up the
00064   // algorithm (passed internally from the public constructors)
00065   ostringstream oss;
00066   switch (jet_algorithm) {
00067   case ee_kt_algorithm:
00068     if (nparameters != 0) oss << "ee_kt_algorithm should be constructed with 0 parameters but was called with " 
00069                               << nparameters << " parameter(s)\n";
00070     break;
00071   case genkt_algorithm: 
00072   case ee_genkt_algorithm: 
00073     if (nparameters != 2) oss << "(ee_)genkt_algorithm should be constructed with 2 parameters but was called with " 
00074                               << nparameters << " parameter(s)\n";
00075     break;
00076   default:
00077     if (nparameters != 1)
00078     oss << "The jet algorithm you requested ("
00079         << jet_algorithm << ") should be constructed with 1 parameter but was called with " 
00080         << nparameters << " parameter(s)\n";
00081   }
00082   if (oss.str() != "") throw Error(oss.str()); 
00083 
00084   // make sure the strategy requested is sensible
00085   assert (_strategy  != plugin_strategy);
00086 
00087   _plugin = NULL;
00088   set_recombination_scheme(recomb_scheme);
00089   set_extra_param(0.0); // make sure it's defined
00090 }
00091 
00092 
00093 //----------------------------------------------------------------------
00094 string JetDefinition::description() const {
00095   ostringstream name;
00096   if (jet_algorithm() == plugin_algorithm) {
00097     return plugin()->description();
00098   } else if (jet_algorithm() == kt_algorithm) {
00099     name << "Longitudinally invariant kt algorithm with R = " << R();
00100     name << " and " << recombiner()->description();
00101   } else if (jet_algorithm() == cambridge_algorithm) {
00102     name << "Longitudinally invariant Cambridge/Aachen algorithm with R = " 
00103          << R() ;
00104     name << " and " << recombiner()->description();
00105   } else if (jet_algorithm() == antikt_algorithm) {
00106     name << "Longitudinally invariant anti-kt algorithm with R = " 
00107          << R() ;
00108     name << " and " << recombiner()->description();
00109   } else if (jet_algorithm() == genkt_algorithm) {
00110     name << "Longitudinally invariant generalised kt algorithm with R = " 
00111          << R() << ", p = " << extra_param();
00112     name << " and " << recombiner()->description();
00113   } else if (jet_algorithm() == cambridge_for_passive_algorithm) {
00114     name << "Longitudinally invariant Cambridge/Aachen algorithm with R = " 
00115          << R() << "and a special hack whereby particles with kt < " 
00116          << extra_param() << "are treated as passive ghosts";
00117   } else if (jet_algorithm() == ee_kt_algorithm) {
00118     name << "e+e- kt (Durham) algorithm (NB: no R)";
00119     name << " with " << recombiner()->description();
00120   } else if (jet_algorithm() == ee_genkt_algorithm) {
00121     name << "e+e- generalised kt algorithm with R = " 
00122          << R() << ", p = " << extra_param();
00123     name << " and " << recombiner()->description();
00124   } else {
00125     throw Error("JetDefinition::description(): unrecognized jet_finder");
00126   }
00127   return name.str();
00128 }
00129 
00130 
00131 void JetDefinition::set_recombination_scheme(
00132                                RecombinationScheme recomb_scheme) {
00133   _default_recombiner = JetDefinition::DefaultRecombiner(recomb_scheme);
00134   _recombiner = 0;
00135 }
00136 
00137 
00138 string JetDefinition::DefaultRecombiner::description() const {
00139   switch(_recomb_scheme) {
00140   case E_scheme:
00141     return "E scheme recombination";
00142   case pt_scheme:
00143     return "pt scheme recombination";
00144   case pt2_scheme:
00145     return "pt2 scheme recombination";
00146   case Et_scheme:
00147     return "Et scheme recombination";
00148   case Et2_scheme:
00149     return "Et2 scheme recombination";
00150   case BIpt_scheme:
00151     return "boost-invariant pt scheme recombination";
00152   case BIpt2_scheme:
00153     return "boost-invariant pt2 scheme recombination";
00154   default:
00155     ostringstream err;
00156     err << "DefaultRecombiner: unrecognized recombination scheme " 
00157         << _recomb_scheme;
00158     throw Error(err.str());
00159   }
00160 }
00161 
00162 
00163 void JetDefinition::DefaultRecombiner::recombine(
00164            const PseudoJet & pa, const PseudoJet & pb,
00165            PseudoJet & pab) const {
00166   
00167   double weighta, weightb;
00168 
00169   switch(_recomb_scheme) {
00170   case E_scheme:
00171     pab = pa + pb; 
00172     pab.set_user_index(0);
00173     return;
00174   // all remaining schemes are massless recombinations and locally
00175   // we just set weights, while the hard work is done below...
00176   case pt_scheme:
00177   case Et_scheme:
00178   case BIpt_scheme:
00179     weighta = pa.perp(); 
00180     weightb = pb.perp();
00181     break;
00182   case pt2_scheme:
00183   case Et2_scheme:
00184   case BIpt2_scheme:
00185     weighta = pa.perp2(); 
00186     weightb = pb.perp2();
00187     break;
00188   default:
00189     ostringstream err;
00190     err << "DefaultRecombiner: unrecognized recombination scheme " 
00191         << _recomb_scheme;
00192     throw Error(err.str());
00193   }
00194 
00195   double perp_ab = pa.perp() + pb.perp();
00196   if (perp_ab != 0.0) { // weights also non-zero...
00197     double y_ab    = (weighta * pa.rap() + weightb * pb.rap())/(weighta+weightb);
00198     
00199     // take care with periodicity in phi...
00200     double phi_a = pa.phi(), phi_b = pb.phi();
00201     if (phi_a - phi_b > pi)  phi_b += twopi;
00202     if (phi_a - phi_b < -pi) phi_b -= twopi;
00203     double phi_ab = (weighta * phi_a + weightb * phi_b)/(weighta+weightb);
00204     
00205     pab = PseudoJet(perp_ab*cos(phi_ab),
00206                     perp_ab*sin(phi_ab),
00207                     perp_ab*sinh(y_ab),
00208                     perp_ab*cosh(y_ab));
00209   } else { // weights are zero
00210     pab = PseudoJet(0.0,0.0,0.0,0.0);
00211   }
00212   pab.set_user_index(0);
00213 }
00214 
00215 
00216 void JetDefinition::DefaultRecombiner::preprocess(PseudoJet & p) const {
00217   switch(_recomb_scheme) {
00218   case E_scheme:
00219   case BIpt_scheme:
00220   case BIpt2_scheme:
00221     break;
00222   case pt_scheme:
00223   case pt2_scheme:
00224     {
00225       // these schemes (as in the ktjet implementation) need massless
00226       // initial 4-vectors with essentially E=|p|.
00227       double newE = sqrt(p.perp2()+p.pz()*p.pz());
00228       int    user_index = p.user_index();
00229       p = PseudoJet(p.px(), p.py(), p.pz(), newE);
00230       p.set_user_index(user_index);
00231     }
00232     break;
00233   case Et_scheme:
00234   case Et2_scheme:
00235     {
00236       // these schemes (as in the ktjet implementation) need massless
00237       // initial 4-vectors with essentially E=|p|.
00238       double rescale = p.E()/sqrt(p.perp2()+p.pz()*p.pz());
00239       int    user_index = p.user_index();
00240       p = PseudoJet(rescale*p.px(), rescale*p.py(), rescale*p.pz(), p.E());
00241       p.set_user_index(user_index);
00242     }
00243     break;
00244   default:
00245     ostringstream err;
00246     err << "DefaultRecombiner: unrecognized recombination scheme " 
00247         << _recomb_scheme;
00248     throw Error(err.str());
00249   }
00250 }
00251 
00252 void JetDefinition::Plugin::set_ghost_separation_scale(double scale) const {
00253       throw Error("set_ghost_separation_scale not supported");
00254 }
00255  
00256 
00257 FASTJET_END_NAMESPACE