FastJets.hh

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_FastJets_HH
00003 #define RIVET_FastJets_HH
00004 
00005 #include "Rivet/Projection.hh"
00006 #include "Rivet/Projections/JetAlg.hh"
00007 #include "Rivet/Projections/FinalState.hh"
00008 #include "Rivet/Particle.hh"
00009 #include "Rivet/Jet.hh"
00010 
00011 #include "fastjet/JetDefinition.hh"
00012 #include "fastjet/AreaDefinition.hh"
00013 #include "fastjet/ClusterSequence.hh"
00014 #include "fastjet/ClusterSequenceArea.hh"
00015 #include "fastjet/PseudoJet.hh"
00016 
00017 #include "fastjet/SISConePlugin.hh"
00018 #include "fastjet/ATLASConePlugin.hh"
00019 #include "fastjet/CMSIterativeConePlugin.hh"
00020 #include "fastjet/CDFJetCluPlugin.hh"
00021 #include "fastjet/CDFMidPointPlugin.hh"
00022 #include "fastjet/D0RunIIConePlugin.hh"
00023 #include "fastjet/TrackJetPlugin.hh"
00024 #include "fastjet/JadePlugin.hh"
00025 //#include "fastjet/PxConePlugin.hh"
00026 
00027 namespace Rivet {
00028 
00029 
00030   /// Make a 3-momentum vector from a FastJet pseudo-jet
00031   inline Vector3 momentum3(const fastjet::PseudoJet& pj) {
00032     return Vector3(pj.px(), pj.py(), pj.pz());
00033   }
00034 
00035   /// Make a 4-momentum vector from a FastJet pseudo-jet
00036   inline FourMomentum momentum(const fastjet::PseudoJet& pj) {
00037     return FourMomentum(pj.E(), pj.px(), pj.py(), pj.pz());
00038   }
00039 
00040 
00041   /// Typedef for a collection of PseudoJets.
00042   typedef vector<fastjet::PseudoJet> PseudoJets;
00043 
00044 
00045 
00046   /////////////////////////
00047 
00048 
00049 
00050   /// Project out jets found using the FastJet package jet algorithms.
00051   class FastJets : public JetAlg {
00052 
00053   public:
00054     /// Wrapper enum for selected Fastjet jet algorithms.
00055     enum JetAlgName { KT, CAM, SISCONE, ANTIKT,
00056                       PXCONE,
00057                       ATLASCONE, CMSCONE,
00058                       CDFJETCLU, CDFMIDPOINT, D0ILCONE,
00059                       JADE, DURHAM, TRACKJET };
00060 
00061 
00062     /// @name Constructors etc.
00063     //@{
00064 
00065     /// "Wrapped" argument constructor using Rivet enums for most common
00066     /// jet alg choices (including some plugins). For the built-in algs,
00067     /// E-scheme recombination is used. For full control of
00068     /// FastJet built-in jet algs, use the native arg constructor.
00069     FastJets(const FinalState& fsp, JetAlgName alg,
00070              double rparameter, double seed_threshold=1.0);
00071 
00072     /// Native argument constructor, using FastJet alg/scheme enums.
00073     FastJets(const FinalState& fsp, fastjet::JetAlgorithm type,
00074              fastjet::RecombinationScheme recom, double rparameter);
00075 
00076     /// Explicitly pass in an externally-constructed plugin
00077     FastJets(const FinalState& fsp, fastjet::JetDefinition::Plugin& plugin);
00078 
00079     /// Same thing as above, but we want to pass the particles directly to the calc method
00080     FastJets(JetAlgName alg, double rparameter, double seed_threshold=1.0);
00081     FastJets(fastjet::JetAlgorithm type, fastjet::RecombinationScheme recom, double rparameter);
00082     FastJets(fastjet::JetDefinition::Plugin& plugin);
00083 
00084     // /// Explicit copy constructor.
00085     // FastJets(const FastJets& other);
00086 
00087     /// Clone on the heap.
00088     virtual const Projection* clone() const {
00089       return new FastJets(*this);
00090     }
00091 
00092     //@}
00093 
00094 
00095   public:
00096 
00097     /// Reset the projection. Jet def, etc. are unchanged.
00098     void reset();
00099 
00100     /// @brief Use provided jet area definition
00101     /// @warning adef is NOT copied, the user must ensure that it remains valid!
00102     /// Provide an adef null pointer to re-disable jet area calculation
00103     void useJetArea(fastjet::AreaDefinition* adef) {
00104       _adef = adef;
00105     }
00106 
00107     /// Number of jets above the \f$ p_\perp \f$ cut.
00108     size_t numJets(double ptmin = 0.0) const;
00109 
00110     /// Number of jets.
00111     size_t size() const {
00112       return numJets();
00113     }
00114 
00115     /// Get the jets (unordered).
00116     Jets _jets(double ptmin = 0.0) const;
00117 
00118     /// Get the pseudo jets (unordered).
00119     PseudoJets pseudoJets(double ptmin = 0.0) const;
00120 
00121     /// Get the pseudo jets, ordered by \f$ p_T \f$.
00122     PseudoJets pseudoJetsByPt(double ptmin = 0.0) const {
00123       return sorted_by_pt(pseudoJets(ptmin));
00124     }
00125 
00126     /// Get the pseudo jets, ordered by \f$ E \f$.
00127     PseudoJets pseudoJetsByE(double ptmin = 0.0) const {
00128       return sorted_by_E(pseudoJets(ptmin));
00129     }
00130 
00131     /// Get the pseudo jets, ordered by rapidity.
00132     PseudoJets pseudoJetsByRapidity(double ptmin = 0.0) const {
00133       return sorted_by_rapidity(pseudoJets(ptmin));
00134     }
00135 
00136     /// Return the cluster sequence (FastJet-specific).
00137     const fastjet::ClusterSequence* clusterSeq() const {
00138       return _cseq.get();
00139     }
00140 
00141     /// Return the cluster sequence (FastJet-specific).
00142     const fastjet::ClusterSequenceArea* clusterSeqArea() const {
00143       /// @todo Throw error if no area def? Or just blindly call dynamic_cast?
00144       if (_adef == 0) return (fastjet::ClusterSequenceArea*) 0;
00145       return dynamic_cast<fastjet::ClusterSequenceArea*>(_cseq.get());
00146     }
00147 
00148     /// Return the jet definition (FastJet-specific).
00149     const fastjet::JetDefinition& jetDef() const {
00150       return _jdef;
00151     }
00152 
00153     /// Return the area definition (FastJet-specific). May be null.
00154     const fastjet::AreaDefinition* areaDef() const {
00155       return _adef;
00156     }
00157 
00158     /// Get the subjet splitting variables for the given jet.
00159     vector<double> ySubJet(const fastjet::PseudoJet& jet) const;
00160 
00161     /// @brief Split a jet a la PRL100,242001(2008).
00162     /// Based on code from G.Salam, A.Davison.
00163     fastjet::PseudoJet splitJet(fastjet::PseudoJet jet, double& last_R) const;
00164 
00165     /// @brief Filter a jet a la PRL100,242001(2008).
00166     /// Based on code from G.Salam, A.Davison.
00167     fastjet::PseudoJet filterJet(fastjet::PseudoJet jet, double& stingy_R, const double def_R) const;
00168 
00169   private:
00170 
00171     Jets _pseudojetsToJets(const PseudoJets& pjets) const;
00172 
00173     void _init1(JetAlgName alg, double rparameter, double seed_threshold) {
00174       setName("FastJets");
00175       MSG_DEBUG("R parameter = " << rparameter);
00176       MSG_DEBUG("Seed threshold = " << seed_threshold);
00177       if (alg == KT) {
00178         _jdef = fastjet::JetDefinition(fastjet::kt_algorithm, rparameter, fastjet::E_scheme);
00179       } else if (alg == CAM) {
00180         _jdef = fastjet::JetDefinition(fastjet::cambridge_algorithm, rparameter, fastjet::E_scheme);
00181       } else if (alg == ANTIKT) {
00182         _jdef = fastjet::JetDefinition(fastjet::antikt_algorithm, rparameter, fastjet::E_scheme);
00183       } else if (alg == DURHAM) {
00184         _jdef = fastjet::JetDefinition(fastjet::ee_kt_algorithm, fastjet::E_scheme);
00185       } else {
00186         // Plugins:
00187         if (alg == SISCONE) {
00188           const double OVERLAP_THRESHOLD = 0.75;
00189           _plugin.reset(new fastjet::SISConePlugin(rparameter, OVERLAP_THRESHOLD));
00190         } else if (alg == PXCONE) {
00191           string msg = "PxCone currently not supported, since FastJet doesn't install it by default. ";
00192           msg += "Please notify the Rivet authors if this behaviour should be changed.";
00193           throw Error(msg);
00194           //_plugin.reset(new fastjet::PxConePlugin(rparameter));
00195         } else if (alg == ATLASCONE) {
00196           const double OVERLAP_THRESHOLD = 0.5;
00197           _plugin.reset(new fastjet::ATLASConePlugin(rparameter, seed_threshold, OVERLAP_THRESHOLD));
00198         } else if (alg == CMSCONE) {
00199           _plugin.reset(new fastjet::CMSIterativeConePlugin(rparameter, seed_threshold));
00200         } else if (alg == CDFJETCLU) {
00201           const double OVERLAP_THRESHOLD = 0.75;
00202           _plugin.reset(new fastjet::CDFJetCluPlugin(rparameter, OVERLAP_THRESHOLD, seed_threshold));
00203         } else if (alg == CDFMIDPOINT) {
00204           const double OVERLAP_THRESHOLD = 0.5;
00205           _plugin.reset(new fastjet::CDFMidPointPlugin(rparameter, OVERLAP_THRESHOLD, seed_threshold));
00206         } else if (alg == D0ILCONE) {
00207           const double min_jet_Et = 6.0;
00208           _plugin.reset(new fastjet::D0RunIIConePlugin(rparameter, min_jet_Et));
00209         } else if (alg == JADE) {
00210           _plugin.reset(new fastjet::JadePlugin());
00211         } else if (alg == TRACKJET) {
00212           _plugin.reset(new fastjet::TrackJetPlugin(rparameter));
00213         }
00214         _jdef = fastjet::JetDefinition(_plugin.get());
00215       }
00216     }
00217 
00218     void _init2(fastjet::JetAlgorithm type,
00219                      fastjet::RecombinationScheme recom, double rparameter) {
00220       setName("FastJets");
00221       _jdef = fastjet::JetDefinition(type, rparameter, recom);
00222     }
00223 
00224     void _init3(fastjet::JetDefinition::Plugin& plugin) {
00225       setName("FastJets");
00226       /// @todo Should we be copying the plugin?
00227       _plugin.reset(&plugin);
00228       _jdef = fastjet::JetDefinition(_plugin.get());
00229     }
00230 
00231   protected:
00232 
00233     /// Perform the projection on the Event.
00234     void project(const Event& e);
00235 
00236     /// Compare projections.
00237     int compare(const Projection& p) const;
00238 
00239   public:
00240 
00241     /// Do the calculation locally (no caching).
00242     void calc(const ParticleVector& ps);
00243 
00244 
00245   private:
00246 
00247     /// Jet definition
00248     fastjet::JetDefinition _jdef;
00249 
00250     /// Pointer to user-handled area definition
00251     fastjet::AreaDefinition* _adef;
00252 
00253     /// Cluster sequence
00254     shared_ptr<fastjet::ClusterSequence> _cseq;
00255 
00256     /// FastJet external plugin
00257     shared_ptr<fastjet::JetDefinition::Plugin> _plugin;
00258 
00259     /// Map of vectors of y scales. This is mutable so we can use caching/lazy evaluation.
00260     mutable map<int, vector<double> > _yscales;
00261 
00262     /// set of particles sorted by their PT2
00263     //set<Particle, ParticleBase::byPTAscending> _particles;
00264     map<int, Particle> _particles;
00265 
00266   };
00267 
00268 }
00269 
00270 #endif