Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:37

0001 // FastJet3.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2024 Torbjorn Sjostrand.
0003 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
0004 // Please respect the MCnet Guidelines, see GUIDELINES for details.
0005 
0006 // This header file written by Gavin Salam.
0007 
0008 #ifndef Pythia8_FastJet3_H
0009 #define Pythia8_FastJet3_H
0010 
0011 //----------------------------------------------------------------------
0012 /// \file FastJet3Pythia8.hh
0013 ///
0014 /// Code providing an interface for FastJet 3 to make use of Pythia8
0015 /// particles and momenta. Given a
0016 ///
0017 /// \code
0018 ///   Pythia8::Particle  py8_particle;
0019 /// \endcode
0020 ///
0021 /// you may write
0022 ///
0023 /// \code
0024 ///   fastjet::PseudoJet fj_particle = py8_particle;
0025 /// \endcode
0026 ///
0027 /// A copy of the Pythia8::Particle can then be accessed as
0028 ///
0029 /// \code
0030 ///   fj_particle.user_info<Pythia8::Particle>()
0031 /// \endcode
0032 ///
0033 /// so that one can obtain information about the particle such as
0034 ///
0035 /// \code
0036 ///   fj_particle.user_info<Pythia8::Particle>().status();
0037 ///   fj_particle.user_info<Pythia8::Particle>().charge();
0038 /// \endcode
0039 ///
0040 /// etc. Note that because the construction of a PseudoJet from the
0041 /// Pythia8 particle involves taking a copy of the whole particle
0042 /// (which has a number of member variables), there will be a small
0043 /// time penalty at that point.
0044 ///
0045 /// This file also defines a number of selectors that act on such
0046 /// PseudoJets, such as
0047 ///
0048 /// \code
0049 ///   SelectorIsCharged();
0050 ///   SelectorId(int id);
0051 /// \endcode
0052 ///
0053 /// so that one can for example write
0054 ///
0055 /// \code
0056 ///   vector<PseudoJet> charged_constituents
0057 ///     = SelectorIsCharged()(jet.constituents());
0058 /// \endcode
0059 ///
0060 /// The full list of Pythia8-specific selectors is to be found at the
0061 /// end of this file. They can be combined with each other and with
0062 /// FastJet selectors using standard boolean operators.  They are all
0063 /// in the fastjet namespace.
0064 ///
0065 /// If you do not need the above facilities, then you may instead
0066 /// construct the PseudoJet from the pythia8 particle's 4-vector
0067 ///
0068 /// \code
0069 ///   PseudoJet fj_particle = py8_particle.p();
0070 /// \endcode
0071 ///
0072 /// NB: this code is entirely given as an include file. If compilation
0073 /// time is critical for your application, you may wish to split it
0074 /// into separate .cc and .hh files.
0075 ///
0076 // ----------------------------------------------------------------------
0077 // Copyright 2011 by Matteo Cacciari, Gavin Salam and Gregory
0078 // Soyez. Permission is granted to redistribute this file and modify
0079 // it, as long as this notice is retained and any changes are clearly
0080 // marked. No warranties are provided!
0081 // ----------------------------------------------------------------------
0082 
0083 #include "fastjet/config.h"             // will allow a test for FJ3
0084 #include "fastjet/ClusterSequence.hh"   // also gives PseudoJet & JetDefinition
0085 #include "fastjet/Selector.hh"
0086 #include "Pythia8/Event.h"              // this is what we need from Pythia8
0087 
0088 // FASTJET_VERSION is only defined from version 3 onwards so we can
0089 // use it to test that we have a sufficiently recent version
0090 #ifndef FASTJET_VERSION
0091 #error "FastJet3 is required in order to obtain the features of this interface"
0092 #endif
0093 
0094 FASTJET_BEGIN_NAMESPACE // place the code here inside the FJ namespace
0095 
0096 /// \class Py8Particle
0097 ///
0098 /// A class derived from a pythia 8 particle and that also derives
0099 /// from PseudoJet::UserInfoBase, so that it can be used as UserInfo
0100 /// inside PseudoJets, but also be cast back to the Pythia8 particle
0101 class Py8Particle: public Pythia8::Particle,
0102                    public PseudoJet::UserInfoBase {
0103 public:
0104   Py8Particle(const Pythia8::Particle & particle) : Particle(particle),
0105     mIndex(particle.index()) {}
0106    virtual int index() const override {return mIndex;}
0107 private:
0108   int mIndex;
0109 };
0110 
0111 /// specialization of the PseudoJet constructor so that it can take a
0112 /// pythia8 particle (and makes a copy of it as user info);
0113 template<>
0114 inline PseudoJet::PseudoJet(const Pythia8::Particle & particle) {
0115   reset(particle.px(),particle.py(),particle.pz(), particle.e());
0116   set_user_index( particle.index() );
0117   set_user_info(new Py8Particle(particle));
0118 }
0119 
0120 /// specialization of the PseudoJet constructor so that it can take a
0121 /// pythia8 Vec4. There is then no particular user info available.
0122 template<>
0123 inline PseudoJet::PseudoJet(const Pythia8::Vec4 & particle) {
0124   reset(particle.px(),particle.py(),particle.pz(), particle.e());
0125 }
0126 
0127 
0128 /// \class SelectorWorkerPy8
0129 ///
0130 /// A template class to help with the creation of Selectors for Pythia
0131 /// particle properties. It's not necessary to understand how this
0132 /// works in order to use the selectors. See below for the actual list
0133 /// of selectors.
0134 ///
0135 /// (But if you're curious, essentially it stores a pointer to a
0136 /// member function of Pythia8::Particle, and when called to select
0137 /// particles, executes it and checks the return value is equal to
0138 /// that requested in the constructor).
0139 template<class T> class SelectorWorkerPy8 : public SelectorWorker {
0140 public:
0141   /// the typedef helps with the notation for member function pointers
0142   typedef  T (Pythia8::Particle::*Py8ParticleFnPtr)() const;
0143 
0144   /// c'tor, which takes the member fn pointer and the return value
0145   /// that it should be equal to
0146   SelectorWorkerPy8(Py8ParticleFnPtr member_fn_ptr, T value) :
0147     _member_fn_ptr(member_fn_ptr), _value(value) {};
0148 
0149   /// the one function from SelectorWorker that must be overloaded to
0150   /// get functioning selection. It makes sure that the PseudoJet
0151   /// actually has Pythia8::Particle user info before checking
0152   /// its value.
0153   bool pass(const PseudoJet & p) const {
0154     const Pythia8::Particle * py8_particle
0155       = dynamic_cast<const Pythia8::Particle *>(p.user_info_ptr());
0156     if (py8_particle == 0) {
0157       return false; // no info, so false
0158     } else {
0159       return (py8_particle->*_member_fn_ptr)() == _value;
0160     }
0161   }
0162 private:
0163   Py8ParticleFnPtr _member_fn_ptr;
0164   T _value;
0165 };
0166 
0167 /// @name Boolean FJ3/PY8 Selectors
0168 ///
0169 /// A series of selectors for boolean properties of PseudoJets with
0170 /// Pythia8::Particle information; PseudoJets without
0171 /// Pythia8::Particle structure never pass these selectors.
0172 ///
0173 ///\{
0174 inline Selector SelectorIsFinal    () {return
0175   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isFinal   , true));}
0176 inline Selector SelectorIsCharged  () {return
0177   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isCharged , true));}
0178 inline Selector SelectorIsNeutral  () {return
0179   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isNeutral , true));}
0180 inline Selector SelectorIsResonance() {return
0181   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isResonance,true));}
0182 inline Selector SelectorIsVisible  () {return
0183   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isVisible , true));}
0184 inline Selector SelectorIsLepton   () {return
0185   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isLepton  , true));}
0186 inline Selector SelectorIsQuark    () {return
0187   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isQuark   , true));}
0188 inline Selector SelectorIsGluon    () {return
0189   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isGluon   , true));}
0190 inline Selector SelectorIsDiquark  () {return
0191   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isDiquark , true));}
0192 inline Selector SelectorIsParton   () {return
0193   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isParton  , true));}
0194 inline Selector SelectorIsHadron   () {return
0195   Selector(new SelectorWorkerPy8<bool>(&Pythia8::Particle::isHadron  , true));}
0196 ///\}
0197 
0198 /// @name Integer FJ3/PY8 Selectors
0199 ///
0200 /// A series of selectors for integer properties of PseudoJets with
0201 /// Pythia8::Particle information; PseudoJets without
0202 /// Pythia8::Particle structure never pass these selectors.
0203 ///
0204 ///\{
0205 inline Selector SelectorId       (int i) {return
0206   Selector(new SelectorWorkerPy8<int>(&Pythia8::Particle::id       , i));}
0207 inline Selector SelectorIdAbs    (int i) {return
0208   Selector(new SelectorWorkerPy8<int>(&Pythia8::Particle::idAbs    , i));}
0209 inline Selector SelectorStatus   (int i) {return
0210   Selector(new SelectorWorkerPy8<int>(&Pythia8::Particle::status   , i));}
0211 inline Selector SelectorStatusAbs(int i) {return
0212   Selector(new SelectorWorkerPy8<int>(&Pythia8::Particle::statusAbs, i));}
0213 ///\}
0214 
0215 
0216 FASTJET_END_NAMESPACE
0217 
0218 #endif // Pythia8_FastJet3_H