FastJets.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Rivet.hh" 00003 #include "Rivet/Tools/Logging.hh" 00004 #include "Rivet/Projections/FastJets.hh" 00005 00006 namespace Rivet { 00007 00008 00009 void FastJets::_init1(JetAlgName alg, double rparameter, double seed_threshold) { 00010 setName("FastJets"); 00011 MSG_DEBUG("R parameter = " << rparameter); 00012 MSG_DEBUG("Seed threshold = " << seed_threshold); 00013 if (alg == KT) { 00014 _jdef = fastjet::JetDefinition(fastjet::kt_algorithm, rparameter, fastjet::E_scheme); 00015 } else if (alg == CAM) { 00016 _jdef = fastjet::JetDefinition(fastjet::cambridge_algorithm, rparameter, fastjet::E_scheme); 00017 } else if (alg == ANTIKT) { 00018 _jdef = fastjet::JetDefinition(fastjet::antikt_algorithm, rparameter, fastjet::E_scheme); 00019 } else if (alg == DURHAM) { 00020 _jdef = fastjet::JetDefinition(fastjet::ee_kt_algorithm, fastjet::E_scheme); 00021 } else { 00022 // Plugins: 00023 if (alg == SISCONE) { 00024 const double OVERLAP_THRESHOLD = 0.75; 00025 _plugin.reset(new fastjet::SISConePlugin(rparameter, OVERLAP_THRESHOLD)); 00026 } else if (alg == PXCONE) { 00027 string msg = "PxCone currently not supported, since FastJet doesn't install it by default. "; 00028 msg += "Please notify the Rivet authors if this behaviour should be changed."; 00029 throw Error(msg); 00030 //_plugin.reset(new fastjet::PxConePlugin(rparameter)); 00031 } else if (alg == ATLASCONE) { 00032 const double OVERLAP_THRESHOLD = 0.5; 00033 _plugin.reset(new fastjet::ATLASConePlugin(rparameter, seed_threshold, OVERLAP_THRESHOLD)); 00034 } else if (alg == CMSCONE) { 00035 _plugin.reset(new fastjet::CMSIterativeConePlugin(rparameter, seed_threshold)); 00036 } else if (alg == CDFJETCLU) { 00037 const double OVERLAP_THRESHOLD = 0.75; 00038 _plugin.reset(new fastjet::CDFJetCluPlugin(rparameter, OVERLAP_THRESHOLD, seed_threshold)); 00039 } else if (alg == CDFMIDPOINT) { 00040 const double OVERLAP_THRESHOLD = 0.5; 00041 _plugin.reset(new fastjet::CDFMidPointPlugin(rparameter, OVERLAP_THRESHOLD, seed_threshold)); 00042 } else if (alg == D0ILCONE) { 00043 const double min_jet_Et = 6.0; 00044 _plugin.reset(new fastjet::D0RunIIConePlugin(rparameter, min_jet_Et)); 00045 } else if (alg == JADE) { 00046 _plugin.reset(new fastjet::JadePlugin()); 00047 } else if (alg == TRACKJET) { 00048 _plugin.reset(new fastjet::TrackJetPlugin(rparameter)); 00049 } 00050 _jdef = fastjet::JetDefinition(_plugin.get()); 00051 } 00052 } 00053 00054 void FastJets::_init2(fastjet::JetAlgorithm type, 00055 fastjet::RecombinationScheme recom, double rparameter) { 00056 setName("FastJets"); 00057 _jdef = fastjet::JetDefinition(type, rparameter, recom); 00058 } 00059 00060 void FastJets::_init3(fastjet::JetDefinition::Plugin* plugin) { 00061 setName("FastJets"); 00062 /// @todo Should we be copying the plugin? 00063 _plugin.reset(plugin); 00064 _jdef = fastjet::JetDefinition(_plugin.get()); 00065 } 00066 00067 00068 00069 int FastJets::compare(const Projection& p) const { 00070 const FastJets& other = dynamic_cast<const FastJets&>(p); 00071 return \ 00072 (_useInvisibles ? mkNamedPCmp(other, "FS") : mkNamedPCmp(other, "VFS")) || 00073 cmp(_jdef.jet_algorithm(), other._jdef.jet_algorithm()) || 00074 cmp(_jdef.recombination_scheme(), other._jdef.recombination_scheme()) || 00075 cmp(_jdef.plugin(), other._jdef.plugin()) || 00076 cmp(_jdef.R(), other._jdef.R()) || 00077 cmp(_adef, other._adef); 00078 } 00079 00080 00081 00082 void FastJets::project(const Event& e) { 00083 ParticleVector particles; 00084 if (_useInvisibles) { 00085 particles = applyProjection<FinalState>(e, "FS").particles(); 00086 } else { 00087 particles = applyProjection<FinalState>(e, "VFS").particles(); 00088 } 00089 calc(particles); 00090 } 00091 00092 00093 void FastJets::calc(const ParticleVector& ps) { 00094 _particles.clear(); 00095 vector<fastjet::PseudoJet> vecs; 00096 // Store 4 vector data about each particle into vecs 00097 int counter = 1; 00098 foreach (const Particle& p, ps) { 00099 const FourMomentum fv = p.momentum(); 00100 fastjet::PseudoJet pJet(fv.px(), fv.py(), fv.pz(), fv.E()); 00101 pJet.set_user_index(counter); 00102 vecs.push_back(pJet); 00103 _particles[counter] = p; 00104 ++counter; 00105 } 00106 MSG_DEBUG("Running FastJet ClusterSequence construction"); 00107 00108 // Choose CSeq as basic or area-calculating depending on whether _adef pointer is non-null. 00109 if (_adef == 0) { 00110 _cseq.reset(new fastjet::ClusterSequence(vecs, _jdef)); 00111 } else { 00112 _cseq.reset(new fastjet::ClusterSequenceArea(vecs, _jdef, *_adef)); 00113 } 00114 } 00115 00116 00117 Jets FastJets::_pseudojetsToJets(const PseudoJets& pjets) const { 00118 Jets rtn; 00119 foreach (const fastjet::PseudoJet& pj, pjets) { 00120 assert(clusterSeq()); 00121 const PseudoJets parts = clusterSeq()->constituents(pj); 00122 vector<Particle> constituents; 00123 constituents.reserve(parts.size()); 00124 foreach (const fastjet::PseudoJet& p, parts) { 00125 map<int, Particle>::const_iterator found = _particles.find(p.user_index()); 00126 assert(found != _particles.end()); 00127 constituents.push_back(found->second); 00128 } 00129 FourMomentum pjet(pj.E(), pj.px(), pj.py(), pj.pz()); 00130 Jet j(constituents, pjet); 00131 rtn.push_back(j); 00132 } 00133 /// @todo Cache? 00134 return rtn; 00135 } 00136 00137 00138 void FastJets::reset() { 00139 _yscales.clear(); 00140 _particles.clear(); 00141 /// @todo _cseq = fastjet::ClusterSequence(); 00142 } 00143 00144 00145 size_t FastJets::numJets(double ptmin) const { 00146 if (_cseq.get() != 0) { 00147 return _cseq->inclusive_jets(ptmin).size(); 00148 } else { 00149 return 0; 00150 } 00151 } 00152 00153 00154 Jets FastJets::_jets(double ptmin) const { 00155 Jets rtn = _pseudojetsToJets(pseudoJets(ptmin)); 00156 return rtn; 00157 } 00158 00159 00160 // Jets FastJets::jetsByPt(double ptmin) const { 00161 // return _pseudojetsToJets(pseudoJetsByPt(ptmin)); 00162 // } 00163 00164 00165 // Jets FastJets::jetsByE(double ptmin) const { 00166 // return _pseudojetsToJets(pseudoJetsByE(ptmin)); 00167 // } 00168 00169 00170 // Jets FastJets::jetsByRapidity(double ptmin) const { 00171 // return _pseudojetsToJets(pseudoJetsByRapidity(ptmin)); 00172 // } 00173 00174 00175 PseudoJets FastJets::pseudoJets(double ptmin) const { 00176 if (_cseq.get() != 0) { 00177 return _cseq->inclusive_jets(ptmin); 00178 } else { 00179 return PseudoJets(); 00180 } 00181 } 00182 00183 00184 vector<double> FastJets::ySubJet(const fastjet::PseudoJet& jet) const { 00185 assert(clusterSeq()); 00186 fastjet::ClusterSequence subjet_cseq(clusterSeq()->constituents(jet), _jdef); 00187 vector<double> yMergeVals; 00188 for (int i = 1; i < 4; ++i) { 00189 // Multiply the dmerge value by R^2 so that it corresponds to a 00190 // relative k_T (fastjet has 1/R^2 in the d_ij distance by default) 00191 const double ktmerge = subjet_cseq.exclusive_dmerge(i) * _jdef.R()*_jdef.R(); 00192 yMergeVals.push_back(ktmerge/jet.perp2()); 00193 } 00194 _yscales.insert(make_pair( jet.cluster_hist_index(), yMergeVals )); 00195 return yMergeVals; 00196 } 00197 00198 00199 00200 fastjet::PseudoJet FastJets::splitJet(fastjet::PseudoJet jet, double& last_R) const { 00201 // Sanity cuts 00202 if (jet.E() <= 0 || _cseq->constituents(jet).size() <= 1) { 00203 return jet; 00204 } 00205 00206 // Build a new cluster sequence just using the consituents of this jet. 00207 assert(clusterSeq()); 00208 fastjet::ClusterSequence cs(clusterSeq()->constituents(jet), _jdef); 00209 00210 // Get the jet back again 00211 fastjet::PseudoJet remadeJet = cs.inclusive_jets()[0]; 00212 MSG_DEBUG("Jet2:" << remadeJet.m() << "," << remadeJet.e()); 00213 00214 fastjet::PseudoJet parent1, parent2; 00215 fastjet::PseudoJet split(0.0, 0.0, 0.0, 0.0); 00216 while (cs.has_parents(remadeJet, parent1, parent2)) { 00217 MSG_DEBUG("Parents:" << parent1.m() << "," << parent2.m()); 00218 if (parent1.m2() < parent2.m2()) { 00219 fastjet::PseudoJet tmp; 00220 tmp = parent1; parent1 = parent2; parent2 = tmp; 00221 } 00222 00223 double ktdist = parent1.kt_distance(parent2); 00224 double rtycut2 = 0.3*0.3; 00225 if (parent1.m() < ((2.0*remadeJet.m())/3.0) && ktdist > rtycut2*remadeJet.m2()) { 00226 break; 00227 } else { 00228 remadeJet = parent1; 00229 } 00230 } 00231 00232 last_R = 0.5 * sqrt(parent1.squared_distance(parent2)); 00233 split.reset(remadeJet.px(), remadeJet.py(), remadeJet.pz(), remadeJet.E()); 00234 return split; 00235 } 00236 00237 00238 00239 fastjet::PseudoJet FastJets::filterJet(fastjet::PseudoJet jet, 00240 double& stingy_R, const double def_R) const { 00241 assert(clusterSeq()); 00242 00243 if (jet.E() <= 0.0 || clusterSeq()->constituents(jet).size() == 0) { 00244 return jet; 00245 } 00246 if (stingy_R == 0.0) { 00247 stingy_R = def_R; 00248 } 00249 00250 stingy_R = def_R < stingy_R ? def_R : stingy_R; 00251 fastjet::JetDefinition stingy_jet_def(fastjet::cambridge_algorithm, stingy_R); 00252 00253 //FlavourRecombiner recom; 00254 //stingy_jet_def.set_recombiner(&recom); 00255 fastjet::ClusterSequence scs(clusterSeq()->constituents(jet), stingy_jet_def); 00256 std::vector<fastjet::PseudoJet> stingy_jets = sorted_by_pt(scs.inclusive_jets()); 00257 00258 fastjet::PseudoJet reconst_jet(0.0, 0.0, 0.0, 0.0); 00259 00260 for (unsigned isj = 0; isj < std::min(3U, (unsigned int) stingy_jets.size()); ++isj) { 00261 reconst_jet += stingy_jets[isj]; 00262 } 00263 return reconst_jet; 00264 } 00265 00266 00267 } Generated on Fri Dec 21 2012 15:03:40 for The Rivet MC analysis system by ![]() |