|
FastJet 3.0alpha3
|
00001 //STARTHEADER 00002 // $Id: JetDefinition.cc 2222 2011-06-02 23:27:59Z soyez $ 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 "fastjet/CompositeJetStructure.hh" 00034 #include<sstream> 00035 00036 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00037 00038 using namespace std; 00039 00040 //---------------------------------------------------------------------- 00041 // [NB: implementation was getting complex, so in 2.4-devel moved it 00042 // from .hh to .cc] 00043 JetDefinition::JetDefinition(JetAlgorithm jet_algorithm, 00044 double R, 00045 Strategy strategy, 00046 RecombinationScheme recomb_scheme, 00047 int nparameters) : 00048 _jet_algorithm(jet_algorithm), _Rparam(R), _strategy(strategy) { 00049 00050 // set R parameter or ensure its sensibleness, as appropriate 00051 if (jet_algorithm == ee_kt_algorithm) { 00052 _Rparam = 4.0; // introduce a fictional R that ensures that 00053 // our clustering sequence will not produce 00054 // "beam" jets except when only a single particle remains. 00055 // Any value > 2 would have done here 00056 } else { 00057 // We maintain some limit on R because particles with pt=0, m=0 00058 // can have rapidities O(10000) and one doesn't want the 00059 // clustering to start including them as if their rapidities were 00060 // physical. 00061 assert ( R < 1000.0); 00062 } 00063 00064 // cross-check the number of parameters that were declared in setting up the 00065 // algorithm (passed internally from the public constructors) 00066 ostringstream oss; 00067 switch (jet_algorithm) { 00068 case ee_kt_algorithm: 00069 if (nparameters != 0) oss << "ee_kt_algorithm should be constructed with 0 parameters but was called with " 00070 << nparameters << " parameter(s)\n"; 00071 break; 00072 case genkt_algorithm: 00073 case ee_genkt_algorithm: 00074 if (nparameters != 2) oss << "(ee_)genkt_algorithm should be constructed with 2 parameters but was called with " 00075 << nparameters << " parameter(s)\n"; 00076 break; 00077 default: 00078 if (nparameters != 1) 00079 oss << "The jet algorithm you requested (" 00080 << jet_algorithm << ") should be constructed with 1 parameter but was called with " 00081 << nparameters << " parameter(s)\n"; 00082 } 00083 if (oss.str() != "") throw Error(oss.str()); 00084 00085 // make sure the strategy requested is sensible 00086 assert (_strategy != plugin_strategy); 00087 00088 _plugin = NULL; 00089 set_recombination_scheme(recomb_scheme); 00090 set_extra_param(0.0); // make sure it's defined 00091 } 00092 00093 00094 //---------------------------------------------------------------------- 00095 string JetDefinition::description() const { 00096 ostringstream name; 00097 if (jet_algorithm() == plugin_algorithm) { 00098 return plugin()->description(); 00099 } else if (jet_algorithm() == kt_algorithm) { 00100 name << "Longitudinally invariant kt algorithm with R = " << R(); 00101 name << " and " << recombiner()->description(); 00102 } else if (jet_algorithm() == cambridge_algorithm) { 00103 name << "Longitudinally invariant Cambridge/Aachen algorithm with R = " 00104 << R() ; 00105 name << " and " << recombiner()->description(); 00106 } else if (jet_algorithm() == antikt_algorithm) { 00107 name << "Longitudinally invariant anti-kt algorithm with R = " 00108 << R() ; 00109 name << " and " << recombiner()->description(); 00110 } else if (jet_algorithm() == genkt_algorithm) { 00111 name << "Longitudinally invariant generalised kt algorithm with R = " 00112 << R() << ", p = " << extra_param(); 00113 name << " and " << recombiner()->description(); 00114 } else if (jet_algorithm() == cambridge_for_passive_algorithm) { 00115 name << "Longitudinally invariant Cambridge/Aachen algorithm with R = " 00116 << R() << "and a special hack whereby particles with kt < " 00117 << extra_param() << "are treated as passive ghosts"; 00118 } else if (jet_algorithm() == ee_kt_algorithm) { 00119 name << "e+e- kt (Durham) algorithm (NB: no R)"; 00120 name << " with " << recombiner()->description(); 00121 } else if (jet_algorithm() == ee_genkt_algorithm) { 00122 name << "e+e- generalised kt algorithm with R = " 00123 << R() << ", p = " << extra_param(); 00124 name << " and " << recombiner()->description(); 00125 } else if (jet_algorithm() == undefined_jet_algorithm) { 00126 name << "uninitialised JetDefinition (jet_algorithm=undefined_jet_algorithm)" ; 00127 } else { 00128 throw Error("JetDefinition::description(): unrecognized jet_algorithm"); 00129 } 00130 return name.str(); 00131 } 00132 00133 00134 void JetDefinition::set_recombination_scheme( 00135 RecombinationScheme recomb_scheme) { 00136 _default_recombiner = JetDefinition::DefaultRecombiner(recomb_scheme); 00137 _recombiner = 0; 00138 } 00139 00140 00141 // returns true if the current jet definitions shares the same 00142 // recombiner as teh one passed as an argument 00143 bool JetDefinition::has_same_recombiner(const JetDefinition &other_jd) const{ 00144 // first make sure that they have the same recombination scheme 00145 const RecombinationScheme & scheme = recombination_scheme(); 00146 if (other_jd.recombination_scheme() != scheme) return false; 00147 00148 // if the scheme is "external", also check that they ahve the same 00149 // recombiner 00150 return (scheme != external_scheme) 00151 || (recombiner() == other_jd.recombiner()); 00152 } 00153 00154 string JetDefinition::DefaultRecombiner::description() const { 00155 switch(_recomb_scheme) { 00156 case E_scheme: 00157 return "E scheme recombination"; 00158 case pt_scheme: 00159 return "pt scheme recombination"; 00160 case pt2_scheme: 00161 return "pt2 scheme recombination"; 00162 case Et_scheme: 00163 return "Et scheme recombination"; 00164 case Et2_scheme: 00165 return "Et2 scheme recombination"; 00166 case BIpt_scheme: 00167 return "boost-invariant pt scheme recombination"; 00168 case BIpt2_scheme: 00169 return "boost-invariant pt2 scheme recombination"; 00170 default: 00171 ostringstream err; 00172 err << "DefaultRecombiner: unrecognized recombination scheme " 00173 << _recomb_scheme; 00174 throw Error(err.str()); 00175 } 00176 } 00177 00178 00179 void JetDefinition::DefaultRecombiner::recombine( 00180 const PseudoJet & pa, const PseudoJet & pb, 00181 PseudoJet & pab) const { 00182 00183 double weighta, weightb; 00184 00185 switch(_recomb_scheme) { 00186 case E_scheme: 00187 pab = pa + pb; 00188 return; 00189 // all remaining schemes are massless recombinations and locally 00190 // we just set weights, while the hard work is done below... 00191 case pt_scheme: 00192 case Et_scheme: 00193 case BIpt_scheme: 00194 weighta = pa.perp(); 00195 weightb = pb.perp(); 00196 break; 00197 case pt2_scheme: 00198 case Et2_scheme: 00199 case BIpt2_scheme: 00200 weighta = pa.perp2(); 00201 weightb = pb.perp2(); 00202 break; 00203 default: 00204 ostringstream err; 00205 err << "DefaultRecombiner: unrecognized recombination scheme " 00206 << _recomb_scheme; 00207 throw Error(err.str()); 00208 } 00209 00210 double perp_ab = pa.perp() + pb.perp(); 00211 if (perp_ab != 0.0) { // weights also non-zero... 00212 double y_ab = (weighta * pa.rap() + weightb * pb.rap())/(weighta+weightb); 00213 00214 // take care with periodicity in phi... 00215 double phi_a = pa.phi(), phi_b = pb.phi(); 00216 if (phi_a - phi_b > pi) phi_b += twopi; 00217 if (phi_a - phi_b < -pi) phi_b -= twopi; 00218 double phi_ab = (weighta * phi_a + weightb * phi_b)/(weighta+weightb); 00219 00220 pab = PseudoJet(perp_ab*cos(phi_ab), 00221 perp_ab*sin(phi_ab), 00222 perp_ab*sinh(y_ab), 00223 perp_ab*cosh(y_ab)); 00224 } else { // weights are zero 00225 pab = PseudoJet(0.0,0.0,0.0,0.0); 00226 } 00227 } 00228 00229 00230 void JetDefinition::DefaultRecombiner::preprocess(PseudoJet & p) const { 00231 switch(_recomb_scheme) { 00232 case E_scheme: 00233 case BIpt_scheme: 00234 case BIpt2_scheme: 00235 break; 00236 case pt_scheme: 00237 case pt2_scheme: 00238 { 00239 // these schemes (as in the ktjet implementation) need massless 00240 // initial 4-vectors with essentially E=|p|. 00241 double newE = sqrt(p.perp2()+p.pz()*p.pz()); 00242 int user_index = p.user_index(); 00243 p = PseudoJet(p.px(), p.py(), p.pz(), newE); 00244 p.set_user_index(user_index); 00245 } 00246 break; 00247 case Et_scheme: 00248 case Et2_scheme: 00249 { 00250 // these schemes (as in the ktjet implementation) need massless 00251 // initial 4-vectors with essentially E=|p|. 00252 double rescale = p.E()/sqrt(p.perp2()+p.pz()*p.pz()); 00253 int user_index = p.user_index(); 00254 p = PseudoJet(rescale*p.px(), rescale*p.py(), rescale*p.pz(), p.E()); 00255 p.set_user_index(user_index); 00256 } 00257 break; 00258 default: 00259 ostringstream err; 00260 err << "DefaultRecombiner: unrecognized recombination scheme " 00261 << _recomb_scheme; 00262 throw Error(err.str()); 00263 } 00264 } 00265 00266 void JetDefinition::Plugin::set_ghost_separation_scale(double scale) const { 00267 throw Error("set_ghost_separation_scale not supported"); 00268 } 00269 00270 00271 00272 //------------------------------------------------------------------------------- 00273 // helper functions to build a jet made of pieces 00274 // 00275 // This is the extended version with support for a user-defined 00276 // recombination-scheme 00277 // ------------------------------------------------------------------------------- 00278 00279 // build a "CompositeJet" from the vector of its pieces 00280 // 00281 // the user passes the reciombination scheme used to "sum" the pieces. 00282 PseudoJet join(const vector<PseudoJet> & pieces, const JetDefinition::Recombiner & recombiner){ 00283 // compute the total momentum 00284 //-------------------------------------------------- 00285 PseudoJet result; // automatically initialised to 0 00286 if (pieces.size()>0){ 00287 result = pieces[0]; 00288 for (unsigned int i=1; i<pieces.size(); i++) 00289 recombiner.plus_equal(result, pieces[i]); 00290 } 00291 00292 // attach a CompositeJetStructure to the result 00293 //-------------------------------------------------- 00294 CompositeJetStructure *cj_struct = new CompositeJetStructure(pieces, &recombiner); 00295 00296 result.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(cj_struct)); 00297 00298 return result; 00299 } 00300 00301 // build a "CompositeJet" from a single PseudoJet 00302 PseudoJet join(const PseudoJet & j1, 00303 const JetDefinition::Recombiner & recombiner){ 00304 return join(vector<PseudoJet>(1,j1), recombiner); 00305 } 00306 00307 // build a "CompositeJet" from two PseudoJet 00308 PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, 00309 const JetDefinition::Recombiner & recombiner){ 00310 vector<PseudoJet> pieces; 00311 pieces.push_back(j1); 00312 pieces.push_back(j2); 00313 return join(pieces, recombiner); 00314 } 00315 00316 // build a "CompositeJet" from 3 PseudoJet 00317 PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3, 00318 const JetDefinition::Recombiner & recombiner){ 00319 vector<PseudoJet> pieces; 00320 pieces.push_back(j1); 00321 pieces.push_back(j2); 00322 pieces.push_back(j3); 00323 return join(pieces, recombiner); 00324 } 00325 00326 // build a "CompositeJet" from 4 PseudoJet 00327 PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3, const PseudoJet & j4, 00328 const JetDefinition::Recombiner & recombiner){ 00329 vector<PseudoJet> pieces; 00330 pieces.push_back(j1); 00331 pieces.push_back(j2); 00332 pieces.push_back(j3); 00333 pieces.push_back(j4); 00334 return join(pieces, recombiner); 00335 } 00336 00337 00338 00339 00340 FASTJET_END_NAMESPACE
1.7.4