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   FastJets::FastJets(const FinalState& fsp, JetAlgName alg, double rparameter, double seed_threshold)
00010     : JetAlg(fsp), _adef(0)
00011   {
00012     _init1(alg, rparameter, seed_threshold);
00013   }
00014 
00015   FastJets::FastJets(const FinalState& fsp, fastjet::JetAlgorithm type,
00016                      fastjet::RecombinationScheme recom, double rparameter)
00017     : JetAlg(fsp), _adef(0)
00018   {
00019     _init2(type, recom, rparameter);
00020   }
00021 
00022 
00023   FastJets::FastJets(const FinalState& fsp,
00024                      fastjet::JetDefinition::Plugin& plugin)
00025     : JetAlg(fsp), _adef(0)
00026   {
00027     _init3(plugin);
00028   }
00029 
00030 
00031   FastJets::FastJets(JetAlgName alg, double rparameter, double seed_threshold)
00032     : _adef(0)
00033   {
00034     _init1(alg, rparameter, seed_threshold);
00035   }
00036 
00037   FastJets::FastJets(fastjet::JetAlgorithm type,
00038                      fastjet::RecombinationScheme recom, double rparameter)
00039     : _adef(0)
00040   {
00041     _init2(type, recom, rparameter);
00042   }
00043 
00044 
00045   FastJets::FastJets(fastjet::JetDefinition::Plugin& plugin)
00046     : _adef(0)
00047   {
00048     _init3(plugin);
00049   }
00050 
00051 
00052   int FastJets::compare(const Projection& p) const {
00053     const FastJets& other = dynamic_cast<const FastJets&>(p);
00054     // cout << "CMP " << _useInvisibles << endl;
00055     return \
00056       (_useInvisibles ? mkNamedPCmp(other, "FS") : mkNamedPCmp(other, "VFS")) ||
00057       cmp(_jdef.jet_algorithm(), other._jdef.jet_algorithm()) ||
00058       cmp(_jdef.recombination_scheme(), other._jdef.recombination_scheme()) ||
00059       cmp(_jdef.plugin(), other._jdef.plugin()) ||
00060       cmp(_jdef.R(), other._jdef.R()) ||
00061       cmp(_adef, other._adef);
00062   }
00063 
00064 
00065 
00066   void FastJets::project(const Event& e) {
00067     ParticleVector particles;
00068     if (_useInvisibles) {
00069       particles = applyProjection<FinalState>(e, "FS").particles();
00070     } else {
00071       particles = applyProjection<FinalState>(e, "VFS").particles();
00072     }
00073     calc(particles);
00074   }
00075 
00076 
00077   void FastJets::calc(const ParticleVector& ps) {
00078     _particles.clear();
00079     vector<fastjet::PseudoJet> vecs;
00080     // Store 4 vector data about each particle into vecs
00081     int counter = 1;
00082     foreach (const Particle& p, ps) {
00083       const FourMomentum fv = p.momentum();
00084       fastjet::PseudoJet pJet(fv.px(), fv.py(), fv.pz(), fv.E());
00085       pJet.set_user_index(counter);
00086       vecs.push_back(pJet);
00087       _particles[counter] = p;
00088       ++counter;
00089     }
00090     MSG_DEBUG("Running FastJet ClusterSequence construction");
00091 
00092     // Choose CSeq as basic or area-calculating depending on whether _adef pointer is non-null.
00093     if (_adef == 0) {
00094       _cseq.reset(new fastjet::ClusterSequence(vecs, _jdef));
00095     } else {
00096       _cseq.reset(new fastjet::ClusterSequenceArea(vecs, _jdef, *_adef));
00097     }
00098   }
00099 
00100 
00101   Jets FastJets::_pseudojetsToJets(const PseudoJets& pjets) const {
00102     Jets rtn;
00103     foreach (const fastjet::PseudoJet& pj, pjets) {
00104       Jet j;
00105       assert(clusterSeq());
00106       const PseudoJets parts = clusterSeq()->constituents(pj);
00107       foreach (const fastjet::PseudoJet& p, parts) {
00108         map<int, Particle>::const_iterator found = _particles.find(p.user_index());
00109         assert(found != _particles.end());
00110         j.addParticle(found->second);
00111       }
00112       rtn.push_back(j);
00113     }
00114     return rtn;
00115   }
00116 
00117 
00118   void FastJets::reset() {
00119     _yscales.clear();
00120     _particles.clear();
00121     /// @todo _cseq = fastjet::ClusterSequence();
00122   }
00123 
00124 
00125   size_t FastJets::numJets(double ptmin) const {
00126     if (_cseq.get() != 0) {
00127       return _cseq->inclusive_jets(ptmin).size();
00128     } else {
00129       return 0;
00130     }
00131   }
00132 
00133 
00134   Jets FastJets::_jets(double ptmin) const {
00135     Jets rtn = _pseudojetsToJets(pseudoJets(ptmin));
00136     return rtn;
00137   }
00138 
00139 
00140   // Jets FastJets::jetsByPt(double ptmin) const {
00141   //   return _pseudojetsToJets(pseudoJetsByPt(ptmin));
00142   // }
00143 
00144 
00145   // Jets FastJets::jetsByE(double ptmin) const {
00146   //   return _pseudojetsToJets(pseudoJetsByE(ptmin));
00147   // }
00148 
00149 
00150   // Jets FastJets::jetsByRapidity(double ptmin) const {
00151   //   return _pseudojetsToJets(pseudoJetsByRapidity(ptmin));
00152   // }
00153 
00154 
00155   PseudoJets FastJets::pseudoJets(double ptmin) const {
00156     if (_cseq.get() != 0) {
00157       return _cseq->inclusive_jets(ptmin);
00158     } else {
00159       return PseudoJets();
00160     }
00161   }
00162 
00163 
00164   vector<double> FastJets::ySubJet(const fastjet::PseudoJet& jet) const {
00165     assert(clusterSeq());
00166     fastjet::ClusterSequence subjet_cseq(clusterSeq()->constituents(jet), _jdef);
00167     vector<double> yMergeVals;
00168     for (int i = 1; i < 4; ++i) {
00169       // Multiply the dmerge value by R^2 so that it corresponds to a
00170       // relative k_T (fastjet has 1/R^2 in the d_ij distance by default)
00171       const double ktmerge = subjet_cseq.exclusive_dmerge(i) * _jdef.R()*_jdef.R();
00172       yMergeVals.push_back(ktmerge/jet.perp2());
00173     }
00174     _yscales.insert(make_pair( jet.cluster_hist_index(), yMergeVals ));
00175     return yMergeVals;
00176   }
00177 
00178 
00179 
00180   fastjet::PseudoJet FastJets::splitJet(fastjet::PseudoJet jet, double& last_R) const {
00181     // Sanity cuts
00182     if (jet.E() <= 0 || _cseq->constituents(jet).size() <= 1) {
00183       return jet;
00184     }
00185 
00186     // Build a new cluster sequence just using the consituents of this jet.
00187     assert(clusterSeq());
00188     fastjet::ClusterSequence cs(clusterSeq()->constituents(jet), _jdef);
00189 
00190     // Get the jet back again
00191     fastjet::PseudoJet remadeJet = cs.inclusive_jets()[0];
00192     MSG_DEBUG("Jet2:" << remadeJet.m() << "," << remadeJet.e());
00193 
00194     fastjet::PseudoJet parent1, parent2;
00195     fastjet::PseudoJet split(0.0, 0.0, 0.0, 0.0);
00196     while (cs.has_parents(remadeJet, parent1, parent2)) {
00197       MSG_DEBUG("Parents:" << parent1.m() << "," << parent2.m());
00198       if (parent1.m2() < parent2.m2()) {
00199         fastjet::PseudoJet tmp;
00200         tmp = parent1; parent1 = parent2; parent2 = tmp;
00201       }
00202 
00203       double ktdist = parent1.kt_distance(parent2);
00204       double rtycut2 = 0.3*0.3;
00205       if (parent1.m() < ((2.0*remadeJet.m())/3.0) && ktdist > rtycut2*remadeJet.m2()) {
00206         break;
00207       } else {
00208         remadeJet = parent1;
00209       }
00210     }
00211 
00212     last_R = 0.5 * sqrt(parent1.squared_distance(parent2));
00213     split.reset(remadeJet.px(), remadeJet.py(), remadeJet.pz(), remadeJet.E());
00214     return split;
00215   }
00216 
00217 
00218 
00219   fastjet::PseudoJet FastJets::filterJet(fastjet::PseudoJet jet,
00220                                          double& stingy_R, const double def_R) const {
00221     assert(clusterSeq());
00222 
00223     if (jet.E() <= 0.0 || clusterSeq()->constituents(jet).size() == 0) {
00224       return jet;
00225     }
00226     if (stingy_R == 0.0) {
00227       stingy_R = def_R;
00228     }
00229 
00230     stingy_R = def_R < stingy_R ? def_R : stingy_R;
00231     fastjet::JetDefinition stingy_jet_def(fastjet::cambridge_algorithm, stingy_R);
00232 
00233     //FlavourRecombiner recom;
00234     //stingy_jet_def.set_recombiner(&recom);
00235     fastjet::ClusterSequence scs(clusterSeq()->constituents(jet), stingy_jet_def);
00236     std::vector<fastjet::PseudoJet> stingy_jets = sorted_by_pt(scs.inclusive_jets());
00237 
00238     fastjet::PseudoJet reconst_jet(0.0, 0.0, 0.0, 0.0);
00239 
00240     for (unsigned isj = 0; isj < std::min(3U, (unsigned int) stingy_jets.size()); ++isj) {
00241       reconst_jet += stingy_jets[isj];
00242     }
00243     return reconst_jet;
00244   }
00245 
00246 }