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 00018 // void FastJets::_init1(JetAlgName alg, double rparameter, double seed_threshold) { 00019 // _initBase(); 00020 00021 00022 void FastJets::_initJdef(JetAlgName alg, double rparameter, double seed_threshold) { 00023 MSG_DEBUG("JetAlg = " << alg); 00024 MSG_DEBUG("R parameter = " << rparameter); 00025 MSG_DEBUG("Seed threshold = " << seed_threshold); 00026 if (alg == KT) { 00027 _jdef = fastjet::JetDefinition(fastjet::kt_algorithm, rparameter, fastjet::E_scheme); 00028 } else if (alg == CAM) { 00029 _jdef = fastjet::JetDefinition(fastjet::cambridge_algorithm, rparameter, fastjet::E_scheme); 00030 } else if (alg == ANTIKT) { 00031 _jdef = fastjet::JetDefinition(fastjet::antikt_algorithm, rparameter, fastjet::E_scheme); 00032 } else if (alg == DURHAM) { 00033 _jdef = fastjet::JetDefinition(fastjet::ee_kt_algorithm, fastjet::E_scheme); 00034 } else { 00035 // Plugins: 00036 if (alg == SISCONE) { 00037 const double OVERLAP_THRESHOLD = 0.75; 00038 _plugin.reset(new fastjet::SISConePlugin(rparameter, OVERLAP_THRESHOLD)); 00039 // } else if (alg == PXCONE) { 00040 // string msg = "PxCone currently not supported, since FastJet doesn't install it by default. "; 00041 // msg += "Please notify the Rivet authors if this behaviour should be changed."; 00042 // throw Error(msg); 00043 // _plugin.reset(new fastjet::PxConePlugin(rparameter)); 00044 } else if (alg == ATLASCONE) { 00045 const double OVERLAP_THRESHOLD = 0.5; 00046 _plugin.reset(new fastjet::ATLASConePlugin(rparameter, seed_threshold, OVERLAP_THRESHOLD)); 00047 } else if (alg == CMSCONE) { 00048 _plugin.reset(new fastjet::CMSIterativeConePlugin(rparameter, seed_threshold)); 00049 } else if (alg == CDFJETCLU) { 00050 const double OVERLAP_THRESHOLD = 0.75; 00051 _plugin.reset(new fastjet::CDFJetCluPlugin(rparameter, OVERLAP_THRESHOLD, seed_threshold)); 00052 } else if (alg == CDFMIDPOINT) { 00053 const double OVERLAP_THRESHOLD = 0.5; 00054 _plugin.reset(new fastjet::CDFMidPointPlugin(rparameter, OVERLAP_THRESHOLD, seed_threshold)); 00055 } else if (alg == D0ILCONE) { 00056 const double min_jet_Et = 6.0; 00057 _plugin.reset(new fastjet::D0RunIIConePlugin(rparameter, min_jet_Et)); 00058 } else if (alg == JADE) { 00059 _plugin.reset(new fastjet::JadePlugin()); 00060 } else if (alg == TRACKJET) { 00061 _plugin.reset(new fastjet::TrackJetPlugin(rparameter)); 00062 } 00063 _jdef = fastjet::JetDefinition(_plugin.get()); 00064 } 00065 } 00066 00067 00068 // void FastJets::_init2(fastjet::JetAlgorithm type, 00069 // fastjet::RecombinationScheme recom, double rparameter) 00070 // : FastJets 00071 // { 00072 00073 // _initBase(); 00074 // _jdef = fastjet::JetDefinition(type, rparameter, recom); 00075 // } 00076 00077 00078 // void FastJets::_init3(const fastjet::JetDefinition& jdef) { 00079 // _initBase(); 00080 // _jdef = jdef; 00081 // } 00082 00083 00084 // void FastJets::_init4(fastjet::JetDefinition::Plugin* plugin) { 00085 // _initBase(); 00086 // _plugin.reset(plugin); 00087 // _jdef = fastjet::JetDefinition(_plugin.get()); 00088 // } 00089 00090 00091 00092 int FastJets::compare(const Projection& p) const { 00093 const FastJets& other = dynamic_cast<const FastJets&>(p); 00094 return \ 00095 cmp(_useMuons, other._useMuons) || 00096 cmp(_useInvisibles, other._useInvisibles) || 00097 mkNamedPCmp(other, "FS") || 00098 cmp(_jdef.jet_algorithm(), other._jdef.jet_algorithm()) || 00099 cmp(_jdef.recombination_scheme(), other._jdef.recombination_scheme()) || 00100 cmp(_jdef.plugin(), other._jdef.plugin()) || 00101 cmp(_jdef.R(), other._jdef.R()) || 00102 cmp(_adef, other._adef); 00103 } 00104 00105 00106 namespace { 00107 /// @todo Replace with C++11 lambdas 00108 bool isPromptInvisible(const Particle& p) { return !(p.isVisible() || p.fromDecay()); } 00109 // bool isMuon(const Particle& p) { return p.abspid() == PID::MUON; } 00110 bool isPromptMuon(const Particle& p) { return isMuon(p) && !p.fromDecay(); } 00111 } 00112 00113 00114 void FastJets::project(const Event& e) { 00115 // Assemble final state particles 00116 const string fskey = (_useInvisibles == JetAlg::NO_INVISIBLES) ? "VFS" : "FS"; 00117 Particles fsparticles = applyProjection<FinalState>(e, fskey).particles(); 00118 // Remove prompt invisibles if needed (already done by VFS if using NO_INVISIBLES) 00119 if (_useInvisibles == JetAlg::DECAY_INVISIBLES) 00120 fsparticles.erase( std::remove_if(fsparticles.begin(), fsparticles.end(), isPromptInvisible), fsparticles.end() ); 00121 // Remove prompt/all muons if needed 00122 if (_useMuons == JetAlg::DECAY_MUONS) 00123 fsparticles.erase( std::remove_if(fsparticles.begin(), fsparticles.end(), isPromptMuon), fsparticles.end() ); 00124 else if (_useMuons == JetAlg::NO_MUONS) 00125 fsparticles.erase( std::remove_if(fsparticles.begin(), fsparticles.end(), isMuon), fsparticles.end() ); 00126 00127 // Tagging particles 00128 /// @todo Allow the user to specify tag particle kinematic thresholds 00129 const Particles chadrons = applyProjection<HeavyHadrons>(e, "HFHadrons").cHadrons(); 00130 const Particles bhadrons = applyProjection<HeavyHadrons>(e, "HFHadrons").bHadrons(); 00131 const Particles taus = applyProjection<FinalState>(e, "Taus").particles(); 00132 calc(fsparticles, chadrons+bhadrons+taus); 00133 } 00134 00135 00136 void FastJets::calc(const Particles& fsparticles, const Particles& tagparticles) { 00137 _particles.clear(); 00138 vector<fastjet::PseudoJet> pjs; 00139 00140 MSG_DEBUG("Finding jets from " << fsparticles.size() << " input particles"); 00141 00142 /// @todo Use FastJet3's UserInfo system 00143 00144 // Store 4 vector data about each particle into FastJet's PseudoJets 00145 int counter = 1; 00146 for (const Particle& p : fsparticles) { 00147 fastjet::PseudoJet pj = p; 00148 pj.set_user_index(counter); 00149 pjs.push_back(pj); 00150 _particles[counter] = p; 00151 counter += 1; 00152 } 00153 // And the same for ghost tagging particles (with negative user indices) 00154 counter = 1; 00155 for (const Particle& p : tagparticles) { 00156 fastjet::PseudoJet pj = p; 00157 pj *= 1e-20; ///< Ghostify the momentum 00158 pj.set_user_index(-counter); 00159 pjs.push_back(pj); 00160 _particles[-counter] = p; 00161 counter += 1; 00162 } 00163 00164 // Choose cseq as basic or area-calculating 00165 if (_adef) { 00166 _cseq.reset(new fastjet::ClusterSequenceArea(pjs, _jdef, *_adef)); 00167 } else { 00168 _cseq.reset(new fastjet::ClusterSequence(pjs, _jdef)); 00169 } 00170 MSG_DEBUG("FastJet ClusterSequence constructed; Njets_tot = " 00171 << _cseq->inclusive_jets().size() << ", Njets_10 = " 00172 << _cseq->inclusive_jets(10*GeV).size()); //< only inefficient in debug mode 00173 } 00174 00175 00176 void FastJets::reset() { 00177 _yscales.clear(); 00178 _particles.clear(); 00179 /// @todo _cseq = fastjet::ClusterSequence(); 00180 } 00181 00182 00183 Jets FastJets::_jets() const { 00184 Jets rtn; rtn.reserve(pseudojets().size()); 00185 foreach (const fastjet::PseudoJet& pj, pseudojets()) { 00186 rtn.push_back(_mkJet(pj)); 00187 } 00188 /// @todo Cache? 00189 return rtn; 00190 } 00191 00192 00193 Jet FastJets::trimJet(const Jet &input, const fastjet::Filter &trimmer)const{ 00194 assert(input.pseudojet().associated_cluster_sequence() == clusterSeq().get()); 00195 PseudoJet pj = trimmer(input); 00196 return _mkJet(pj); 00197 } 00198 00199 00200 PseudoJets FastJets::pseudoJets(double ptmin) const { 00201 return clusterSeq() ? clusterSeq()->inclusive_jets(ptmin) : PseudoJets(); 00202 } 00203 00204 00205 Jet FastJets::_mkJet(const PseudoJet &pj)const{ 00206 assert(clusterSeq()); 00207 00208 // Take the constituents from the cluster sequence, unless the jet was not 00209 // associated with the cluster sequence (could be the case for trimmed jets) 00210 const PseudoJets parts = (pj.associated_cluster_sequence() == clusterSeq().get()) 00211 ? clusterSeq()->constituents(pj) : pj.constituents(); 00212 00213 vector<Particle> constituents, tags; 00214 constituents.reserve(parts.size()); 00215 for (const fastjet::PseudoJet& p : parts) { 00216 map<int, Particle>::const_iterator found = _particles.find(p.user_index()); 00217 // assert(found != _particles.end()); 00218 if (found == _particles.end() && p.is_pure_ghost()) continue; //< Pure FJ ghosts are ok 00219 assert(found != _particles.end()); //< Anything else must be known 00220 assert(found->first != 0); //< All mapping IDs are pos-def (particles) or neg-def (tags) 00221 if (found->first > 0) constituents.push_back(found->second); 00222 else if (found->first < 0) tags.push_back(found->second); 00223 } 00224 00225 return Jet(pj, constituents, tags); 00226 } 00227 00228 00229 } Generated on Tue Dec 13 2016 16:32:37 for The Rivet MC analysis system by ![]() |