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