diff --git a/Analysis/NLOHepMCFile.h b/Analysis/NLOHepMCFile.h --- a/Analysis/NLOHepMCFile.h +++ b/Analysis/NLOHepMCFile.h @@ -1,206 +1,201 @@ // -*- C++ -*- #ifndef ThePEG_NLOHepMCFile_H #define ThePEG_NLOHepMCFile_H // // This is the declaration of the NLOHepMCFile class. // #include #include "ThePEG/Handlers/AnalysisHandler.h" #include "ThePEG/Config/HepMCHelper.h" namespace ThePEG { /** * \author Simon Platzer * * \brief Write hard sub processes or sub process groups to HepMC. * */ class NLOHepMCFile: public AnalysisHandler { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ NLOHepMCFile(); /** * The copy constructor. */ NLOHepMCFile(const NLOHepMCFile &); - - /** - * The destructor. - */ - virtual ~NLOHepMCFile() {} //@} public: /** @name Virtual functions required by the AnalysisHandler class. */ //@{ /** * Analyze a given Event. Note that a fully generated event * may be presented several times, if it has been manipulated in * between. The default version of this function will call transform * to make a lorentz transformation of the whole event, then extract * all final state particles and call analyze(tPVector) of this * analysis object and those of all associated analysis objects. The * default version will not, however, do anything on events which * have not been fully generated, or have been manipulated in any * way. * @param event pointer to the Event to be analyzed. * @param ieve the event number. * @param loop the number of times this event has been presented. * If negative the event is now fully generated. * @param state a number different from zero if the event has been * manipulated in some way since it was last presented. */ virtual void analyze(tEventPtr event, long ieve, int loop, int state); /** * Produca a HepMC event for the given subprocess */ HepMC::GenEvent * makeEvent(tEventPtr event, tSubProPtr sub, long no, Energy eUnit, Length lUnit, CrossSection xsec, CrossSection xsecErr) const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); //@} protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The PDG ID to be used for remnants */ long _remnantId; /** * The HepMC format */ int _format; /** * The HepMC filename */ string _filename; #ifdef HAVE_HEPMC_ROOTIO /** * The name of TTRee in ROOT file */ string _ttreename; /** * The name of branch in ROOT file */ string _tbranchname; #endif /** * The HepMC I/O handler */ #ifdef HAVE_HEPMC3 HepMC::Writer *_hepmcio; #else HepMC::IO_BaseClass *_hepmcio; #endif /** * The HepMC dump file */ ofstream _hepmcdump; /** * Selector for the choice of units */ int _unitchoice; /** * Choice of output precision in GenEvent format */ unsigned int _geneventPrecision; /** * Count events */ unsigned long _eventNumber; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ NLOHepMCFile & operator=(const NLOHepMCFile &) = delete; }; } #endif /* ThePEG_NLOHepMCFile_H */ diff --git a/Analysis/ProgressLog.cc b/Analysis/ProgressLog.cc --- a/Analysis/ProgressLog.cc +++ b/Analysis/ProgressLog.cc @@ -1,171 +1,169 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the ProgressLog class. // #include "ProgressLog.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include #include using namespace ThePEG; ProgressLog::ProgressLog(): secstep(0) {} -ProgressLog::~ProgressLog() {} - void ProgressLog::analyze(tEventPtr event, long ieve, int loop, int state) { AnalysisHandler::analyze(event, ieve, loop, state); long n = generator()->N(); long i = ieve; if ( !statusTime(i, n) ) return; double fcpui = fclock(); time_t timei = time(0); double ftime0 = time0; double ftime1 = time1; double ftimei = timei; double eff = 1.0; if ( ftimei > ftime1 && fcpui > fcpu1 ) eff = (fcpui-fcpu1)/(ftimei-ftime1); if ( eff >= 1.0 ) eff = 0.999999; int ieff = 100*eff; double eff0 = 1.0; if ( ftimei > ftime0 && fcpui > fcpu0 ) eff0 = (fcpui-fcpu0)/(ftimei-ftime0); if ( eff0 >= 1.0 ) eff0 = 0.999999; int ieff0 = 100*eff0; double fcpun = fcpu0 + (n*(fcpui-fcpu0))/i; time_t timen = (time_t)(ftimei + (fcpun-fcpui)/eff + 30.0); time_t timen0 = (time_t)(ftimei + (fcpun-fcpui)/eff0 + 30.0); char date[1024]; char daten[1024]; char daten0[1024]; strftime(date,1024,"%y.%m.%d %H:%M",localtime(&timei)); strftime(daten,1024,"%H:%M",localtime(&timen)); strftime(daten0,1024,"%H:%M",localtime(&timen0)); long ii = i; if ( n - i < n/10 ) ii = i - n; time_t dayn = (timen - timei)/86400; time_t dayn0 = (timen0 - timei)/86400; ostream & os = generator()->log(); if ( dayn <= 0 && dayn0 <= 0 ) { os << date << " " << setw(8) << ii << "/" << setw(9); os.setf(ios::left, ios::adjustfield); os << n << " etc: " << daten << "["; os.setf(ios::right, ios::adjustfield); os << setw(2) << ieff << "%] " << daten0 << "[" << ieff0 << "%] " << host << ":" << pid << endl << flush; } else { os << date << " " << setw(8) << ii << "/" << setw(9); os.setf(ios::left, ios::adjustfield); os << n << " etc: " << dayn << "+" << daten << "["; os.setf(ios::right, ios::adjustfield); os << setw(2) << ieff << "%] " << dayn0 << "+" << daten0 << "[" << ieff0 << "%] " << host << ":" << pid << endl << flush; } fcpu1 = fcpui; time1 = timei; } double ProgressLog::fclock() { struct tms tmsbuf; times(&tmsbuf); double d = tmsbuf.tms_utime+tmsbuf.tms_stime+tmsbuf.tms_cutime+tmsbuf.tms_cstime; d /= sysconf(_SC_CLK_TCK); return d; } bool ProgressLog::statusTime(long i, long n) const { if ( i <= 0 ) return false; if ( i == n ) return true; if ( i > n/2 ) i = n-i; while ( i >= 10 && !(i%10) ) i /= 10; if ( i == 1 || i == 2 || i == 5 ) return true; if ( secstep > 0 && time(0) > time1 + secstep ) return true; return false; } IBPtr ProgressLog::clone() const { return new_ptr(*this); } IBPtr ProgressLog::fullclone() const { return new_ptr(*this); } void ProgressLog::doinitrun() { AnalysisHandler::doinitrun(); fcpu0 = fcpu1 = fclock(); time0 = time1 = time(0); char name[1024]; gethostname(name,1024); host = name; if ( host.find(".") != string::npos ) host = host.substr(0, host.find(".")); pid = getpid(); char date[1024]; strftime(date,1024,"%y.%m.%d %H:%M",localtime(&time0)); ostream & os = generator()->log(); os << date << " 0/" << setw(9); os.setf(ios::left, ios::adjustfield); os << generator()->N(); os.setf(ios::right, ios::adjustfield); os << " Initializing... " << host << ":" << pid << endl << flush; } void ProgressLog::persistentOutput(PersistentOStream & os) const { os << secstep; } void ProgressLog::persistentInput(PersistentIStream & is, int) { is >> secstep; } ClassDescription ProgressLog::initProgressLog; // Definition of the static class description member. void ProgressLog::Init() { static ClassDocumentation documentation ("The ProgressLog class will not perform an actual analysis. Instead" " it will write out a progress status on the standard log file. By" " default it will write on event 1, 2, 5, 10, 20, 50, ... etc. But" " optionally it can in addition also write out every given number of" " seconds.\n\n" "The status line which is written out contains the current date " "and time, the number of events processed so far and the total number" "of events to be generated, two estimates of the time of completion " "(one based on the current cpu usage and one based on the average " "cpu usage [the usage is given in brackets]), and the host on which " "the program is running, together with its process number."); static Parameter interfaceInterval ("Interval", "Besides the standard intervals, also write a status line every " "given number of seconds.", &ProgressLog::secstep, 0, 0, 0, true, false, Interface::lowerlim); interfaceInterval.setHasDefault(false); } diff --git a/Analysis/ProgressLog.h b/Analysis/ProgressLog.h --- a/Analysis/ProgressLog.h +++ b/Analysis/ProgressLog.h @@ -1,226 +1,218 @@ // -*- C++ -*- #ifndef THEPEG_ProgressLog_H #define THEPEG_ProgressLog_H // // This is the declaration of the ProgressLog class. // #include "ThePEG/Handlers/AnalysisHandler.h" namespace ThePEG { /** * The ProgressLog class will not perform an actual analysis. Instead * it will write out a progress status on the standard log file. By * default it will write on event 1, 2, 5, 10, 20, 50, ... etc. But * optionally it can in addition also write out every given number of * seconds. * * The status line which is written out contains the current date and * time, the number of events processed so far and the total number of * events to be generated, two estimates of the time of completion * (one based on the current cpu usage and one based on the average * cpu usage [the usage is given in brackets]), and the host on which * the program is running, together with its process number. * * @see \ref ProgressLogInterfaces "The interfaces" * defined for ProgressLog. */ class ProgressLog: public AnalysisHandler { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ ProgressLog(); - /** - * The destructor. - */ - virtual ~ProgressLog(); - //@} - public: /** @name Virtual functions required by the AnalysisHandler class. */ //@{ /** * Analyze a given Event. Note that a fully generated event * may be presented several times, if it has been manipulated in * between. The default version of this function will call transform * to make a lorentz transformation of the whole event, then extract * all final state particles and call analyze(tPVector) of this * analysis object and those of all associated analysis objects. The * default version will not, however, do anything on events which * have not been fully generated, or have been manipulated in any * way. * @param event pointer to the Event to be analyzed. * @param ieve the event number. * @param loop the number of times this event has been presented. * If negative the event is now fully generated. * @param state a number different from zero if the event has been * manipulated in some way since it was last presented. */ virtual void analyze(tEventPtr event, long ieve, int loop, int state); //@} /** * Return the cpu clock in seconds. */ static double fclock(); /** * Check if it is time to write out a status line. */ bool statusTime(long i, long n) const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} private: /** * If larger than 0, a status line will be written every secstep second. */ int secstep; /** * The clock when the run was started. */ time_t time0; /** * The cpu clock when the run was started. */ double fcpu0; /** * The clock the last time a status line was written out. */ time_t time1; /** * The cpu clock the last time a status line was written out. */ double fcpu1; /** * The host on which we are running. */ string host; /** * The pid of the current process. */ pid_t pid; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initProgressLog; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ ProgressLog & operator=(const ProgressLog &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of ProgressLog. */ template <> struct BaseClassTrait { /** Typedef of the first base class of ProgressLog. */ typedef AnalysisHandler NthBase; }; /** This template specialization informs ThePEG about the name of * the ProgressLog class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::ProgressLog"; } /** * The name of a file containing the dynamic library where the class * ProgressLog is implemented. It may also include several, space-separated, * libraries if the class ProgressLog depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "ProgressLog.so"; } }; /** @endcond */ } #endif /* THEPEG_ProgressLog_H */ diff --git a/Analysis/XSecCheck.cc b/Analysis/XSecCheck.cc --- a/Analysis/XSecCheck.cc +++ b/Analysis/XSecCheck.cc @@ -1,81 +1,79 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the XSecCheck class. // #include "XSecCheck.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/EventRecord/Event.h" #ifdef ThePEG_TEMPLATES_IN_CC_FILE // #include "XSecCheck.tcc" #endif #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; -XSecCheck::~XSecCheck() {} - IBPtr XSecCheck::clone() const { return new_ptr(*this); } IBPtr XSecCheck::fullclone() const { return new_ptr(*this); } void XSecCheck::analyze(tEventPtr event, long ieve, int loop, int state) { AnalysisHandler::analyze(event, ieve, loop, state); sumw += event->weight(); } void XSecCheck::dofinish() { AnalysisHandler::dofinish(); CrossSection xsec = sumw*generator()->histogramScale(); if ( abs(xsec - target) > tol*abs(xsec + target) ) Throw() << "The total cross section of this run, " << xsec/picobarn << " picobarn, dit not match the target value, " << target/picobarn << " picobarn." << Exception::warning; } void XSecCheck::persistentOutput(PersistentOStream & os) const { os << ounit(target, picobarn) << tol << sumw; } void XSecCheck::persistentInput(PersistentIStream & is, int) { is >> iunit(target, picobarn) >> tol >> sumw; } ClassDescription XSecCheck::initXSecCheck; // Definition of the static class description member. void XSecCheck::Init() { static ClassDocumentation documentation ("The XSecCheck class is a simple analysis class used for testing " "purposes. If the total cross section does not match the one specified " "by TargetXSec, an exception will be thrown."); static Parameter interfaceTargetXSec ("TargetXSec", "The expected total cross section in units of picobarn.", &XSecCheck::target, picobarn, ZERO, ZERO, ZERO, true, false, Interface::lowerlim); interfaceTargetXSec.setHasDefault(false); static Parameter interfaceTolerance ("Tolerance", "The relative tolerance accepted when comparing the total cross " "section with TargetXSec.", &XSecCheck::tol, 0.01, 0.0, 1.0, true, false, Interface::limited); interfaceTolerance.setHasDefault(false); } diff --git a/Analysis/XSecCheck.h b/Analysis/XSecCheck.h --- a/Analysis/XSecCheck.h +++ b/Analysis/XSecCheck.h @@ -1,205 +1,197 @@ // -*- C++ -*- #ifndef THEPEG_XSecCheck_H #define THEPEG_XSecCheck_H // // This is the declaration of the XSecCheck class. // #include "ThePEG/Handlers/AnalysisHandler.h" namespace ThePEG { /** * The XSecCheck class is a simple analysis class used for testing * purposes. If the total cross section does not match the one * specified by TargetXSec, an exception will * be thrown. * * @see \ref XSecCheckInterfaces "The interfaces" * defined for XSecCheck. */ class XSecCheck: public AnalysisHandler { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ XSecCheck() : target(ZERO), tol(0.01), sumw(0.0) {} - /** - * The destructor. - */ - virtual ~XSecCheck(); - //@} - public: /** * The exception class used if the target cross section was not met. */ struct UnexpectedXSec: public Exception {}; public: /** @name Virtual functions required by the AnalysisHandler class. */ //@{ /** * Analyze a given Event. Note that a fully generated event * may be presented several times, if it has been manipulated in * between. The default version of this function will call transform * to make a lorentz transformation of the whole event, then extract * all final state particles and call analyze(tPVector) of this * analysis object and those of all associated analysis objects. The * default version will not, however, do anything on events which * have not been fully generated, or have been manipulated in any * way. * @param event pointer to the Event to be analyzed. * @param ieve the event number. * @param loop the number of times this event has been presented. * If negative the event is now fully generated. * @param state a number different from zero if the event has been * manipulated in some way since it was last presented. */ virtual void analyze(tEventPtr event, long ieve, int loop, int state); //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun() { AnalysisHandler::doinitrun(); sumw = 0.0; } /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); //@} private: /** * The expected total cross section. */ CrossSection target; /** * The relative tolerance accepted when comparing the total cross * section with the target. */ double tol; /** * The sum of the weights of the events analyzed. */ double sumw; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initXSecCheck; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ XSecCheck & operator=(const XSecCheck &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of XSecCheck. */ template <> struct BaseClassTrait { /** Typedef of the first base class of XSecCheck. */ typedef AnalysisHandler NthBase; }; /** This template specialization informs ThePEG about the name of * the XSecCheck class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::XSecCheck"; } /** * The name of a file containing the dynamic library where the class * XSecCheck is implemented. It may also include several, space-separated, * libraries if the class XSecCheck depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "XSecCheck.so"; } }; /** @endcond */ } #endif /* THEPEG_XSecCheck_H */ diff --git a/Config/std.h b/Config/std.h --- a/Config/std.h +++ b/Config/std.h @@ -1,188 +1,186 @@ // -*- C++ -*- // // std.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_std_H #define ThePEG_std_H /** \file * This file introduces a number of std:: classes into * the ThePEG namespace. Also introduces some useful functions for * standard library classes. * * Do not make changes in this file. If you want to use alternatives * to the std:: classes in ThePEG, edit a copy of this * file and include it in an alternative config file which can be * included in the main ThePEG.h config file using the macro * ThePEG_ALTERNATE_CONFIG. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace std { /** @cond TRAITSPECIALIZATIONS */ /** * This specialization of the std::less class is needed in order to be * able use put pointers to type_info objects as keys in maps and * sets. */ template <> -struct less : - public binary_function -{ +struct less { /** * This is the function called when comparing two pointers to * type_info. */ bool operator()(const type_info * x, const type_info * y) const { return x->before(*y); } }; /** @endcond */ } namespace ThePEG { using std::array; using std::deque; using std::stack; using std::vector; using std::multiset; using std::set; using std::map; using std::list; using std::multimap; using std::pair; using std::make_pair; using std::less; using std::string; using std::type_info; using std::exception; using std::range_error; using std::ios; using std::ostream; using std::istream; using std::ofstream; using std::ifstream; using std::ostringstream; using std::istringstream; using std::cin; using std::cout; using std::cerr; using std::endl; using std::flush; using std::setprecision; using std::setw; using std::swap; using std::min; using std::max; using std::mem_fn; using std::mem_fun; using std::sqrt; //using std::pow; using std::abs; using std::atan2; using std::isfinite; /** Powers - standard or non-standard */ template inline constexpr double pow(double x, ExponentT p) { return std::pow(x,double(p)); } /** Square root of an integer. */ inline double sqrt(int x) { return std::sqrt(double(x)); } /** factorial */ inline constexpr long double factorial(unsigned int n) { return (n < 2) ? 1.0 : n * factorial(n - 1); } /** Check if a given object is a part of a container. */ template inline bool member(const Container & c, const Key & k) { return c.find(k) != c.end(); } /** Check if a given object is a part of a vector. */ template inline bool member(const vector & v, const Key & k) { for ( typename vector::const_iterator i = v.begin(); i != v.end(); ++i ) if ( *i == k ) return true; return false; // return find(v.begin(), v.end(), k) != v.end(); } /** Return an insert iterator for a given container. */ template inline std::insert_iterator inserter(Cont & c) { return std::insert_iterator(c, c.end()); } /** Return an insert iterator for a given vector. Overrides the * general version. */ template inline std::back_insert_iterator< vector > inserter(vector & v) { return back_inserter(v); } /** Return an insert iterator for a given vector. Overrides the * general version. */ template inline std::back_insert_iterator< deque > inserter(deque & v) { return back_inserter(v); } /** Stream manipulator setting an ostream to left-adjust its ouput. */ inline ostream& left(ostream& os) { os.setf(ios::left, ios::adjustfield); return os; } /** Stream manipulator setting an ostream to right-adjust its ouput. */ inline ostream& right(ostream& os) { os.setf(ios::right, ios::adjustfield); return os; } } /** Macro for declaring a set. */ #define ThePEG_DECLARE_SET(VALTYPE,NAME) \ /** A set of VALTYPE. */ \ typedef set > NAME /** Macro for declaring a multiset. */ #define ThePEG_DECLARE_MULTISET(VALTYPE,NAME) \ /** A multiset of VALTYPE. */ \ typedef multiset > NAME /** Macro for declaring a map. */ #define ThePEG_DECLARE_MAP(KEYTYPE,VALTYPE,NAME) \ /** A map of VALTYPE indexed by KEYTYPE. */ \ typedef map > NAME #endif /* ThePEG_std_H */ diff --git a/Cuts/Cuts.cc b/Cuts/Cuts.cc --- a/Cuts/Cuts.cc +++ b/Cuts/Cuts.cc @@ -1,663 +1,661 @@ // -*- C++ -*- // // Cuts.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the Cuts class. // #include "Cuts.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/EventRecord/SubProcess.h" #include "ThePEG/EventRecord/Collision.h" #include "ThePEG/EventRecord/TmpTransform.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Utilities/HoldFlag.h" #include "ThePEG/Utilities/Debug.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Config/algorithm.h" using namespace ThePEG; Cuts::Cuts(Energy MhatMin) : theSMax(ZERO), theY(0), theCurrentSHat(-1.0*GeV2), theCurrentYHat(0), theMHatMin(MhatMin), theMHatMax(Constants::MaxEnergy), theYHatMin(-Constants::MaxRapidity), theYHatMax(Constants::MaxRapidity), theX1Min(0.0), theX1Max(1.0), theX2Min(0.0), theX2Max(1.0), theScaleMin(ZERO), theScaleMax(Constants::MaxEnergy2), theSubMirror(false), theCutWeight(1.0), theLastCutWeight(1.0) {} -Cuts::~Cuts() {} - IBPtr Cuts::clone() const { return new_ptr(*this); } IBPtr Cuts::fullclone() const { return new_ptr(*this); } void Cuts::doinitrun() { Interfaced::doinitrun(); if ( Debug::level ) { describe(); for_each(theOneCuts, mem_fn(&OneCutBase::describe)); for_each(theTwoCuts, mem_fn(&TwoCutBase::describe)); for_each(theMultiCuts, mem_fn(&MultiCutBase::describe)); } } void Cuts::describe() const { CurrentGenerator::log() << fullName() << ":\n" << "MHat = " << theMHatMin/GeV << " .. " << theMHatMax/GeV << " GeV\n" << "Scale = " << theScaleMin/GeV2 << " .. " << theScaleMax/GeV2 << " GeV2\n" << "YHat = " << theYHatMin << " .. " << theYHatMax << '\n' << "X1 = " << theX1Min << " .. " << theX1Max << '\n' << "X2 = " << theX2Min << " .. " << theX2Max << "\n\n"; if ( theJetFinder ) theJetFinder->describe(); } void Cuts::initialize(Energy2 smax, double Y) { theSMax = smax; theMHatMax = min(theMHatMax, sqrt(smax)); theY = Y; theSubMirror = false; } void Cuts::initEvent() { theCurrentSHat = -1.0*GeV2; theCurrentYHat = 0.0; theSubMirror = false; } bool Cuts::initSubProcess(Energy2 shat, double yhat, bool mirror) const { theCutWeight = 1.0; theLastCutWeight = 1.0; theSubMirror = mirror; theCurrentSHat = shat; theCurrentYHat = yhat; if ( shat <= sHatMin() || shat > sHatMax()*(1.0 + 1000.0*Constants::epsilon) ) { theCutWeight = 0.0; return false; } if ( yhat <= yHatMin() || yhat >= yHatMax() ) { theCutWeight = 0.0; return false; } double x1 = min(1.0, sqrt(shat/SMax())*exp(yhat)); if ( x1 <= x1Min() || x1 > x1Max() ) { theCutWeight = 0.0; return false; } double x2 = min(1.0, sqrt(shat/SMax())*exp(-yhat)); if ( x2 <= x2Min() || x2 > x2Max() ) { theCutWeight = 0.0; return false; } return true; } bool Cuts::passCuts(const tcPDVector & ptype, const vector & p, tcPDPtr t1, tcPDPtr t2) const { if ( subMirror() ) { vector pmir = p; for ( int i = 0, N = pmir.size(); i < N; ++i ) pmir[i].setZ(-pmir[i].z()); swap(t1,t2); HoldFlag<> nomir(theSubMirror, false); return passCuts(ptype, pmir, t1, t2); } bool pass = true; theCutWeight = 1.0; theLastCutWeight = 1.0; if ( jetFinder() ) { if ( ptype.size() > jetFinder()->minOutgoing() ) { vector jets; tcPDVector jettype; if ( !jetFinder()->restrictConsitutents() ) { jets = p; jettype = ptype; } else { tcPDVector::const_iterator pd = ptype.begin(); vector::const_iterator pm = p.begin(); for ( ; pd != ptype.end(); ++pd, ++pm ) { if ( pm->rapidity() > jetFinder()->constituentRapidityRange().first && pm->rapidity() < jetFinder()->constituentRapidityRange().second ) { jets.push_back(*pm); jettype.push_back(*pd); } } } if ( jetFinder()->cluster(jettype,jets,this,t1,t2) ){ return passCuts(jettype,jets,t1,t2); } } } for ( int i = 0, N = p.size(); i < N; ++i ) for ( int j = 0, M = theOneCuts.size(); j < M; ++j ) { pass &= theOneCuts[j]->passCuts(this, ptype[i], p[i]); theCutWeight *= theLastCutWeight; theLastCutWeight = 1.0; if ( !pass ) { theCutWeight = 0.0; return false; } } for ( int i1 = 0, N1 = p.size() - 1; i1 < N1; ++i1 ) for ( int i2 = i1 + 1, N2 = p.size(); i2 < N2; ++i2 ) for ( int j = 0, M = theTwoCuts.size(); j < M; ++j ) { pass &= theTwoCuts[j]->passCuts(this, ptype[i1], ptype[i2], p[i1], p[i2]); theCutWeight *= theLastCutWeight; theLastCutWeight = 1.0; if ( !pass ) { theCutWeight = 0.0; return false; } } for ( int j = 0, M = theMultiCuts.size(); j < M; ++j ) { pass &= theMultiCuts[j]->passCuts(this, ptype, p); theCutWeight *= theLastCutWeight; theLastCutWeight = 1.0; if ( !pass ) { theCutWeight = 0.0; return false; } } if ( t1 ) { LorentzMomentum p1(ZERO, ZERO, 0.5*sqrt(currentSHat()), 0.5*sqrt(currentSHat())); for ( int i = 0, N = p.size(); i < N; ++i ) for ( int j = 0, M = theTwoCuts.size(); j < M; ++j ) { pass &= theTwoCuts[j]->passCuts(this, t1, ptype[i], p1, p[i], true, false); theCutWeight *= theLastCutWeight; theLastCutWeight = 1.0; if ( !pass ) { theCutWeight = 0.0; return false; } } } if ( t2 ) { LorentzMomentum p2(ZERO, ZERO, -0.5*sqrt(currentSHat()), 0.5*sqrt(currentSHat())); for ( int i = 0, N = p.size(); i < N; ++i ) for ( int j = 0, M = theTwoCuts.size(); j < M; ++j ) { pass &= theTwoCuts[j]->passCuts(this, ptype[i], t2, p[i], p2, false, true); theCutWeight *= theLastCutWeight; theLastCutWeight = 1.0; if ( !pass ) { theCutWeight = 0.0; return false; } } } return pass; } bool Cuts::passCuts(const tcPVector & p, tcPDPtr t1, tcPDPtr t2) const { tcPDVector ptype(p.size()); vector mom(p.size()); for ( int i = 0, N = p.size(); i < N; ++i ) { ptype[i] = p[i]->dataPtr(); mom[i] = p[i]->momentum(); } return passCuts(ptype, mom, t1, t2); } bool Cuts::passCuts(const SubProcess & sub) const { if ( !passCuts(tcPVector(sub.outgoing().begin(), sub.outgoing().end()), sub.incoming().first->dataPtr(), sub.incoming().second->dataPtr()) ) return false; return true; } bool Cuts::passCuts(const Collision & coll) const { tSubProPtr sub = coll.primarySubProcess(); LorentzMomentum phat = sub->incoming().first->momentum() + sub->incoming().second->momentum(); if ( !initSubProcess(phat.m2(), phat.rapidity()) ) return false; TmpTransform tmp(sub, Utilities::getBoostToCM(sub->incoming())); if ( !passCuts(*sub) ) return false; return true; } Energy2 Cuts::minS(const tcPDVector & pv) const { Energy2 mins = ZERO; for ( int i = 0, N = theMultiCuts.size(); i < N; ++i ) mins = max(mins, theMultiCuts[i]->minS(pv)); return mins; } Energy2 Cuts::maxS(const tcPDVector & pv) const { Energy2 maxs = SMax(); for ( int i = 0, N = theMultiCuts.size(); i < N; ++i ) maxs = min(maxs, theMultiCuts[i]->maxS(pv)); return maxs; } Energy2 Cuts::minSij(tcPDPtr pi, tcPDPtr pj) const { Energy2 mins = ZERO; for ( int i = 0, N = theTwoCuts.size(); i < N; ++i ) mins = max(mins, theTwoCuts[i]->minSij(pi, pj)); if ( mins > ZERO ) return mins; mins = sqr(pi->massMin() + pj->massMin()); mins = max(mins, sqr(minKTClus(pi, pj))/4.0); mins = max(mins, minDurham(pi, pj)*currentSHat()/2.0); mins = max(mins, minKT(pi)*minKT(pj)*minDeltaR(pi, pj)/4.0); return mins; } Energy2 Cuts::minTij(tcPDPtr pi, tcPDPtr po) const { Energy2 mint = ZERO; for ( int i = 0, N = theTwoCuts.size(); i < N; ++i ) mint = max(mint, theTwoCuts[i]->minTij(pi, po)); if ( mint > ZERO ) return mint; mint = max(mint, sqr(minKT(po))); return mint; } double Cuts::minDeltaR(tcPDPtr pi, tcPDPtr pj) const { double mindr = 0.0; for ( int i = 0, N = theTwoCuts.size(); i < N; ++i ) mindr = max(mindr, theTwoCuts[i]->minDeltaR(pi, pj)); return mindr; } Energy Cuts::minKTClus(tcPDPtr pi, tcPDPtr pj) const { Energy minkt = ZERO; for ( int i = 0, N = theTwoCuts.size(); i < N; ++i ) minkt = max(minkt, theTwoCuts[i]->minKTClus(pi, pj)); return minkt; } double Cuts::minDurham(tcPDPtr pi, tcPDPtr pj) const { double y = 0.0; for ( int i = 0, N = theTwoCuts.size(); i < N; ++i ) y = max(y, theTwoCuts[i]->minDurham(pi, pj)); return y; } Energy Cuts::minKT(tcPDPtr p) const { Energy minkt = ZERO; for ( int i = 0, N = theOneCuts.size(); i < N; ++i ) minkt = max(minkt, theOneCuts[i]->minKT(p)); if ( minkt > ZERO ) return minkt; minkt = minKTClus(p, tcPDPtr()); return minkt; } double Cuts::minEta(tcPDPtr p) const { double mineta = -Constants::MaxRapidity; for ( int i = 0, N = theOneCuts.size(); i < N; ++i ) mineta = max(mineta, theOneCuts[i]->minEta(p)); return mineta; } double Cuts::maxEta(tcPDPtr p) const { double maxeta = Constants::MaxRapidity; for ( int i = 0, N = theOneCuts.size(); i < N; ++i ) maxeta = min(maxeta, theOneCuts[i]->maxEta(p)); return maxeta; } double Cuts::minYStar(tcPDPtr p) const { if ( currentSHat() < ZERO ) return -Constants::MaxRapidity; if ( subMirror() ) { HoldFlag<> nomir(theSubMirror, false); return -maxYStar(p); } double etamin = minEta(p); double ytot = Y() + currentYHat(); if ( etamin > 0.0 ) { Energy minkt = minKT(p); Energy maxm = p->massMax(); return asinh(minkt*sinh(etamin)/sqrt(sqr(minkt) + sqr(maxm))) - ytot; } else { return etamin - ytot; } } double Cuts::maxYStar(tcPDPtr p) const { if ( currentSHat() < ZERO ) return Constants::MaxRapidity; if ( subMirror() ) { HoldFlag<> nomir(theSubMirror, false); return -minYStar(p); } double etamax = maxEta(p); double ytot = Y() + currentYHat(); if ( etamax > 0.0 ) { return etamax - ytot; } else { Energy minkt = minKT(p); Energy maxm = p->massMax(); return asinh(minkt*sinh(etamax)/sqrt(sqr(minkt) + sqr(maxm))) - ytot; } } double Cuts::minRapidityMax(tcPDPtr p) const { double minRapidityMax = -Constants::MaxRapidity; for ( int i = 0, N = theOneCuts.size(); i < N; ++i ) minRapidityMax = max(minRapidityMax, theOneCuts[i]->minRapidityMax(p)); return minRapidityMax; } double Cuts::maxRapidityMin(tcPDPtr p) const { double maxRapidityMin = Constants::MaxRapidity; for ( int i = 0, N = theOneCuts.size(); i < N; ++i ) maxRapidityMin = min(maxRapidityMin, theOneCuts[i]->maxRapidityMin(p)); return maxRapidityMin; } void Cuts::persistentOutput(PersistentOStream & os) const { os << ounit(theSMax, GeV2) << theY << ounit(theCurrentSHat, GeV2) << theCurrentYHat << ounit(theMHatMin, GeV) << ounit(theMHatMax, GeV) << theYHatMin << theYHatMax << theX1Min << theX1Max << theX2Min << theX2Max << ounit(theScaleMin, GeV2) << ounit(theScaleMax, GeV2) << theOneCuts << theTwoCuts << theMultiCuts << theJetFinder << theSubMirror << theCutWeight << theLastCutWeight << theFuzzyTheta; } void Cuts::persistentInput(PersistentIStream & is, int) { is >> iunit(theSMax, GeV2) >> theY >> iunit(theCurrentSHat, GeV2) >> theCurrentYHat >> iunit(theMHatMin, GeV) >> iunit(theMHatMax, GeV) >> theYHatMin >> theYHatMax >> theX1Min >> theX1Max >> theX2Min >> theX2Max >> iunit(theScaleMin, GeV2) >> iunit(theScaleMax, GeV2) >> theOneCuts >> theTwoCuts >> theMultiCuts >> theJetFinder >> theSubMirror >> theCutWeight >> theLastCutWeight >> theFuzzyTheta; } ClassDescription Cuts::initCuts; // Definition of the static class description member. Energy Cuts::maxMHatMin() const { return theMHatMax; } Energy Cuts::minMHatMax() const { return theMHatMin; } Energy2 Cuts::maxScaleMin() const { return theScaleMax; } Energy2 Cuts::minScaleMax() const { return theScaleMin; } double Cuts::maxYHatMin() const { return theYHatMax; } double Cuts::minYHatMax() const { return theYHatMin; } double Cuts::maxX1Min() const { return theX1Max; } double Cuts::minX1Max() const { return theX1Min; } double Cuts::maxX2Min() const { return theX2Max; } double Cuts::minX2Max() const { return theX2Min; } void Cuts::Init() { typedef double (ThePEG::Cuts::*IGFN)() const; typedef void (ThePEG::Cuts::*ISFN)(double); static ClassDocumentation documentation ("Cuts is a class for implementing kinematical cuts in ThePEG. The " "class itself only implements cuts on the total momentum of the hard " "sub-process, implemented as minimum and maximum values of \\f$x_1\\f$ " "and \\f$x_2\\f$ (or \\f$\\hat{s}\\f$ and \\f$\\hat{y}\\f$. Further cuts " "can be implemented either by inheriting from this base class, in which " "the virtual cut() function should be overridden, or by assigning " "objects of class OneCutBase, TwoCutBase and MultiCutBase defining " "cuts on single particles, pairs of particles and groups of " "particles respectively."); static Parameter interfaceMHatMin ("MHatMin", "The minimum allowed value of \\f$\\sqrt{\\hat{s}}\\f$.", &Cuts::theMHatMin, GeV, 2.0*GeV, ZERO, Constants::MaxEnergy, true, false, Interface::limited, 0, 0, 0, &Cuts::maxMHatMin, 0); interfaceMHatMin.setHasDefault(false); static Parameter interfaceMHatMax ("MHatMax", "The maximum allowed value of \\f$\\sqrt{\\hat{s}}\\f$.", &Cuts::theMHatMax, GeV, 100.0*GeV, ZERO, ZERO, true, false, Interface::lowerlim, 0, 0, &Cuts::minMHatMax, 0, 0); interfaceMHatMax.setHasDefault(false); static Parameter interfaceScaleMin ("ScaleMin", "The minimum allowed value of the scale to be used in PDFs and " "coupling constants.", &Cuts::theScaleMin, GeV2, ZERO, ZERO, Constants::MaxEnergy2, true, false, Interface::limited, 0, 0, 0, &Cuts::maxScaleMin, 0); interfaceScaleMin.setHasDefault(false); static Parameter interfaceScaleMax ("ScaleMax", "The maximum allowed value of the scale to be used in PDFs and " "coupling constants.", &Cuts::theScaleMax, GeV2, 10000.0*GeV2, ZERO, ZERO, true, false, Interface::lowerlim, 0, 0, &Cuts::minScaleMax, 0, 0); interfaceScaleMax.setHasDefault(false); static Parameter interfaceYHatMin ("YHatMin", "The minimum value of the rapidity of the hard sub-process " "(wrt. the rest system of the colliding particles).", &Cuts::theYHatMin, -10.0, 0.0, Constants::MaxRapidity, true, false, Interface::upperlim, (ISFN)0, (IGFN)0, (IGFN)0, &Cuts::maxYHatMin, (IGFN)0); interfaceYHatMin.setHasDefault(false); static Parameter interfaceYHatMax ("YHatMax", "The maximum value of the rapidity of the hard sub-process " "(wrt. the rest system of the colliding particles).", &Cuts::theYHatMax, 10.0, -Constants::MaxRapidity, 0.0, true, false, Interface::lowerlim, (ISFN)0, (IGFN)0, &Cuts::minYHatMax, (IGFN)0, (IGFN)0); interfaceYHatMax.setHasDefault(false); static Parameter interfaceX1Min ("X1Min", "The minimum value of the positive light-cone fraction of the hard " "sub-process.", &Cuts::theX1Min, 0.0, 0.0, 1.0, true, false, Interface::limited, (ISFN)0, (IGFN)0, (IGFN)0, &Cuts::maxX1Min, (IGFN)0); interfaceX1Min.setHasDefault(false); static Parameter interfaceX1Max ("X1Max", "The maximum value of the positive light-cone fraction of the hard " "sub-process.", &Cuts::theX1Max, 0.0, 0.0, 1.0, true, false, Interface::limited, (ISFN)0, (IGFN)0, &Cuts::minX1Max, (IGFN)0, (IGFN)0); interfaceX1Max.setHasDefault(false); static Parameter interfaceX2Min ("X2Min", "The minimum value of the negative light-cone fraction of the hard " "sub-process.", &Cuts::theX2Min, 0.0, 0.0, 1.0, true, false, Interface::limited, (ISFN)0, (IGFN)0, (IGFN)0, &Cuts::maxX2Min, (IGFN)0); interfaceX2Min.setHasDefault(false); static Parameter interfaceX2Max ("X2Max", "The maximum value of the negative light-cone fraction of the hard " "sub-process.", &Cuts::theX2Max, 0.0, 0.0, 1.0, true, false, Interface::limited, (ISFN)0, (IGFN)0, &Cuts::minX2Max, (IGFN)0, (IGFN)0); interfaceX2Max.setHasDefault(false); static RefVector interfaceOneCuts ("OneCuts", "The objects defining cuts on single outgoing partons from the " "hard sub-process.", &Cuts::theOneCuts, -1, true, false, true, false, false); static RefVector interfaceTwoCuts ("TwoCuts", "The objects defining cuts on pairs of particles in the " "hard sub-process.", &Cuts::theTwoCuts, -1, true, false, true, false, false); static RefVector interfaceMultiCuts ("MultiCuts", "The objects defining cuts on sets of outgoing particles from the " "hard sub-process.", &Cuts::theMultiCuts, -1, true, false, true, false, false); static Reference interfaceJetFinder ("JetFinder", "Set a JetFinder object used to define cuts on the" "level of reconstructed jets as needed for higher order corrections.", &Cuts::theJetFinder, false, false, true, true, false); static Reference interfaceFuzzy ("Fuzzy", "The fuzziness to be applied to cuts (may not be supported by all cut objects).", &Cuts::theFuzzyTheta, false, false, true, true, false); interfaceX1Min.rank(10); interfaceX1Max.rank(9); interfaceX2Min.rank(8); interfaceX2Max.rank(7); interfaceMHatMin.rank(6); interfaceMHatMax.rank(5); interfaceYHatMin.rank(4); interfaceYHatMax.rank(3); interfaceOneCuts.rank(2); interfaceTwoCuts.rank(1); } double Cuts::yHatMin() const { return theX1Min > 0.0 && theX2Max > 0.0? max(theYHatMin, 0.5*log(theX1Min/theX2Max)): theYHatMin; } double Cuts::yHatMax() const { return theX1Max > 0.0 && theX2Min > 0.0? min(theYHatMax, 0.5*log(theX1Max/theX2Min)): theYHatMax; } bool Cuts::yHat(double y) const { return y > yHatMin() && y < yHatMax(); } double Cuts::x1Min() const { return max(theX1Min, (theMHatMin/sqrt(SMax()))*exp(theYHatMin)); } double Cuts::x1Max() const { return min(theX1Max, (theMHatMax/sqrt(SMax()))*exp(theYHatMax)); } bool Cuts::x1(double x) const { return x > x1Min() && x <= x1Max(); } double Cuts::x2Min() const { return max(theX2Min, (theMHatMin/sqrt(SMax()))/exp(theYHatMax)); } double Cuts::x2Max() const { return min(theX2Max, (theMHatMax/sqrt(SMax()))/exp(theYHatMin)); } bool Cuts::x2(double x) const { return x > x2Min() && x <= x2Max(); } template vector::transient_const_pointer> Cuts::oneCutObjects() const { typedef typename Ptr::transient_const_pointer tcPtr; vector ret; for ( int i = 0, N = theOneCuts.size(); i < N; ++i ) if ( dynamic_ptr_cast(theOneCuts[i]) ) ret.push_back(dynamic_ptr_cast(theOneCuts[i])); return ret; } template vector::transient_const_pointer> Cuts::twoCutObjects() const { typedef typename Ptr::transient_const_pointer tcPtr; vector ret; for ( int i = 0, N = theTwoCuts.size(); i < N; ++i ) if ( dynamic_ptr_cast(theTwoCuts[i]) ) ret.push_back(dynamic_ptr_cast(theTwoCuts[i])); return ret; } template vector::transient_const_pointer> Cuts::multiCutObjects() const { typedef typename Ptr::transient_const_pointer tcPtr; vector ret; for ( int i = 0, N = theMultiCuts.size(); i < N; ++i ) if ( dynamic_ptr_cast(theMultiCuts[i]) ) ret.push_back(dynamic_ptr_cast(theMultiCuts[i])); return ret; } diff --git a/Cuts/Cuts.h b/Cuts/Cuts.h --- a/Cuts/Cuts.h +++ b/Cuts/Cuts.h @@ -1,838 +1,833 @@ // -*- C++ -*- // // Cuts.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_Cuts_H #define THEPEG_Cuts_H // // This is the declaration of the Cuts class. // #include "ThePEG/Interface/Interfaced.h" #include "Cuts.fh" #include "OneCutBase.h" #include "TwoCutBase.h" #include "MultiCutBase.h" #include "JetFinder.h" #include "FuzzyTheta.h" namespace ThePEG { /** * Cuts is a class for implementing kinematical cuts in ThePEG. The * class itself only implements cuts on the total momentum of the hard * sub-process, implemented as minimum and maximum values of \f$x_1\f$ * and \f$x_2\f$ (or \f$\hat{s}=x_1x_2S_{tot}\f$ and * \f$\hat{y}=\log(x_1/x_2)/2\f$. Further cuts can be implemented * either by inheriting from this base class, in which the virtual * cut() function should be overridden, or by assigning objects of * class OneCutBase, TwoCutBase and MultiCutBase defining cuts on * single particles, pairs of particles and groups of particles in the * hard sub-process respectively. * * The Cuts object must be initialized specifying the overall * laboratory frame, giving the total squared invariant mass, \f$S\f$, * and the rapidity, \f$Y\f$, of the colliding particles in this * frame. The colliding particles are thus assumed to be directed * along the \f$z\f$-axis. * * For each event, the Cuts object must also be initialized giving the * squared invarint mass, \f$\hat{s}\f$, and the total rapidity, * \f$\hat{y}\f$, of the hard sub-process in the center-of-mass frame * of the colliding particles. Note that this means that the * transformation between the lab frame and the rest frame of the hard * sub-process is assumed to be a simple boost along the z-axis. * * @see \ref CutsInterfaces "The interfaces" * defined for Cuts. */ class Cuts: public Interfaced { public: /** * A vector of OneCutBase pointers. */ typedef vector OneCutVector; /** * A vector of TwoCutBase pointers. */ typedef vector TwoCutVector; /** * A vector of MultiCutBase pointers. */ typedef vector MultiCutVector; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ Cuts(Energy MhatMin=2*GeV); - - /** - * The destructor. - */ - virtual ~Cuts(); //@} public: /** @name Initialization functions. */ //@{ /** * Initialize this object specifying the maximum total invariant * mass squared, \a smax, and the total rapidity, \a Y, of the * colliding particles (for the maximum invariant mass). A sub-class * overriding this function must make sure the base-class function * is called. This function should be called once in the beginning * of a run. */ virtual void initialize(Energy2 smax, double Y); /** * Initialize this object for a new event. A sub-class overriding * this function must make sure the base-class function is called. * This function is called before the generation of a new * sub-process, before the incoming partons have been generated. */ virtual void initEvent(); /** * Set information about the invariant mass squared, \a shat, and * rapidity, \a yhat, of the hard sub-process. The rapidity should * be given wrt. the center of mass of the colliding particles. A * sub-class overriding this function must make sure the base-class * function is called. This function is called before the generation * of a new sub-process, after the incoming partons have been * generated. If \a mirror is true any questions regarding cuts on * the sub-process in the functions minYStar(tcPDPtr), * maxYStar(tcPDPtr p), passCuts(const tcPDVector &, const * vector &, tcPDPtr, tcPDPtr) and passCuts(const * tcPVector &, tcPDPtr t1, tcPDPtr) will assume that the z-axis is * reversed in the sub-process rest frame. Returns false if the * given values were outside of the cuts. */ virtual bool initSubProcess(Energy2 shat, double yhat, bool mirror = false) const; //@} /** @name Check functions to see if a state has passed the cuts or not. */ //@{ /** * Check if the outgoing particles, with the given types and * momenta, from a sub-process passes the cuts. The particles must * be given in the rest frame of tha hard sub-process, and the * initSubProcess must have been called before. Also the types of * the incoming partons, \a t1 and \a t2, may be given if availible. */ virtual bool passCuts(const tcPDVector & ptype, const vector & p, tcPDPtr t1 = tcPDPtr(), tcPDPtr t2 = tcPDPtr()) const; /** * Check if the outgoing particles from a sub-process passes the * cuts. The particles must be given in the rest frame of tha hard * sub-process, and the initSubProcess must have been called * before. Also the types of the incoming partons, \a t1 and \a t2, * may be given if availible. */ bool passCuts(const tcPVector & p, tcPDPtr t1 = tcPDPtr(), tcPDPtr t2 = tcPDPtr()) const; /** * Check if the incoming and outgoing particles in the given * sub-process passes the cuts. The sub-process must be given in its * rest frame, and the initSubProcess must have been called before. */ bool passCuts(const SubProcess & sub) const; /** * Check if the given collision passes the cuts. The collision must * be given in its rest frame. */ bool passCuts(const Collision & coll) const; //@} /** @name Access to cuts of the underlying cut objects. */ //@{ /** * Return the minimum allowed squared invariant mass of two outgoing * partons of type \a pi and \a pj. This function first determines * the minimum from the corresponding function from in TwoCutBase * objects. If no minimum was found, one is derived from * minKTClus(), minDurham(), minKT() and minDeltaR(), if possible. */ Energy2 minSij(tcPDPtr pi, tcPDPtr pj) const; /** * Return the minimum allowed value of the negative of the squared * invariant mass of an incoming parton of type \a pi and an * outgoing parton of type \a po. This function first determines the * minimum from the corresponding function from in TwoCutBase * objects. If no minimum was found, one is derived from minKT(), if * possible. */ Energy2 minTij(tcPDPtr pi, tcPDPtr po) const; /** * Return the minimum allowed value of \f$\Delta * R_{ij}=\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ of two * outgoing partons of type \a pi and \a pj. Simply returns the * maximum of the results from calling the corresponding function in * the TwoCutBase objects. */ double minDeltaR(tcPDPtr pi, tcPDPtr pj) const; /** * Return the minimum allowed value of the longitudinally invariant * \f$k_\perp\f$-algorithms distance measure. This is defined as * \f$\min(p_{\perp i}, p_{\perp * j})\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ for two outgoing * partons, or simply \f$p_{\perp i}\f$ or \f$p_{\perp j}\f$ for a * single outgoing parton. Returns 0 if both partons are incoming. A * null pointer indicates an incoming parton, hence the type of the * incoming parton is irrelevant. Simply returns the maximum of the * results from calling the corresponding function in the TwoCutBase * objects. */ Energy minKTClus(tcPDPtr pi, tcPDPtr pj) const; /** * Return the minimum allowed value of the Durham * \f$k_\perp\f$-algorithms distance measure. This is defined as * \f$2\min(E_j^2, E_j^2)(1-\cos\theta_{ij})/\hat{s}\f$ for two * outgoing partons. Simply returns the maximum of the results from * calling the corresponding function in the TwoCutBase objects. */ double minDurham(tcPDPtr pi, tcPDPtr pj) const; /** * Return the minimum allowed value of the transverse momentum of an * outgoing parton. This function first determines the minimum from * the corresponding function from in OneCutBase objects. If no * minimum was found, one is derived from minKTClus(), if possible. */ Energy minKT(tcPDPtr p) const; /** * Return the minimum allowed pseudo-rapidity of an outgoing parton * of the given type. The pseudo-rapidity is measured in the lab * system. Simply returns the maximum of the results from calling * the corresponding function in the OneCutBase objects. */ double minEta(tcPDPtr p) const; /** * Return the maximum allowed pseudo-rapidity of an outgoing parton * of the given type. The pseudo-rapidity is measured in the lab * system. Simply returns the minimum of the results from calling * the corresponding function in the OneCutBase objects. */ double maxEta(tcPDPtr p) const; /** * Return the minimum allowed rapidity of an outgoing parton * of the given type. The rapidity is measured in the lab * system. Simply returns the maximum of the results from calling * the corresponding function in the OneCutBase objects. */ double minRapidityMax(tcPDPtr p) const; /** * Return the maximum allowed rapidity of an outgoing parton * of the given type. The rapidity is measured in the lab * system. Simply returns the minimum of the results from calling * the corresponding function in the OneCutBase objects. */ double maxRapidityMin(tcPDPtr p) const; /** * Return the minimum allowed rapidity of an outgoing parton of the * given type in the center-of-mass system of the hard sub-process. * Only available after initSubProcess() has been called. */ double minYStar(tcPDPtr p) const; /** * Return the minimum allowed rapidity of an outgoing parton of the * given type in the center-of-mass system of the hard sub-process. * Only available after initSubProcess() has been called. */ double maxYStar(tcPDPtr p) const; /** * Return the minimum allowed value of the squared invariant mass of * a set of outgoing partons of the given types. Typically used to * cut off the tails of the mass of a resonance for * efficiency. Simply returns the maximum of the results from * calling the corresponding function in the MultiCutBase objects. */ Energy2 minS(const tcPDVector & pv) const; /** * Return the maximum allowed value of the squared invariant mass of * a set of outgoing partons of the given types. Typically used to * cut off the tails of the mass of a resonance for * efficiency. Simply returns the minimum of the results from * calling the corresponding function in the MultiCutBase objects. */ Energy2 maxS(const tcPDVector & pv) const; //@} /** @name Direct access to underlying cut objects. */ //@{ /** * Return a vector of pointers to objects of the given class (with * base class OneCutBase). */ template vector::transient_const_pointer> oneCutObjects() const; /** * Return a vector of pointers to objects of the given class (with * base class TwoCutBase). */ template vector::transient_const_pointer> twoCutObjects() const; /** * Return a vector of pointers to objects of the given class (with * base class MultiCutBase). */ template vector::transient_const_pointer> multiCutObjects() const; /** * Return the objects defining cuts on single outgoing partons from the * hard sub-process. */ const OneCutVector& oneCuts() const { return theOneCuts; } /** * Return the objects defining cuts on pairs of particles in the hard * sub-process. */ const TwoCutVector& twoCuts() const { return theTwoCuts; } /** * Return the objects defining cuts on sets of outgoing particles from the * hard sub-process. */ const MultiCutVector& multiCuts() const { return theMultiCuts; } /** * Return the jet finder */ Ptr::tptr jetFinder() const { return theJetFinder; } /** * Add a OneCutBase object. */ void add(tOneCutPtr c) { theOneCuts.push_back(c); } /** * Add a TwoCutBase object. */ void add(tTwoCutPtr c) { theTwoCuts.push_back(c); } /** * Add a MultiCutBase object. */ void add(tMultiCutPtr c) { theMultiCuts.push_back(c); } //@} public: /** @name Simple access functions. */ //@{ /** * The maximum allowed total invariant mass squared allowed for * events to be considered. */ Energy2 SMax() const { return theSMax; } /** * The total rapidity of the colliding particles corresponding to * the maximum invariant mass squared, SMax(). */ double Y() const { return theY; } /** * The invariant mass squared of the hard sub-process of the event * being considered. */ Energy2 currentSHat() const { return theCurrentSHat; } /** * The total rapidity of hard sub-process (wrt. the rest system of * the colliding particles so that currentYHat() + Y() gives the * true rapidity) of the event being considered. */ double currentYHat() const { return theCurrentYHat; } //@} /** @name Functions to inquire about specific cuts. */ //@{ /** * The minimum allowed value of \f$\hat{s}\f$. */ Energy2 sHatMin() const { return max(sqr(theMHatMin), theX1Min*theX2Min*SMax()); } /** * The maximum allowed value of \f$\hat{s}\f$. */ Energy2 sHatMax() const { return min(sqr(theMHatMax), theX1Max*theX2Max*SMax()); } /** * Check if the given \f$\hat{s}\f$ is within the cuts. */ bool sHat(Energy2 sh) const { return sh > sHatMin() && sh <= sHatMax()*(1.0 + 1000.0*Constants::epsilon); } /** * The minimum allowed value of \f$\sqrt{\hat{s}}\f$. */ Energy mHatMin() const { return max(theMHatMin, sqrt(theX1Min*theX2Min*SMax())); } /** * The maximum allowed value of \f$\sqrt{\hat{s}}\f$. */ Energy mHatMax() const { return min(theMHatMax, sqrt(theX1Max*theX2Max*SMax())); } /** * The minimum value of the rapidity of the hard sub-process * (wrt. the rest system of the colliding particles). */ double yHatMin() const; /** * The maximum value of the rapidity of the hard sub-process * (wrt. the rest system of the colliding particles). */ double yHatMax() const; /** * Check if the given \f$\hat{y}\f$ is within the cuts. */ bool yHat(double y) const; /** * The minimum value of the positive light-cone fraction of the hard * sub-process. */ double x1Min() const; /** * The maximum value of the positive light-cone fraction of the hard * sub-process. */ double x1Max() const; /** * Check if the given \f$x_1\f$ is within the cuts. */ bool x1(double x) const; /** * The minimum value of the negative light-cone fraction of the hard * sub-process. */ double x2Min() const; /** * The maximum value of the negative light-cone fraction of the hard * sub-process. */ double x2Max() const; /** * Check if the given \f$x_2\f$ is within the cuts. */ bool x2(double x) const; /** * The minimum allowed value of the scale to be used in PDF's and * coupling constants. */ Energy2 scaleMin() const { return theScaleMin; } /** * The maximum allowed value of the scale to be used in PDF's and * coupling constants. */ Energy2 scaleMax() const { return theScaleMax; } /** * Check if the given scale is within the cuts. */ bool scale(Energy2 Q2) const { return Q2 > scaleMin() && Q2 < scaleMax(); } /** * Set true if a matrix element is should be using this cut and is * mirrored along the z-axis . */ bool subMirror() const { return theSubMirror; } /** * Return the overall cut weight */ double cutWeight() const { return theCutWeight; } /** * Set the cut weight as appropriate from the call to the last n-cut * object. */ void lastCutWeight(double w) const { theLastCutWeight = w; } /** * Return the fuzziness object */ Ptr::tcptr fuzzy() const { return theFuzzyTheta; } /** * Check for value inside the given bounds and update the weight */ template bool isInside(const Value& v, const Value& lower, const Value& upper, double& weight) const { if ( !fuzzy() ) { if ( v >= lower && v <= upper ) return true; weight = 0.0; return false; } return fuzzy()->isInside(v,lower,upper,weight); } /** * Check for value inside the given bounds and update the weight */ template bool isLessThan(const Value& v, const Value& upper, double& weight) const { if ( !fuzzy() ) { if ( v <= upper ) return true; weight = 0.0; return false; } return fuzzy()->isLessThan(v,upper,weight); } /** * Check for value inside the given bounds and update the weight */ template bool isLargerThan(const Value& v, const Value& lower, double& weight) const { if ( !fuzzy() ) { if ( v >= lower ) return true; weight = 0.0; return false; } return fuzzy()->isLargerThan(v,lower,weight); } //@} public: /** * Describe the currently active cuts in the log file. */ virtual void describe() const; protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * Helper function used by the interface. */ Energy maxMHatMin() const; /** * Helper function used by the interface. */ Energy minMHatMax() const; /** * Helper function used by the interface. */ double maxYHatMin() const; /** * Helper function used by the interface. */ double minYHatMax() const; /** * Helper function used by the interface. */ double maxX1Min() const; /** * Helper function used by the interface. */ double minX1Max() const; /** * Helper function used by the interface. */ double maxX2Min() const; /** * Helper function used by the interface. */ double minX2Max() const; /** * Helper function used by the interface. */ Energy2 maxScaleMin() const; /** * Helper function used by the interface. */ Energy2 minScaleMax() const; private: /** * The maximum allowed total invariant mass squared allowed for * events to be considered. */ Energy2 theSMax; /** * The total rapidity of the colliding particles corresponding to * the maximum invariant mass squared, SMax(). */ double theY; /** * The invariant mass squared of the hard sub-process of the event * being considered. */ mutable Energy2 theCurrentSHat; /** * The total rapidity of hard sub-process (wrt. the rest system of * the colliding particles so that currentYHat() + Y() gives the * true rapidity) of the event being considered. */ mutable double theCurrentYHat; /** * The minimum allowed value of \f$\sqrt{\hat{s}}\f$. */ Energy theMHatMin; /** * The maximum allowed value of \f$\sqrt{\hat{s}}\f$. */ Energy theMHatMax; /** * The minimum value of the rapidity of the hard sub-process * (wrt. the rest system of the colliding particles). */ double theYHatMin; /** * The maximum value of the rapidity of the hard sub-process * (wrt. the rest system of the colliding particles). */ double theYHatMax; /** * The minimum value of the positive light-cone fraction of the hard * sub-process. */ double theX1Min; /** * The maximum value of the positive light-cone fraction of the hard * sub-process. */ double theX1Max; /** * The minimum value of the negative light-cone fraction of the hard * sub-process. */ double theX2Min; /** * The maximum value of the negative light-cone fraction of the hard * sub-process. */ double theX2Max; /** * The minimum allowed value of the scale to be used in PDF's and * coupling constants. */ Energy2 theScaleMin; /** * The maximum allowed value of the scale to be used in PDF's and * coupling constants. */ Energy2 theScaleMax; /** * The objects defining cuts on single outgoing partons from the * hard sub-process. */ OneCutVector theOneCuts; /** * The objects defining cuts on pairs of particles in the hard * sub-process. */ TwoCutVector theTwoCuts; /** * The objects defining cuts on sets of outgoing particles from the * hard sub-process. */ MultiCutVector theMultiCuts; /** * An optional jet finder used to define cuts on the level of * reconstructed jets. */ Ptr::ptr theJetFinder; /** * Set to true if a matrix element is should be using this cut and is * mirrored along the z-axis . */ mutable bool theSubMirror; /** * The overall cut weight */ mutable double theCutWeight; /** * The cut weight as appropriate from the call to the last n-cut * object. */ mutable double theLastCutWeight; /** * The fuzziness object */ Ptr::ptr theFuzzyTheta; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initCuts; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ Cuts & operator=(const Cuts &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of Cuts. */ template <> struct BaseClassTrait { /** Typedef of the first base class of Cuts. */ typedef Interfaced NthBase; }; /** This template specialization informs ThePEG about the name of * the Cuts class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::Cuts"; } }; /** @endcond */ } #endif /* THEPEG_Cuts_H */ diff --git a/Cuts/FastJetFinder.cc b/Cuts/FastJetFinder.cc --- a/Cuts/FastJetFinder.cc +++ b/Cuts/FastJetFinder.cc @@ -1,297 +1,295 @@ // -*- C++ -*- // // FastJetFinder.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the FastJetFinder class. // #include "FastJetFinder.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Cuts/Cuts.h" #include "fastjet/ClusterSequence.hh" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; FastJetFinder::FastJetFinder() : theDCut(ZERO), theConeRadius(0.7), theVariant(kt), theMode(inclusive), theRecombination(recoE) {} -FastJetFinder::~FastJetFinder() {} - void FastJetFinder::doinit() { fastjet::ClusterSequence::set_fastjet_banner_stream(0); } void FastJetFinder::doinitrun() { fastjet::ClusterSequence::set_fastjet_banner_stream(& CurrentGenerator::log()); // Force banner to be printed right now; suppresses later output. fastjet::ClusterSequence::print_banner(); } IBPtr FastJetFinder::clone() const { return new_ptr(*this); } IBPtr FastJetFinder::fullclone() const { return new_ptr(*this); } void FastJetFinder::describe() const { generator()->log() << "'" << name() << "' clustering jets from constituents matched by '" << unresolvedMatcher()->name() << "'\n" << "into " << (theMode == inclusive ? "inclusive" : "exclusive") << " jets recombining with the " << (theRecombination == recoPt ? "pt" : "E") << " scheme\n"; generator()->log() << "The measure used is "; switch(theVariant) { case 1: generator()->log() << "kt"; break; case 2: generator()->log() << "CA"; break; case 3: generator()->log() << "antiKt"; break; case 4: generator()->log() << "sphericalKt"; break; case 5: generator()->log() << "sphericalCA"; break; case 6: generator()->log() << "sphericalAntiKt"; break; default: assert(false); } generator()->log() << "\n"; generator()->log() << "The cone radius is R = " << theConeRadius << "\n"; if ( theMode == exclusive ) { generator()->log() << "The exclusive resolution scale in GeV is D = " << sqrt(theDCut/GeV2) << "\n"; } generator()->log() << flush; } bool FastJetFinder::cluster(tcPDVector & ptype, vector & p, tcCutsPtr, tcPDPtr, tcPDPtr) const { if ( ptype.size() <= minOutgoing() ){ return false; } tcPDVector::iterator di = ptype.begin(); vector::iterator pi = p.begin(); size_t index = 0; vector recombinables; tcPDVector ptypeBuffer; vector pBuffer; for ( ; di != ptype.end(); ++di, ++pi, index++ ) { if ( !unresolvedMatcher()->check(**di) ) { ptypeBuffer.push_back(*di); pBuffer.push_back(*pi); continue; } recombinables.push_back(fastjet::PseudoJet( (*pi).x()/GeV,(*pi).y()/GeV,(*pi).z()/GeV, (*pi).t()/GeV )); recombinables.back().set_user_index(index); } fastjet::Strategy strategy = fastjet::Best; fastjet::RecombinationScheme recomb_scheme; if ( theRecombination == recoE ) recomb_scheme = fastjet::E_scheme; else if ( theRecombination == recoPt) recomb_scheme = fastjet::pt_scheme; else assert(false); fastjet::JetAlgorithm jet_algorithm = fastjet::kt_algorithm; if ( theVariant == CA ) { jet_algorithm = fastjet::cambridge_algorithm; } else if ( theVariant == antiKt ) { jet_algorithm = fastjet::antikt_algorithm; } else if ( theVariant > 3 ) { jet_algorithm = fastjet::ee_genkt_algorithm; } fastjet::JetDefinition jet_def; if ( theVariant < 4 ) { jet_def = fastjet::JetDefinition(jet_algorithm, theConeRadius, recomb_scheme, strategy); } else { int power = 1; if ( theVariant == sphericalCA ) { power = 0; } if ( theVariant == sphericalAntiKt ) { power = -1; } jet_def = fastjet::JetDefinition(jet_algorithm, theConeRadius, power, recomb_scheme, strategy); } fastjet::ClusterSequence clust_seq(recombinables, jet_def); double dcut = 0.0; if ( theVariant != antiKt && theVariant != sphericalAntiKt ) { dcut = theDCut/GeV2; } else { dcut = theDCut != ZERO ? GeV2/theDCut : ZERO; } vector recoJets; if ( theMode == inclusive ) recoJets = clust_seq.inclusive_jets(); else if ( theMode == exclusive ) recoJets = clust_seq.exclusive_jets(dcut); if ( recoJets.size() + pBuffer.size() == p.size() ){ return false; } else { tcPDVector ptypeNew; vector pNew; for (vector::const_iterator iter = recoJets.begin(); iter != recoJets.end(); iter++){ ptypeNew.push_back(ptype[iter->constituents().begin()->user_index()]); pNew.push_back(LorentzMomentum(iter->px()*GeV, iter->py()*GeV, iter->pz()*GeV, iter->E()*GeV)); } di = ptypeBuffer.begin(); pi = pBuffer.begin(); for (; di != ptypeBuffer.end(); di++, pi++){ ptypeNew.push_back(*di); pNew.push_back(*pi); } ptype = ptypeNew; p = pNew; return true; } } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FastJetFinder::persistentOutput(PersistentOStream & os) const { os << ounit(theDCut,GeV2) << theConeRadius << theVariant << theMode << theRecombination; } void FastJetFinder::persistentInput(PersistentIStream & is, int) { is >> iunit(theDCut,GeV2) >> theConeRadius >> theVariant >> theMode >> theRecombination; } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeFastJetFinder("ThePEG::FastJetFinder", "FastJetFinder.so"); void FastJetFinder::Init() { static ClassDocumentation documentation ("FastJetFinder implements the class of longitudinally invariant kt " "jet clustering algorithms, as relevant for cuts on the real " "emission contribution to a NLO calculation. Recombination is " "exclusively performed using the pt scheme."); static Parameter interfaceDCut ("DCut", "The distance cut, when acting exclusively. " "The inverse is taken for the anti-kt algorithm, " "while for the Cambridge/Aachen variant dCut/GeV2 is used.", &FastJetFinder::theDCut, GeV2, 0.0*GeV2, 0.0*GeV2, 0*GeV2, false, false, Interface::lowerlim); static Parameter interfaceConeRadius ("ConeRadius", "The cone radius R used in inclusive mode.", &FastJetFinder::theConeRadius, 0.7, 0.0, 10.0, false, false, Interface::limited); static Switch interfaceVariant ("Variant", "The variant to use.", &FastJetFinder::theVariant, kt, false, false); static SwitchOption interfaceVariantKt (interfaceVariant, "Kt", "Kt algorithm.", kt); static SwitchOption interfaceVariantCA (interfaceVariant, "CA", "Cambridge/Aachen algorithm.", CA); static SwitchOption interfaceVariantAntiKt (interfaceVariant, "AntiKt", "Anti kt algorithm.", antiKt); static SwitchOption interfaceVariantSphericalKt (interfaceVariant, "SphericalKt", "Spherical kt algorithm.", sphericalKt); static SwitchOption interfaceVariantSphericalCA (interfaceVariant, "SphericalCA", "Spherical Cambridge/Aachen algorithm.", sphericalCA); static SwitchOption interfaceVariantSphericalAntiKt (interfaceVariant, "SphericalAntiKt", "Spherical anti kt algorithm.", sphericalAntiKt); static Switch interfaceMode ("Mode", "The mode to use.", &FastJetFinder::theMode, inclusive, false, false); static SwitchOption interfaceModeInclusive (interfaceMode, "Inclusive", "Find inclusive jets.", inclusive); static SwitchOption interfaceModeExclusive (interfaceMode, "Exclusive", "Find exclusive jets.", exclusive); static Switch interfaceRecombination ("RecombinationScheme", "The recombination scheme to use.", &FastJetFinder::theRecombination, recoE, false, false); static SwitchOption interfaceRecombinationPt (interfaceRecombination, "Pt", "Add transverse momenta", recoPt); static SwitchOption interfaceRecombinationE (interfaceRecombination, "E", "Add the four-momenta", recoE); } diff --git a/Cuts/FastJetFinder.h b/Cuts/FastJetFinder.h --- a/Cuts/FastJetFinder.h +++ b/Cuts/FastJetFinder.h @@ -1,187 +1,179 @@ // -*- C++ -*- // // FastJetFinder.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_FastJetFinder_H #define THEPEG_FastJetFinder_H // // This is the declaration of the FastJetFinder class. // #include "ThePEG/Cuts/JetFinder.h" namespace ThePEG { /** * FastJetFinder implements the class of longitudinally invariant kt * jet clustering algorithms. * * @see \ref FastJetFinderInterfaces "The interfaces" * defined for FastJetFinder. */ class FastJetFinder: public JetFinder { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FastJetFinder(); - /** - * The destructor. - */ - virtual ~FastJetFinder(); - //@} - public: /** * Perform jet clustering on the given outgoing particles. * Optionally, information on the incoming particles is provided. * Return true, if a clustering has been performed. */ virtual bool cluster(tcPDVector & ptype, vector & p, tcCutsPtr parent, tcPDPtr t1 = tcPDPtr(), tcPDPtr t2 = tcPDPtr()) const; /** * Describe this jet fined. */ virtual void describe() const; public: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object. Called in the read phase. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The resolution cut. */ Energy2 theDCut; /** * The `cone radius' R. */ double theConeRadius; /** * The possible variants. */ enum variants { kt = 1, CA = 2, antiKt = 3, sphericalKt = 4, sphericalCA = 5, sphericalAntiKt = 6 }; /** * The variant. */ int theVariant; /** * The possible modes. */ enum modes { inclusive = 1, exclusive = 2 }; /** * The mode. */ int theMode; /** * The possible recombination schemes. */ enum recombinations { recoPt = 1, recoE = 2 }; /** * The recombination scheme */ int theRecombination; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FastJetFinder & operator=(const FastJetFinder &) = delete; }; } #endif /* THEPEG_FastJetFinder_H */ diff --git a/Cuts/FuzzyTheta.cc b/Cuts/FuzzyTheta.cc --- a/Cuts/FuzzyTheta.cc +++ b/Cuts/FuzzyTheta.cc @@ -1,82 +1,80 @@ // -*- C++ -*- // // FuzzyTheta.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the FuzzyTheta class. // #include "FuzzyTheta.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; FuzzyTheta::FuzzyTheta() : theEnergyWidth(1*GeV), theRapidityWidth(0.1), theAngularWidth(0.1) {} -FuzzyTheta::~FuzzyTheta() {} - IBPtr FuzzyTheta::clone() const { return new_ptr(*this); } IBPtr FuzzyTheta::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void FuzzyTheta::persistentOutput(PersistentOStream & os) const { os << ounit(theEnergyWidth,GeV) << theRapidityWidth << theAngularWidth; } void FuzzyTheta::persistentInput(PersistentIStream & is, int) { is >> iunit(theEnergyWidth,GeV) >> theRapidityWidth >> theAngularWidth; } ClassDescription FuzzyTheta::initFuzzyTheta; void FuzzyTheta::Init() { static ClassDocumentation documentation ("FuzzyTheta implements fuzzy cut prescriptions."); static Parameter interfaceEnergyWidth ("EnergyWidth", "The width of smeared energy- and momentum-type cuts.", &FuzzyTheta::theEnergyWidth, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceRapidityWidth ("RapidityWidth", "The width of smeared rapidity-type cuts.", &FuzzyTheta::theRapidityWidth, 0.1, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceAngularWidth ("AngularWidth", "The width of smeared angular-type cuts.", &FuzzyTheta::theAngularWidth, 0.1, 0.0, Constants::pi, false, false, Interface::limited); } diff --git a/Cuts/FuzzyTheta.h b/Cuts/FuzzyTheta.h --- a/Cuts/FuzzyTheta.h +++ b/Cuts/FuzzyTheta.h @@ -1,342 +1,334 @@ // -*- C++ -*- // // FuzzyTheta.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_FuzzyTheta_H #define ThePEG_FuzzyTheta_H // // This is the declaration of the FuzzyTheta class. // #include "ThePEG/Interface/Interfaced.h" #include "ThePEG/Repository/EventGenerator.h" #include namespace ThePEG { namespace CutTypes { /** * Identify an energy-type cut */ struct Energy {}; /** * Identify a momentum-type cut */ struct Momentum {}; /** * Identify a rapidity-type cut */ struct Rapidity {}; /** * Identify an azimuth-type cut */ struct Azimuth {}; /** * Identify an polar-angle-type cut */ struct Polar {}; } /** * FuzzyTheta implements fuzzy cut prescriptions * * @see \ref FuzzyThetaInterfaces "The interfaces" * defined for FuzzyTheta. */ class FuzzyTheta: public Interfaced { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ FuzzyTheta(); - /** - * The destructor. - */ - virtual ~FuzzyTheta(); - //@} - public: /** * Return the (compact) support of the delta approximation * considered, given its center value. This default version assumes * a box approximation. All values are assumed to be in units of the * width considered. */ virtual pair support(double x) const { return make_pair(x-0.5,x+0.5); } /** * Return the overlap integral of the delta approximation with the * given box and center. This default version assumes * a box approximation. All values are assumed to be in units of the * width considered. */ virtual double overlap(double x, const pair& box) const { if ( x - 0.5 >= box.first && x + 0.5 <= box.second ) return 1.; if ( x - 0.5 > box.second || x + 0.5 < box.first ) return 0.; return min(box.second,x+0.5) - max(box.first,x-0.5); } /** * Return the overlap, optionally considering absolute lower and * upper bounds. */ double overlap(double x, pair box, const pair& support) const { box.first = max(box.first,support.first); box.second = min(box.second,support.second); assert(x >= support.first && x <= support.second); assert(support.second - support.first >= 1.); if ( x - 0.5 < support.first ) x = support.first + 0.5; if ( x + 0.5 > support.second ) x = support.second - 0.5; return overlap(x,box); } /** * Return the bounds for an energy-type cut */ pair bounds(const CutTypes::Energy&) const { return make_pair(0.,generator()->maximumCMEnergy()/theEnergyWidth); } /** * Return the width for an energy-type cut */ Energy width(const CutTypes::Energy&) const { return theEnergyWidth; } /** * Return the bounds for a momentum-type cut */ pair bounds(const CutTypes::Momentum&) const { return make_pair(0.,0.5*generator()->maximumCMEnergy()/theEnergyWidth); } /** * Return the width for a momentum-type cut */ Energy width(const CutTypes::Momentum&) const { return theEnergyWidth; } /** * Return the bounds for a rapidity-type cut */ pair bounds(const CutTypes::Rapidity&) const { return make_pair(-Constants::MaxRapidity/theRapidityWidth, Constants::MaxRapidity/theRapidityWidth); } /** * Return the width for a rapidity-type cut */ double width(const CutTypes::Rapidity&) const { return theRapidityWidth; } /** * Return the bounds for a azimuth-type cut */ pair bounds(const CutTypes::Azimuth&) const { return make_pair(0.0,2.*Constants::pi/theAngularWidth); } /** * Return the width for a azimuth-type cut */ double width(const CutTypes::Azimuth&) const { return theAngularWidth; } /** * Return the bounds for a polar-angle-type cut */ pair bounds(const CutTypes::Polar&) const { return make_pair(0.0,Constants::pi/theAngularWidth); } /** * Return the width for a polar-type cut */ double width(const CutTypes::Polar&) const { return theAngularWidth; } /** * Check for value inside the given bounds and update the weight */ template bool isInside(const Value& v, const Value& lower, const Value& upper, double& weight) const { CutType type; Value w = width(type); weight *= overlap(v/w,pair(lower/w,upper/w),bounds(type)); if ( weight == 0.0 ) return false; return true; } /** * Check for value inside the given bounds and update the weight */ template bool isLessThan(const Value& v, const Value& upper, double& weight) const { CutType type; Value w = width(type); pair b = bounds(type); weight *= overlap(v/w,pair(b.first,upper/w),b); if ( weight == 0.0 ) return false; return true; } /** * Check for value inside the given bounds and update the weight */ template bool isLargerThan(const Value& v, const Value& lower, double& weight) const { CutType type; Value w = width(type); pair b = bounds(type); weight *= overlap(v/w,pair(lower/w,b.first),b); if ( weight == 0.0 ) return false; return true; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The width to be considered for momenta */ Energy theEnergyWidth; /** * The width to be considered for rapidity quantities */ double theRapidityWidth; /** * The width to be considered for angular quantities */ double theAngularWidth; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initFuzzyTheta; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ FuzzyTheta & operator=(const FuzzyTheta &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of FuzzyTheta. */ template <> struct BaseClassTrait { /** Typedef of the first base class of FuzzyTheta. */ typedef Interfaced NthBase; }; /** This template specialization informs ThePEG about the name of * the FuzzyTheta class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::FuzzyTheta"; } }; /** @endcond */ } #endif /* ThePEG_FuzzyTheta_H */ diff --git a/Cuts/JetCuts.cc b/Cuts/JetCuts.cc --- a/Cuts/JetCuts.cc +++ b/Cuts/JetCuts.cc @@ -1,232 +1,230 @@ // -*- C++ -*- // // JetCuts.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the JetCuts class. // #include "JetCuts.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Repository/CurrentGenerator.h" using namespace ThePEG; JetCuts::JetCuts() : theOrdering(orderPt) {} -JetCuts::~JetCuts() {} - void JetCuts::describe() const { CurrentGenerator::log() << name() << " cutting on jets ordered in " << (ordering() == orderPt ? "pt " : "y ") << " with regions:\n"; for ( vector::ptr>::const_iterator r = jetRegions().begin(); r != jetRegions().end(); ++r ) (**r).describe(); if ( !jetPairRegions().empty() ) { CurrentGenerator::log() << "and jet pair cuts:\n"; for ( vector::ptr>::const_iterator r = jetPairRegions().begin(); r != jetPairRegions().end(); ++r ) (**r).describe(); for ( vector::ptr>::const_iterator r = multiJetRegions().begin(); r != multiJetRegions().end(); ++r ) (**r).describe(); } if ( !jetVetoRegions().empty() ) { CurrentGenerator::log() << "vetoing jets inside:\n"; for ( vector::ptr>::const_iterator r = jetVetoRegions().begin(); r != jetVetoRegions().end(); ++r ) (**r).describe(); } CurrentGenerator::log() << "\n"; } IBPtr JetCuts::clone() const { return new_ptr(*this); } IBPtr JetCuts::fullclone() const { return new_ptr(*this); } void JetCuts::persistentOutput(PersistentOStream & os) const { os << theUnresolvedMatcher << theJetRegions << theJetVetoRegions << theJetPairRegions << theMultiJetRegions << theOrdering; } void JetCuts::persistentInput(PersistentIStream & is, int) { is >> theUnresolvedMatcher >> theJetRegions >> theJetVetoRegions >> theJetPairRegions >> theMultiJetRegions >> theOrdering; } struct PtLarger { inline bool operator()(const LorentzMomentum& a, const LorentzMomentum& b) const { return a.perp() > b.perp(); } }; struct YLess { inline bool operator()(const LorentzMomentum& a, const LorentzMomentum& b) const { return a.rapidity() < b.rapidity(); } }; bool JetCuts::passCuts(tcCutsPtr parent, const tcPDVector & ptype, const vector & p) const { vector jets; tcPDVector::const_iterator ptypeit = ptype.begin(); vector::const_iterator pit = p.begin(); for ( ; ptypeit != ptype.end(); ++ptypeit, ++pit ) if ( unresolvedMatcher()->check(**ptypeit) ) jets.push_back(*pit); if ( ordering() == orderPt ) { sort(jets.begin(),jets.end(),PtLarger()); } else if ( ordering() == orderY ) { sort(jets.begin(),jets.end(),YLess()); } else assert(false); for ( vector::ptr>::const_iterator r = jetRegions().begin(); r != jetRegions().end(); ++r ) (**r).reset(); set matchedJets; for ( size_t k = 0; k < jets.size(); ++k ) { for ( vector::ptr>::const_iterator r = jetRegions().begin(); r != jetRegions().end(); ++r ) { if ( (**r).matches(parent,k+1,jets[k]) ) { matchedJets.insert(k+1); break; } } } double cutWeight = 1.0; bool pass = true; for ( vector::ptr>::const_iterator r = jetRegions().begin(); r != jetRegions().end(); ++r ) { pass &= (**r).didMatch(); cutWeight *= (**r).cutWeight(); if ( !pass ) { parent->lastCutWeight(0.0); return false; } } for ( vector::ptr>::const_iterator r = jetPairRegions().begin(); r != jetPairRegions().end(); ++r ) { pass &= (**r).matches(parent); cutWeight *= (**r).cutWeight(); if ( !pass ) { parent->lastCutWeight(0.0); return false; } } for ( vector::ptr>::const_iterator r = multiJetRegions().begin(); r != multiJetRegions().end(); ++r ) { pass &= (**r).matches(); cutWeight *= (**r).cutWeight(); if ( !pass ) { parent->lastCutWeight(0.0); return false; } } if ( !jetVetoRegions().empty() ) { for ( size_t k = 0; k < jets.size(); ++k ) { if ( matchedJets.find(k+1) != matchedJets.end() ) continue; for ( vector::ptr>::const_iterator r = jetVetoRegions().begin(); r != jetVetoRegions().end(); ++r ) { pass &= !(**r).matches(parent,k+1,jets[k]); cutWeight *= 1. - (**r).cutWeight(); if ( !pass ) { parent->lastCutWeight(0.0); return false; } } } } parent->lastCutWeight(cutWeight); return pass; } ClassDescription JetCuts::initJetCuts; // Definition of the static class description member. void JetCuts::Init() { static ClassDocumentation documentation ("JetCuts combines various JetRegion and JetPairRegion objects into a " "cut object."); static Reference interfaceUnresolvedMatcher ("UnresolvedMatcher", "A matcher identifying unresolved partons", &JetCuts::theUnresolvedMatcher, false, false, true, false, false); static RefVector interfaceJetRegions ("JetRegions", "The jet regions to be used.", &JetCuts::theJetRegions, -1, false, false, true, false, false); static RefVector interfaceJetVetoRegions ("JetVetoRegions", "The jet veto regions to be used.", &JetCuts::theJetVetoRegions, -1, false, false, true, false, false); static RefVector interfaceJetPairRegions ("JetPairRegions", "The jet pair regions to be used.", &JetCuts::theJetPairRegions, -1, false, false, true, false, false); static RefVector interfaceMultiJetRegions ("MultiJetRegions", "The multi jet regions to be used.", &JetCuts::theMultiJetRegions, -1, false, false, true, false, false); static Switch interfaceOrdering ("Ordering", "The ordering to apply on jets.", &JetCuts::theOrdering, orderPt, false, false); static SwitchOption interfaceOrderingOrderPt (interfaceOrdering, "OrderPt", "Order in decreasing transverse momentum.", orderPt); static SwitchOption interfaceOrderingOrderY (interfaceOrdering, "OrderY", "Order in rapidity.", orderY); } diff --git a/Cuts/JetCuts.h b/Cuts/JetCuts.h --- a/Cuts/JetCuts.h +++ b/Cuts/JetCuts.h @@ -1,232 +1,224 @@ // -*- C++ -*- // // JetCuts.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_JetCuts_H #define THEPEG_JetCuts_H // // This is the declaration of the JetCuts class. // #include "ThePEG/Cuts/MultiCutBase.h" #include "ThePEG/PDT/MatcherBase.h" #include "ThePEG/Cuts/JetRegion.h" #include "ThePEG/Cuts/JetPairRegion.h" #include "ThePEG/Cuts/MultiJetRegion.h" namespace ThePEG { /** * JetCuts combines various JetRegion and JetPairRegion objects into a * cut object. * * @see JetRegion * @see JetPairRegion * * @see \ref JetCutsInterfaces "The interfaces" * defined for JetCuts. */ class JetCuts: public MultiCutBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ JetCuts(); - /** - * The destructor. - */ - virtual ~JetCuts(); - //@} - public: /** @name Overridden virtual functions defined in the base class. */ //@{ /** * Return true if a set of outgoing particles with typea \a ptype * and corresponding momenta \a p passes the cuts. */ virtual bool passCuts(tcCutsPtr parent, const tcPDVector & ptype, const vector & p) const; //@} /** * Describe the currently active cuts in the log file. */ virtual void describe() const; public: /** * Return the matcher for unresolved partons. */ Ptr::tptr unresolvedMatcher() const { return theUnresolvedMatcher; } /** * Return the jet regions to match. */ const vector::ptr>& jetRegions() const { return theJetRegions; } /** * Return the jet veto regions to check. */ const vector::ptr>& jetVetoRegions() const { return theJetVetoRegions; } /** * Return the jet pair regions to match. */ const vector::ptr>& jetPairRegions() const { return theJetPairRegions; } /** * Return the multi jet regions to match. */ const vector::ptr>& multiJetRegions() const { return theMultiJetRegions; } /** * Enumerate the ordering to apply on jets */ enum Orderings { orderPt = 1, orderY = 2 }; /** * Return the ordering */ int ordering() const { return theOrdering; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * A matcher for unresolved partons. */ Ptr::ptr theUnresolvedMatcher; /** * The jet regions to match. */ vector::ptr> theJetRegions; /** * The jet veto regions to check */ vector::ptr> theJetVetoRegions; /** * The jet pair regions to match. */ vector::ptr> theJetPairRegions; /** * The multi jet regions to match. */ vector::ptr> theMultiJetRegions; /** * Types of the ordering to apply on jets */ int theOrdering; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initJetCuts; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ JetCuts & operator=(const JetCuts &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of JetCuts. */ template <> struct BaseClassTrait { /** Typedef of the first base class of JetCuts. */ typedef MultiCutBase NthBase; }; /** This template specialization informs ThePEG about the name of * the JetCuts class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::JetCuts"; } /** Return the name of the shared library be loaded to get * access to the JetCuts class and every other class it uses * (except the base class). */ static string library() { return "JetCuts.so"; } }; /** @endcond */ } #endif /* THEPEG_JetCuts_H */ diff --git a/Cuts/JetFinder.cc b/Cuts/JetFinder.cc --- a/Cuts/JetFinder.cc +++ b/Cuts/JetFinder.cc @@ -1,113 +1,111 @@ // -*- C++ -*- // // JetFinder.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the JetFinder class. // #include "JetFinder.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; JetFinder::JetFinder() : theMinOutgoing(1), theRestrictConstituents(false), theConstituentRapidityRange(Constants::MaxRapidity,Constants::MaxRapidity) {} -JetFinder::~JetFinder() {} - string JetFinder::doYRange(string in) { istringstream ins(in); double first, second; ins >> first >> second; if ( first > second ) swap(first,second); theConstituentRapidityRange = make_pair(first,second); return ""; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void JetFinder::persistentOutput(PersistentOStream & os) const { os << theUnresolvedMatcher << theMinOutgoing << theRestrictConstituents << theConstituentRapidityRange; } void JetFinder::persistentInput(PersistentIStream & is, int) { is >> theUnresolvedMatcher >> theMinOutgoing >> theRestrictConstituents >> theConstituentRapidityRange; } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeAbstractClass describeJetFinder("ThePEG::JetFinder", ""); void JetFinder::Init() { static ClassDocumentation documentation ("JetFinder defines an interface to jet finders to be used when cuts " "should actually be defined on the level of reconstructed jets such " "as typically encountered in higher order corrections."); static Reference interfaceUnresolvedMatcher ("UnresolvedMatcher", "A matcher identifying unresolved partons", &JetFinder::theUnresolvedMatcher, false, false, true, false, false); static Parameter interfaceMinOutgoing ("MinOutgoing", "The minimum number of outgoing partons to be clustered.", &JetFinder::theMinOutgoing, 1, 1, 0, false, false, Interface::lowerlim); static Switch interfaceRestrictConstituents ("RestrictConstituents", "Restrict the constituents for clustering.", &JetFinder::theRestrictConstituents, false, false, false); static SwitchOption interfaceRestrictConstituentsYes (interfaceRestrictConstituents, "Yes", "", true); static SwitchOption interfaceRestrictConstituentsNo (interfaceRestrictConstituents, "No", "", false); static Command interfaceYRange ("ConstituentRapidityRange", "Restrict clustering to a rapidity range.", &JetFinder::doYRange, false); } diff --git a/Cuts/JetFinder.h b/Cuts/JetFinder.h --- a/Cuts/JetFinder.h +++ b/Cuts/JetFinder.h @@ -1,175 +1,167 @@ // -*- C++ -*- // // JetFinder.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_JetFinder_H #define THEPEG_JetFinder_H // // This is the declaration of the JetFinder class. // #include "ThePEG/Interface/Interfaced.h" #include "ThePEG/PDT/MatcherBase.h" #include "Cuts.fh" namespace ThePEG { /** * JetFinder defines an interface to jet finders to be used when cuts * should actually be defined on the level of reconstructed jets such * as typically encountered in higher order corrections. * * @see \ref JetFinderInterfaces "The interfaces" * defined for JetFinder. */ class JetFinder: public Interfaced { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ JetFinder(); - /** - * The destructor. - */ - virtual ~JetFinder(); - //@} - public: /** * Perform jet clustering on the given outgoing particles. * Optionally, information on the incoming particles is provided. * Return true, if a clustering has been performed. */ virtual bool cluster(tcPDVector & ptype, vector & p, tcCutsPtr parent, tcPDPtr t1 = tcPDPtr(), tcPDPtr t2 = tcPDPtr()) const = 0; /** * Return the matcher for unresolved partons. */ Ptr::tptr unresolvedMatcher() const { return theUnresolvedMatcher; } /** * Set the minimum number of outgoing partons on which clustering * should be performed. */ void minOutgoing(unsigned int n) { theMinOutgoing = n; } /** * Return the minimum number of outgoing partons on which clustering * should be performed. */ unsigned int minOutgoing() const { return theMinOutgoing; } /** * Return true, if jets should only be constructed from matching * objects inside a given rapidity interval. */ bool restrictConsitutents() const { return theRestrictConstituents; } /** * Jets should only be constructed from matching * objects inside a given rapidity interval. */ void restrictConsitutents(bool on) { theRestrictConstituents = on; } /** * Return the rapidity interval within objects should be considered * for clustering, if appropriate */ const pair& constituentRapidityRange() const { return theConstituentRapidityRange; } /** * Set the rapidity interval within objects should be considered * for clustering, if appropriate */ void constituentRapidityRange(const pair& r) { theConstituentRapidityRange = r; } /** * Describe this jet finder */ virtual void describe() const = 0; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * Command to insert a rapidity range */ string doYRange(string); /** * A matcher for unresolved partons. */ Ptr::ptr theUnresolvedMatcher; /** * The minimum number of outgoing partons on which clustering * should be performed. */ unsigned int theMinOutgoing; /** * True, if jets should only be constructed from matching * objects inside a given rapidity interval. */ bool theRestrictConstituents; /** * The rapidity interval within objects should be considered * for clustering, if appropriate */ pair theConstituentRapidityRange; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ JetFinder & operator=(const JetFinder &) = delete; }; } #endif /* THEPEG_JetFinder_H */ diff --git a/Cuts/JetPairRegion.cc b/Cuts/JetPairRegion.cc --- a/Cuts/JetPairRegion.cc +++ b/Cuts/JetPairRegion.cc @@ -1,209 +1,207 @@ // -*- C++ -*- // // JetPairRegion.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the JetPairRegion class. // #include "JetPairRegion.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; JetPairRegion::JetPairRegion() : theMassMin(0.*GeV), theMassMax(Constants::MaxEnergy), theDeltaRMin(0.0), theDeltaRMax(Constants::MaxRapidity), theDeltaYMin(0.0), theDeltaYMax(Constants::MaxRapidity), theOppositeHemispheres(false), theCutWeight(1.0) {} -JetPairRegion::~JetPairRegion() {} - IBPtr JetPairRegion::clone() const { return new_ptr(*this); } IBPtr JetPairRegion::fullclone() const { return new_ptr(*this); } void JetPairRegion::describe() const { CurrentGenerator::log() << "JetPairRegion '" << name() << "' matching " << " JetRegions '" << firstRegion()->name() << "' and '" << secondRegion()->name() << "' with\n"; CurrentGenerator::log() << "m = " << massMin()/GeV << " .. " << massMax()/GeV << " GeV\n" << "dR = " << deltaRMin() << " .. " << deltaRMax() << "\n" << "dy = " << deltaYMin() << " .. " << deltaYMax() << "\n"; } bool JetPairRegion::matches(tcCutsPtr parent) { if ( !firstRegion()->didMatch() || !secondRegion()->didMatch() ) { theCutWeight = 0.0; return false; } theCutWeight = 1.0; const LorentzMomentum& pi = firstRegion()->lastMomentum(); const LorentzMomentum& pj = secondRegion()->lastMomentum(); Energy m = (pi+pj).m(); if ( !(firstRegion()->lessThanEnergy(massMin(),m,theCutWeight) && firstRegion()->lessThanEnergy(m,massMax(),theCutWeight)) ) return false; double dy = abs(pi.rapidity() - pj.rapidity()); if ( !(firstRegion()->lessThanRapidity(deltaYMin(),dy,theCutWeight) && firstRegion()->lessThanRapidity(dy,deltaYMax(),theCutWeight)) ) return false; double dphi = abs(pi.phi() - pj.phi()); if ( dphi > Constants::pi ) dphi = 2.0*Constants::pi - dphi; double dR = sqrt(sqr(dy)+sqr(dphi)); if ( !(firstRegion()->lessThanRapidity(deltaRMin(),dR,theCutWeight) && firstRegion()->lessThanRapidity(dR,deltaRMax(),theCutWeight)) ) return false; double py = (pi.rapidity() + parent->currentYHat()) * (pj.rapidity() + parent->currentYHat()); if ( theOppositeHemispheres && !firstRegion()->lessThanRapidity(py,0.0,theCutWeight) ) return false; return true; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void JetPairRegion::persistentOutput(PersistentOStream & os) const { os << theFirstRegion << theSecondRegion << ounit(theMassMin,GeV) << ounit(theMassMax,GeV) << theDeltaRMin << theDeltaRMax << theDeltaYMin << theDeltaYMax << theOppositeHemispheres << theCutWeight; } void JetPairRegion::persistentInput(PersistentIStream & is, int) { is >> theFirstRegion >> theSecondRegion >> iunit(theMassMin,GeV) >> iunit(theMassMax,GeV) >> theDeltaRMin >> theDeltaRMax >> theDeltaYMin >> theDeltaYMax >> theOppositeHemispheres >> theCutWeight; } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeThePEGJetPairRegion("ThePEG::JetPairRegion", "JetCuts.so"); void JetPairRegion::Init() { static ClassDocumentation documentation ("JetPairRegion implements constraints on jets matching two jet regions."); static Reference interfaceFirstRegion ("FirstRegion", "The first region to act on.", &JetPairRegion::theFirstRegion, false, false, true, false, false); static Reference interfaceSecondRegion ("SecondRegion", "The second region to act on.", &JetPairRegion::theSecondRegion, false, false, true, false, false); static Parameter interfaceMassMin ("MassMin", "The minimum jet-jet invariant mass.", &JetPairRegion::theMassMin, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceMassMax ("MassMax", "The maximum jet-jet invariant mass.", &JetPairRegion::theMassMax, GeV, Constants::MaxEnergy, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceDeltaRMin ("DeltaRMin", "The minimum jet-jet lego-plot separation.", &JetPairRegion::theDeltaRMin, 0.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceDeltaRMax ("DeltaRMax", "The maximum jet-jet lego-plot separation.", &JetPairRegion::theDeltaRMax, Constants::MaxRapidity, 0, 0, false, false, Interface::lowerlim); static Parameter interfaceDeltaYMin ("DeltaYMin", "The minimum jet-jet rapidity separation.", &JetPairRegion::theDeltaYMin, 0.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter interfaceDeltaYMax ("DeltaYMax", "The maximum jet-jet rapidity separation.", &JetPairRegion::theDeltaYMax, Constants::MaxRapidity, 0, 0, false, false, Interface::lowerlim); static Switch interfaceOppositeHemispheres ("OppositeHemispheres", "Should the jets go into opposite detector hemispheres?", &JetPairRegion::theOppositeHemispheres, false, true, false); static SwitchOption interfaceOppositeHemispheresTrue (interfaceOppositeHemispheres, "True", "Require jets to be in different hemispheres", true); static SwitchOption interfaceOppositeHemispheresFalse (interfaceOppositeHemispheres, "False", "Do not require jets to be in different hemispheres", false); static SwitchOption interfaceOppositeHemispheresYes (interfaceOppositeHemispheres, "Yes", "Require jets to be in different hemispheres", true); static SwitchOption interfaceOppositeHemispheresNo (interfaceOppositeHemispheres, "No", "Do not require jets to be in different hemispheres", false); } diff --git a/Cuts/JetPairRegion.h b/Cuts/JetPairRegion.h --- a/Cuts/JetPairRegion.h +++ b/Cuts/JetPairRegion.h @@ -1,215 +1,207 @@ // -*- C++ -*- // // JetPairRegion.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_JetPairRegion_H #define ThePEG_JetPairRegion_H // // This is the declaration of the JetPairRegion class. // #include "ThePEG/Cuts/JetRegion.h" namespace ThePEG { /** * JetPairRegion implements constraints on jets matching two jet regions. * * @see JetRegion * @see JetCuts * * @see \ref JetPairRegionInterfaces "The interfaces" * defined for JetPairRegion. */ class JetPairRegion: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ JetPairRegion(); - /** - * The destructor. - */ - virtual ~JetPairRegion(); - //@} - public: /** * Return the first jet region to act on. */ Ptr::tptr firstRegion() const { return theFirstRegion; } /** * Return the second jet region to act on. */ Ptr::tptr secondRegion() const { return theSecondRegion; } /** * Return the minimum jet-jet invariant mass. */ Energy massMin() const { return theMassMin; } /** * Return the maximum jet-jet invariant mass. */ Energy massMax() const { return theMassMax; } /** * Return the minimum jet-jet lego-plot separation. */ double deltaRMin() const { return theDeltaRMin; } /** * Return the maximum jet-jet lego-plot separation. */ double deltaRMax() const { return theDeltaRMax; } /** * Return the minimum jet-jet rapidity separation. */ double deltaYMin() const { return theDeltaYMin; } /** * Return the maximum jet-jet rapidity separation. */ double deltaYMax() const { return theDeltaYMax; } /** * Return the cut weight encountered from the last call to matches() */ double cutWeight() const { return theCutWeight; } public: /** * Describe the currently active cuts in the log file. */ virtual void describe() const; /** * Return true, if the requirements on the jet regions are fullfilled. */ virtual bool matches(tcCutsPtr parent); public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * The first jet region to act on. */ Ptr::ptr theFirstRegion; /** * The second jet region to act on. */ Ptr::ptr theSecondRegion; /** * The minimum jet-jet invariant mass. */ Energy theMassMin; /** * The maximum jet-jet invariant mass. */ Energy theMassMax; /** * The minimum jet-jet lego-plot separation. */ double theDeltaRMin; /** * The maximum jet-jet lego-plot separation. */ double theDeltaRMax; /** * The minimum jet-jet rapidity separation. */ double theDeltaYMin; /** * The maximum jet-jet rapidity separation. */ double theDeltaYMax; /** * Should the jets go into opposite detector hemispheres? */ bool theOppositeHemispheres; /** * The cut weight encountered from the last call to matches() */ double theCutWeight; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ JetPairRegion & operator=(const JetPairRegion &) = delete; }; } #endif /* ThePEG_JetPairRegion_H */ diff --git a/Cuts/JetRegion.cc b/Cuts/JetRegion.cc --- a/Cuts/JetRegion.cc +++ b/Cuts/JetRegion.cc @@ -1,267 +1,265 @@ // -*- C++ -*- // // JetRegion.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the JetRegion class. // #include "JetRegion.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Utilities/StringUtils.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; JetRegion::JetRegion() : thePtMin(0.*GeV), thePtMax(Constants::MaxEnergy), theDidMatch(false), theLastNumber(0), theFuzzy(false), theCutWeight(1.0), theEnergyCutWidth(1.0*GeV), theRapidityCutWidth(0.1) {} -JetRegion::~JetRegion() {} - IBPtr JetRegion::clone() const { return new_ptr(*this); } IBPtr JetRegion::fullclone() const { return new_ptr(*this); } string JetRegion::doYRange(string in) { istringstream ins(StringUtils::stripws(in)); theYRanges.clear(); while ( !ins.eof() ) { double first, second; ins >> first; if ( ins.eof() ) throw Exception() << "need an even number n of values to define n/2 rapidity intervals" << Exception::abortnow; ins >> second; if ( first > second ) swap(first,second); theYRanges.push_back(make_pair(first,second)); } return ""; } void JetRegion::describe() const { CurrentGenerator::log() << "JetRegion '" << name() << "' matching "; if ( accepts().empty() ) CurrentGenerator::log() << "any jets "; else { CurrentGenerator::log() << "jets "; for ( vector::const_iterator k = accepts().begin(); k != accepts().end(); ++k ) { CurrentGenerator::log() << "#" << *k; if ( k != --accepts().end() ) CurrentGenerator::log() << ", "; else CurrentGenerator::log() << " "; } } CurrentGenerator::log() << " within:\n"; CurrentGenerator::log() << "pt = " << ptMin()/GeV << " .. " << ptMax()/GeV << " GeV\n"; for ( vector >::const_iterator r = yRanges().begin(); r != yRanges().end(); ++r ) { CurrentGenerator::log() << "y = " << r->first << " .. " << r->second << "\n"; } } double step(double r) { if ( r < -0.5 ) return 0.0; if ( r > 0.5 ) return 1.0; return r+0.5; } bool JetRegion::lessThanEnergy(Energy a, Energy b, double& weight) const { if ( !fuzzy() ) { if ( a < b ) { weight = 1.0; return true; } weight = 0.0; return false; } double w = step((b-a)/theEnergyCutWidth); if ( w == 0.0 ) { weight = 0.0; return false; } weight *= w; return true; } bool JetRegion::lessThanRapidity(double a, double b, double& weight) const { if ( !fuzzy() ) { if ( a < b ) { weight = 1.0; return true; } weight = 0.0; return false; } double w = step((b-a)/theRapidityCutWidth); if ( w == 0.0 ) { weight = 0.0; return false; } weight *= w; return true; } bool JetRegion::matches(tcCutsPtr parent, int n, const LorentzMomentum& p, double yHat) { // one jet region can only contain one jet if ( didMatch() ) return false; if ( !accepts().empty() && find(accepts().begin(),accepts().end(),n) == accepts().end() ) return false; theCutWeight = 1.0; if ( !(lessThanEnergy(ptMin(),p.perp(),theCutWeight) && lessThanEnergy(p.perp(),ptMax(),theCutWeight)) ) { theCutWeight = 0.0; theDidMatch = false; return false; } double currentY = parent ? parent->currentYHat() : yHat; bool inRange = false || yRanges().empty(); for ( vector >::const_iterator r = yRanges().begin(); r != yRanges().end(); ++r ) { double rangeWeight = 1.0; if ( lessThanRapidity(r->first,p.rapidity() + currentY,rangeWeight) && lessThanRapidity(p.rapidity() + currentY,r->second,rangeWeight) ) { theCutWeight *= rangeWeight; inRange = true; break; } } if ( !inRange ) { theCutWeight = 0.0; theDidMatch = false; return false; } theDidMatch = true; theLastNumber = n; theLastMomentum = p; return true; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void JetRegion::persistentOutput(PersistentOStream & os) const { os << ounit(thePtMin,GeV) << ounit(thePtMax,GeV) << theYRanges << theAccepts << theFuzzy << theCutWeight << ounit(theEnergyCutWidth,GeV) << theRapidityCutWidth; } void JetRegion::persistentInput(PersistentIStream & is, int) { is >> iunit(thePtMin,GeV) >> iunit(thePtMax,GeV) >> theYRanges >> theAccepts >> theFuzzy >> theCutWeight >> iunit(theEnergyCutWidth,GeV) >> theRapidityCutWidth; } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass describeThePEGJetRegion("ThePEG::JetRegion", "JetCuts.so"); void JetRegion::Init() { static ClassDocumentation documentation ("JetRegion implements the requirement of finding a jet inside a " "given range of transverse momenta, and (pseudo-)rapidity."); static Parameter interfacePtMin ("PtMin", "The minimum pt required.", &JetRegion::thePtMin, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfacePtMax ("PtMax", "The maximum pt allowed.", &JetRegion::thePtMax, GeV, Constants::MaxEnergy, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Command interfaceYRange ("YRange", "Insert a rapidity range.", &JetRegion::doYRange, false); static ParVector interfaceAccepts ("Accepts", "The jet numbers accepted. If empty, any jets are accepted.", &JetRegion::theAccepts, -1, 1, 1, 10, false, false, Interface::upperlim); static Switch interfaceFuzzy ("Fuzzy", "Make this jet region a fuzzy cut", &JetRegion::theFuzzy, false, false, false); static SwitchOption interfaceFuzzyYes (interfaceFuzzy, "Yes", "", true); static SwitchOption interfaceFuzzyNo (interfaceFuzzy, "No", "", false); static Parameter interfaceEnergyCutWidth ("EnergyCutWidth", "The pt cut smearing.", &JetRegion::theEnergyCutWidth, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceRapidityCutWidth ("RapidityCutWidth", "The rapidity cut smearing.", &JetRegion::theRapidityCutWidth, 0.1, 0.0, 0, false, false, Interface::lowerlim); } diff --git a/Cuts/JetRegion.h b/Cuts/JetRegion.h --- a/Cuts/JetRegion.h +++ b/Cuts/JetRegion.h @@ -1,248 +1,240 @@ // -*- C++ -*- // // JetRegion.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_JetRegion_H #define ThePEG_JetRegion_H // // This is the declaration of the JetRegion class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Cuts/Cuts.h" namespace ThePEG { /** * JetRegion implements the requirement of finding a jet inside a * given range of transverse momenta, and (pseudo-)rapidity. * * @see JetPairRegion * @see JetCuts * * @see \ref JetRegionInterfaces "The interfaces" * defined for JetRegion. */ class JetRegion: public HandlerBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ JetRegion(); - /** - * The destructor. - */ - virtual ~JetRegion(); - //@} - public: /** * Return the minimum pt. */ Energy ptMin() const { return thePtMin; } /** * Return the maximum pt. */ Energy ptMax() const { return thePtMax; } /** * Return the rapidity ranges. */ const vector >& yRanges() const { return theYRanges; } /** * Return the jets accepted by this region (with respect to the * ordering imposed by the JetCuts object). If empty, any jet will * be accepted. */ const vector& accepts() const { return theAccepts; } /** * Return true, if this jet region is fuzzy */ bool fuzzy() const { return theFuzzy; } /** * Return the cut weight encountered from the last call to matches() */ double cutWeight() const { return theCutWeight; } /** * Perform a (potentially) fuzzy check on energy-type quantities */ bool lessThanEnergy(Energy a, Energy b, double& weight) const; /** * Perform a (potentially) fuzzy check on angular-type quantities */ bool lessThanRapidity(double a, double b, double& weight) const; public: /** * Describe the currently active cuts in the log file. */ virtual void describe() const; /** * Return true, if the given jet matches this region. */ virtual bool matches(tcCutsPtr parent, int n, const LorentzMomentum& p, double yHat = 0.0); /** * Return true, if this region matched a jet in the last call to matches(). */ bool didMatch() { return theDidMatch; } /** * Reset this region to act on a new event. */ virtual void reset() { theDidMatch = false; } /** * Return the number of the last jet matching this region. */ int lastNumber() const { return theLastNumber; } /** * Return the momentum of the last jet matching this region. */ const LorentzMomentum& lastMomentum() const { return theLastMomentum; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * Command to insert a rapidity range */ string doYRange(string); /** * The minimum pt. */ Energy thePtMin; /** * The maximum pt. */ Energy thePtMax; /** * The rapidity ranges. */ vector > theYRanges; /** * The jets accepted by this region (with respect to the ordering * imposed by the JetCuts object). If empty, any jet will be * accepted. */ vector theAccepts; /** * True, if this region matched a jet in the last call to matches(). */ bool theDidMatch; /** * The number of the last jet matching this region. */ int theLastNumber; /** * Return the momentum of the last jet matching this region. */ LorentzMomentum theLastMomentum; /** * True if this region is fuzzy */ bool theFuzzy; /** * The cut weight encountered from the last call to matches() */ double theCutWeight; /** * The smearing width for the pt or mass cuts, if fuzzy */ Energy theEnergyCutWidth; /** * The smearing width for the rapidity cut, if fuzzy */ double theRapidityCutWidth; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ JetRegion & operator=(const JetRegion &) = delete; }; } #endif /* ThePEG_JetRegion_H */ diff --git a/Cuts/KTRapidityCut.cc b/Cuts/KTRapidityCut.cc --- a/Cuts/KTRapidityCut.cc +++ b/Cuts/KTRapidityCut.cc @@ -1,168 +1,166 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the KTRapidityCut class. // #include "KTRapidityCut.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/PDT/MatcherBase.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Repository/CurrentGenerator.h" using namespace ThePEG; -KTRapidityCut::~KTRapidityCut() {} - void KTRapidityCut::describe() const { CurrentGenerator::log() << fullName() << ":\n" << "KT = " << theMinKT/GeV << " .. " << theMaxKT/GeV << " GeV\n" << "Rapidity = " << theMinRapidity << " .. " << theMaxRapidity << "\n\n"; } IBPtr KTRapidityCut::clone() const { return new_ptr(*this); } IBPtr KTRapidityCut::fullclone() const { return new_ptr(*this); } void KTRapidityCut::persistentOutput(PersistentOStream & os) const { os << ounit(theMinKT, GeV) << ounit(theMaxKT, GeV) << theMinRapidity << theMaxRapidity << theMatcher; } void KTRapidityCut::persistentInput(PersistentIStream & is, int) { is >> iunit(theMinKT, GeV) >> iunit(theMaxKT, GeV) >> theMinRapidity >> theMaxRapidity >> theMatcher; } ClassDescription KTRapidityCut::initKTRapidityCut; // Definition of the static class description member. void KTRapidityCut::Init() { static ClassDocumentation documentation ("This is a very simple concrete sub-class of OneCutbase simply " "requiring a minimum transverse momentum of any outgoing particle. " "It is also possible to require a minimum and maximum rapidity. " "Optionally the restrictions only apply to particles matching a " "specific matcher object."); typedef double (ThePEG::KTRapidityCut::*IGFN)() const; typedef void (ThePEG::KTRapidityCut::*ISFN)(double); typedef Energy (ThePEG::KTRapidityCut::*IGFNK)() const; typedef void (ThePEG::KTRapidityCut::*ISFNK)(Energy); static Parameter interfaceMinKT ("MinKT", "The minimum allowed value of the transverse momentum of an outgoing " "parton.", &KTRapidityCut::theMinKT, GeV, 10.0*GeV, ZERO, Constants::MaxEnergy, true, false, Interface::limited, (ISFNK)0, (IGFNK)0, (IGFNK)0, &KTRapidityCut::maxKTMin, (IGFNK)0); interfaceMinKT.setHasDefault(false); static Parameter interfaceMaxKT ("MaxKT", "The maximum allowed value of the transverse momentum of an outgoing " "parton. Note that this cut does not increase the efficiency of the phase " "space generation, but is only applied as a post-cut.", &KTRapidityCut::theMaxKT, GeV, Constants::MaxEnergy, ZERO, ZERO, true, false, Interface::lowerlim, (ISFNK)0, (IGFNK)0, &KTRapidityCut::minKTMax, (IGFNK)0, (IGFNK)0); interfaceMaxKT.setHasDefault(false); static Parameter interfaceMinRapidity ("MinRapidity", "The minimum allowed rapidity of an outgoing parton. " "The rapidity is measured in the lab system.", &KTRapidityCut::theMinRapidity, -Constants::MaxRapidity, 0, Constants::MaxRapidity, true, false, Interface::upperlim, (ISFN)0, (IGFN)0, (IGFN)0, &KTRapidityCut::maxRapidityMin, (IGFN)0); interfaceMinRapidity.setHasDefault(false); static Parameter interfaceMaxRapidity ("MaxRapidity", "The maximum allowed rapidity of an outgoing parton. " "The rapidity is measured in the lab system.", &KTRapidityCut::theMaxRapidity, Constants::MaxRapidity, -Constants::MaxRapidity, 0, true, false, Interface::lowerlim, (ISFN)0, (IGFN)0, &KTRapidityCut::minRapidityMax, (IGFN)0, (IGFN)0); interfaceMaxRapidity.setHasDefault(false); static Reference interfaceMatcher ("Matcher", "If non-null only particles matching this object will be affected " "by the cut.", &KTRapidityCut::theMatcher, true, false, true, true, false); interfaceMinKT.rank(10); interfaceMaxKT.rank(6); interfaceMinRapidity.rank(9); interfaceMaxRapidity.rank(8); interfaceMatcher.rank(7); } Energy KTRapidityCut::maxKTMin() const { return theMaxKT; } Energy KTRapidityCut::minKTMax() const { return theMinKT; } double KTRapidityCut::maxRapidityMin() const { return theMaxRapidity; } double KTRapidityCut::minRapidityMax() const { return theMinRapidity; } double KTRapidityCut::maxRapidityMin(tcPDPtr p) const { if ( theMatcher ) if ( !theMatcher->matches(*p) ) return Constants::MaxRapidity; return theMaxRapidity; } double KTRapidityCut::minRapidityMax(tcPDPtr p) const { if ( theMatcher ) if ( !theMatcher->matches(*p) ) return -Constants::MaxRapidity; return theMinRapidity; } Energy KTRapidityCut::minKT(tcPDPtr p) const { if ( theMatcher && !theMatcher->matches(*p) ) return ZERO; return theMinKT; } double KTRapidityCut::minEta(tcPDPtr) const { return -Constants::MaxRapidity; } double KTRapidityCut::maxEta(tcPDPtr) const { return Constants::MaxRapidity; } bool KTRapidityCut::passCuts(tcCutsPtr parent, tcPDPtr ptype, LorentzMomentum p) const { if ( theMatcher && !theMatcher->matches(*ptype) ) return true; if ( p.perp() < theMinKT ) return false; if ( p.perp() > theMaxKT ) return false; double y = p.rapidity() + parent->Y() + parent->currentYHat(); if ( y > theMaxRapidity ) return false; if ( y < theMinRapidity ) return false; return true; } diff --git a/Cuts/KTRapidityCut.h b/Cuts/KTRapidityCut.h --- a/Cuts/KTRapidityCut.h +++ b/Cuts/KTRapidityCut.h @@ -1,245 +1,237 @@ // -*- C++ -*- #ifndef THEPEG_KTRapidityCut_H #define THEPEG_KTRapidityCut_H // // This is the declaration of the KTRapidityCut class. // #include "ThePEG/Cuts/OneCutBase.h" namespace ThePEG { /** * The KTRapidityCut class is a simple concrete sub-class of OneCutbase simply * requiring a minimum transverse momentum of any outgoing * particle. It is also possible to require a minimum and maximum * rapidity. Optionally the restrictions only apply to particles * matching a specific matcher object. * * @see \ref KTRapidityCutInterfaces "The interfaces" * defined for KTRapidityCut. * @see SimpleKtCut */ class KTRapidityCut: public OneCutBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ KTRapidityCut(Energy minKT=10*GeV) : theMinKT(minKT), theMaxKT(Constants::MaxEnergy), theMinRapidity(-Constants::MaxRapidity), theMaxRapidity(Constants::MaxRapidity) {} - /** - * The destructor. - */ - virtual ~KTRapidityCut(); - //@} - public: /** @name Overwritten virtual functions defined in the base class. */ //@{ /** * Return the minimum allowed value of the transverse momentum of an * outgoing parton. */ virtual Energy minKT(tcPDPtr p) const; /** * Return the minimum allowed pseudo-rapidity of an outgoing parton * of the given type. The pseudo-rapidity is measured in the lab * system. */ virtual double minEta(tcPDPtr p) const; /** * Return the maximum allowed pseudo-rapidity of an outgoing parton * of the given type. The pseudo-rapidity is measured in the lab * system. */ virtual double maxEta(tcPDPtr p) const; /** * Return true if a particle with type \a ptype and momentum \a p * passes the cuts. The \a parent contains information about the * kinematics of the hard sub-process. */ virtual bool passCuts(tcCutsPtr parent, tcPDPtr ptype, LorentzMomentum p) const; //@} /** * Describe the currently active cuts in the log file. */ virtual void describe() const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * Helper function used by the interface. */ Energy maxKTMin() const; /** * Helper function used by the interface. */ Energy minKTMax() const; /** * Helper function used by the interface. */ double maxRapidityMin() const; /** * Helper function used by the interface. */ double minRapidityMax() const; /** * Return the minimum allowed rapidity of an outgoing parton * of the given type. The rapidity is measured in the lab * system. */ virtual double minRapidityMax(tcPDPtr p) const; /** * Return the maximum allowed rapidity of an outgoing parton * of the given type. The rapidity is measured in the lab * system. */ virtual double maxRapidityMin(tcPDPtr p) const; private: /** * The minimum allowed value of the transverse momentum of an * outgoing parton. */ Energy theMinKT; /** * The maximum allowed value of the transverse momentum of an * outgoing parton. */ Energy theMaxKT; /** * The minimum allowed rapidity of an outgoing parton. The * rapidity is measured in the lab system. */ double theMinRapidity; /** * The maximum allowed rapidity of an outgoing parton. The * rapidity is measured in the lab system. */ double theMaxRapidity; /** * If non-null only particles matching this object will be affected * by this cut. */ PMPtr theMatcher; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initKTRapidityCut; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ KTRapidityCut & operator=(const KTRapidityCut &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of KTRapidityCut. */ template <> struct BaseClassTrait { /** Typedef of the first base class of KTRapidityCut. */ typedef OneCutBase NthBase; }; /** This template specialization informs ThePEG about the name of * the KTRapidityCut class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::KTRapidityCut"; } /** * The name of a file containing the dynamic library where the class * KTRapidityCut is implemented. It may also include several, space-separated, * libraries if the class KTRapidityCut depends on other classes (base classes * excepted). In this case the listed libraries will be dynamically * linked in the order they are specified. */ static string library() { return "KTRapidityCut.so"; } }; /** @endcond */ } #endif /* THEPEG_KTRapidityCut_H */ diff --git a/Cuts/NJetsCut.cc b/Cuts/NJetsCut.cc --- a/Cuts/NJetsCut.cc +++ b/Cuts/NJetsCut.cc @@ -1,105 +1,103 @@ // -*- C++ -*- // // NJetsCut.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the NJetsCut class. // #include "NJetsCut.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Repository/CurrentGenerator.h" using namespace ThePEG; NJetsCut::NJetsCut() : nJetsMin(0), nJetsMax(-1) {} -NJetsCut::~NJetsCut() {} - void NJetsCut::describe() const { CurrentGenerator::log() << fullName() << ": requires "; if ( nJetsMin > 0 ) CurrentGenerator::log() << "at least " << nJetsMin; if ( nJetsMax > 0 ) CurrentGenerator::log() << " and at most " << nJetsMax; CurrentGenerator::log() << " jets.\n"; } IBPtr NJetsCut::clone() const { return new_ptr(*this); } IBPtr NJetsCut::fullclone() const { return new_ptr(*this); } void NJetsCut::persistentOutput(PersistentOStream & os) const { os << unresolvedMatcher << nJetsMin << nJetsMax; } void NJetsCut::persistentInput(PersistentIStream & is, int) { is >> unresolvedMatcher >> nJetsMin >> nJetsMax; } bool NJetsCut::passCuts(tcCutsPtr, const tcPDVector & ptype, const vector & p) const { tcPDVector::const_iterator ptit = ptype.begin(); vector::const_iterator pit = p.begin(); int njets = 0; for ( ; ptit != ptype.end(); ++ptit, ++pit ) if ( unresolvedMatcher->check(**ptit) ) { ++njets; } if ( nJetsMax > 0 ) return njets >= nJetsMin && njets <= nJetsMax; return njets >= nJetsMin; } ClassDescription NJetsCut::initNJetsCut; // Definition of the static class description member. void NJetsCut::Init() { static ClassDocumentation documentation ("NJetsCut is a simple cut on jet multiplicity."); static Reference interfaceUnresolvedMatcher ("UnresolvedMatcher", "A matcher identifying unresolved partons", &NJetsCut::unresolvedMatcher, false, false, true, false, false); static Parameter interfaceNJetsMin ("NJetsMin", "The minimum number of jets required.", &NJetsCut::nJetsMin, 0, 0, 0, false, false, Interface::lowerlim); static Parameter interfaceNJetsMax ("NJetsMax", "The maximum number of jets allowed. If -1 no limit is imposed.", &NJetsCut::nJetsMax, -1, -1, 0, false, false, Interface::lowerlim); } diff --git a/Cuts/NJetsCut.h b/Cuts/NJetsCut.h --- a/Cuts/NJetsCut.h +++ b/Cuts/NJetsCut.h @@ -1,170 +1,162 @@ // -*- C++ -*- // // NJetsCut.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_NJetsCut_H #define THEPEG_NJetsCut_H // // This is the declaration of the NJetsCut class. // #include "ThePEG/Cuts/MultiCutBase.h" #include "ThePEG/PDT/MatcherBase.h" namespace ThePEG { /** * NJetsCut is a simple cut on jet multiplicity. * * @see \ref NJetsCutInterfaces "The interfaces" * defined for NJetsCut. */ class NJetsCut: public MultiCutBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ NJetsCut(); - /** - * The destructor. - */ - virtual ~NJetsCut(); - //@} - public: /** @name Overridden virtual functions defined in the base class. */ //@{ /** * Return true if a set of outgoing particles with typea \a ptype * and corresponding momenta \a p passes the cuts. */ virtual bool passCuts(tcCutsPtr parent, const tcPDVector & ptype, const vector & p) const; //@} /** * Describe the currently active cuts in the log file. */ virtual void describe() const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * A matcher for unresolved partons. */ Ptr::ptr unresolvedMatcher; /** * The minimum number of jets. */ int nJetsMin; /** * The maximum number of jets. */ int nJetsMax; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initNJetsCut; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ NJetsCut & operator=(const NJetsCut &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of NJetsCut. */ template <> struct BaseClassTrait { /** Typedef of the first base class of NJetsCut. */ typedef MultiCutBase NthBase; }; /** This template specialization informs ThePEG about the name of * the NJetsCut class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::NJetsCut"; } /** Return the name of the shared library be loaded to get * access to the NJetsCut class and every other class it uses * (except the base class). */ static string library() { return "JetCuts.so"; } }; /** @endcond */ } #endif /* THEPEG_NJetsCut_H */ diff --git a/Cuts/OneJetCut.cc b/Cuts/OneJetCut.cc --- a/Cuts/OneJetCut.cc +++ b/Cuts/OneJetCut.cc @@ -1,108 +1,106 @@ // -*- C++ -*- // // OneJetCut.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the OneJetCut class. // #include "OneJetCut.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Repository/CurrentGenerator.h" using namespace ThePEG; OneJetCut::OneJetCut() : ptMin(20.*GeV), yMin(-5), yMax(5) {} -OneJetCut::~OneJetCut() {} - void OneJetCut::describe() const { CurrentGenerator::log() << fullName() << " requesting one jet with:\n" << "pt(jet)/GeV > " << ptMin/GeV << " y(jet) > " << yMin << " y(jet) < " << yMax << "\n"; } IBPtr OneJetCut::clone() const { return new_ptr(*this); } IBPtr OneJetCut::fullclone() const { return new_ptr(*this); } void OneJetCut::persistentOutput(PersistentOStream & os) const { os << unresolvedMatcher << ounit(ptMin,GeV) << yMin << yMax; } void OneJetCut::persistentInput(PersistentIStream & is, int) { is >> unresolvedMatcher >> iunit(ptMin,GeV) >> yMin >> yMax; } bool OneJetCut::passCuts(tcCutsPtr, const tcPDVector & ptype, const vector & p) const { tcPDVector::const_iterator ptit = ptype.begin(); vector::const_iterator pit = p.begin(); for ( ; ptit != ptype.end(); ++ptit, ++pit ) if ( unresolvedMatcher->check(**ptit) ) { double y = pit->rapidity(); if ( pit->perp() > ptMin && y > yMin && y < yMax ) { return true; } } return false; } ClassDescription OneJetCut::initOneJetCut; // Definition of the static class description member. void OneJetCut::Init() { static ClassDocumentation documentation ("OneJetsCut is a simple one-jet inclusive cut, requiring at least " "one jet above a certain pt in a given rapidity interval."); static Reference interfaceUnresolvedMatcher ("UnresolvedMatcher", "A matcher identifying unresolved partons", &OneJetCut::unresolvedMatcher, false, false, true, false, false); static Parameter interfacePTMin ("PTMin", "Set the minimum pt required for the jet.", &OneJetCut::ptMin, GeV, 20.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter interfaceYMin ("YMin", "Set the minimum rapidity required for the jet.", &OneJetCut::yMin, -5, 0, 0, false, false, Interface::nolimits); static Parameter interfaceYMax ("YMax", "Set the maximum rapidity required for the jet.", &OneJetCut::yMax, 5, 0, 0, false, false, Interface::nolimits); } diff --git a/Cuts/OneJetCut.h b/Cuts/OneJetCut.h --- a/Cuts/OneJetCut.h +++ b/Cuts/OneJetCut.h @@ -1,176 +1,168 @@ // -*- C++ -*- // // OneJetCut.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // Copyright (C) 2009-2019 Simon Platzer // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_OneJetCut_H #define THEPEG_OneJetCut_H // // This is the declaration of the OneJetCut class. // #include "ThePEG/Cuts/MultiCutBase.h" #include "ThePEG/PDT/MatcherBase.h" namespace ThePEG { /** * OneJetsCut is a simple one-jet inclusive cut, requiring at least * one jet above a certain pt in a given rapidity interval. * * @see \ref OneJetCutInterfaces "The interfaces" * defined for OneJetCut. */ class OneJetCut: public MultiCutBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ OneJetCut(); - /** - * The destructor. - */ - virtual ~OneJetCut(); - //@} - public: /** @name Overridden virtual functions defined in the base class. */ //@{ /** * Return true if a set of outgoing particles with typea \a ptype * and corresponding momenta \a p passes the cuts. */ virtual bool passCuts(tcCutsPtr parent, const tcPDVector & ptype, const vector & p) const; //@} /** * Describe the currently active cuts in the log file. */ virtual void describe() const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * A matcher for unresolved partons. */ Ptr::ptr unresolvedMatcher; /** * The minimum pt */ Energy ptMin; /** * The minimum rapidity */ double yMin; /** * The maximum rapidity */ double yMax; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initOneJetCut; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ OneJetCut & operator=(const OneJetCut &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of OneJetCut. */ template <> struct BaseClassTrait { /** Typedef of the first base class of OneJetCut. */ typedef MultiCutBase NthBase; }; /** This template specialization informs ThePEG about the name of * the OneJetCut class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::OneJetCut"; } /** Return the name of the shared library be loaded to get * access to the OneJetCut class and every other class it uses * (except the base class). */ static string library() { return "JetCuts.so"; } }; /** @endcond */ } #endif /* THEPEG_OneJetCut_H */ diff --git a/Cuts/SimpleKTCut.cc b/Cuts/SimpleKTCut.cc --- a/Cuts/SimpleKTCut.cc +++ b/Cuts/SimpleKTCut.cc @@ -1,170 +1,168 @@ // -*- C++ -*- // // SimpleKTCut.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the SimpleKTCut class. // #include "SimpleKTCut.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/PDT/MatcherBase.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Repository/CurrentGenerator.h" using namespace ThePEG; -SimpleKTCut::~SimpleKTCut() {} - void SimpleKTCut::describe() const { CurrentGenerator::log() << fullName() << ":\n" << "KT = " << theMinKT/GeV << " .. " << theMaxKT/GeV << " GeV\n" << "Eta = " << theMinEta << " .. " << theMaxEta << "\n\n"; } IBPtr SimpleKTCut::clone() const { return new_ptr(*this); } IBPtr SimpleKTCut::fullclone() const { return new_ptr(*this); } Energy SimpleKTCut::minKT(tcPDPtr p) const { if ( theMatcher && !theMatcher->matches(*p) ) return ZERO; return theMinKT; } double SimpleKTCut::minEta(tcPDPtr p) const { if ( theMatcher && !theMatcher->matches(*p) ) return -Constants::MaxRapidity; return theMinEta; } double SimpleKTCut::maxEta(tcPDPtr p) const { if ( theMatcher && !theMatcher->matches(*p) ) return Constants::MaxRapidity; return theMaxEta; } bool SimpleKTCut::passCuts(tcCutsPtr parent, tcPDPtr ptype, LorentzMomentum p) const { if ( theMatcher && !theMatcher->matches(*ptype) ) return true; if ( p.perp() < theMinKT ) return false; if ( p.perp() > theMaxKT ) return false; double y = abs(p.t()) <= abs(p.z()) ? (p .z() > ZERO ? 1e10 : -1e10) : p.rapidity(); y += parent->Y() + parent->currentYHat(); if ( p.mt()*sinh(y) <= p.perp()*sinh(theMinEta) ) return false; if ( p.mt()*sinh(y) >= p.perp()*sinh(theMaxEta) ) return false; return true; } void SimpleKTCut::persistentOutput(PersistentOStream & os) const { os << ounit(theMinKT, GeV) << ounit(theMaxKT, GeV) << theMinEta << theMaxEta << theMatcher; } void SimpleKTCut::persistentInput(PersistentIStream & is, int) { is >> iunit(theMinKT, GeV) >> iunit(theMaxKT, GeV) >> theMinEta >> theMaxEta >> theMatcher; } ClassDescription SimpleKTCut::initSimpleKTCut; // Definition of the static class description member. Energy SimpleKTCut::maxKTMin() const { return theMaxKT; } Energy SimpleKTCut::minKTMax() const { return theMinKT; } double SimpleKTCut::maxEtaMin() const { return theMaxEta; } double SimpleKTCut::minEtaMax() const { return theMinEta; } void SimpleKTCut::Init() { typedef double (ThePEG::SimpleKTCut::*IGFN)() const; typedef void (ThePEG::SimpleKTCut::*ISFN)(double); typedef Energy (ThePEG::SimpleKTCut::*IGFNK)() const; typedef void (ThePEG::SimpleKTCut::*ISFNK)(Energy); static ClassDocumentation documentation ("This is a very simple concrete sub-class of OneCutbase simply " "requiring a minimum transverse momentum of any outgoing particle. " "It is also possible to require a minimum and maximum pseudorapidity. " "Optionally the restrictions only apply to particles matching a " "specific matcher object."); static Parameter interfaceMinKT ("MinKT", "The minimum allowed value of the transverse momentum of an outgoing " "parton.", &SimpleKTCut::theMinKT, GeV, 10.0*GeV, ZERO, Constants::MaxEnergy, true, false, Interface::limited, (ISFNK)0, (IGFNK)0, (IGFNK)0, &SimpleKTCut::maxKTMin, (IGFNK)0); static Parameter interfaceMaxKT ("MaxKT", "The maximum allowed value of the transverse momentum of an outgoing " "parton. Note that this cut does not increase the efficiency of the phase " "space generation, but is only applied as a post-cut.", &SimpleKTCut::theMaxKT, GeV, Constants::MaxEnergy, ZERO, ZERO, true, false, Interface::lowerlim, (ISFNK)0, (IGFNK)0, &SimpleKTCut::minKTMax, (IGFNK)0, (IGFNK)0); static Parameter interfaceMinEta ("MinEta", "The minimum allowed pseudo-rapidity of an outgoing parton. " "The pseudo-rapidity is measured in the lab system.", &SimpleKTCut::theMinEta, -Constants::MaxRapidity, 0, Constants::MaxRapidity, true, false, Interface::upperlim, (ISFN)0, (IGFN)0, (IGFN)0, &SimpleKTCut::maxEtaMin, (IGFN)0); static Parameter interfaceMaxEta ("MaxEta", "The maximum allowed pseudo-rapidity of an outgoing parton. " "The pseudo-rapidity is measured in the lab system.", &SimpleKTCut::theMaxEta, Constants::MaxRapidity, -Constants::MaxRapidity, 0, true, false, Interface::lowerlim, (ISFN)0, (IGFN)0, &SimpleKTCut::minEtaMax, (IGFN)0, (IGFN)0); static Reference interfaceMatcher ("Matcher", "If non-null only particles matching this object will be affected " "by the cut.", &SimpleKTCut::theMatcher, true, false, true, true, false); interfaceMinKT.rank(10); interfaceMaxKT.rank(6); interfaceMinEta.rank(9); interfaceMaxEta.rank(8); interfaceMatcher.rank(7); interfaceMinKT.setHasDefault(false); interfaceMaxKT.setHasDefault(false); interfaceMinEta.setHasDefault(false); interfaceMaxEta.setHasDefault(false); } diff --git a/Cuts/SimpleKTCut.h b/Cuts/SimpleKTCut.h --- a/Cuts/SimpleKTCut.h +++ b/Cuts/SimpleKTCut.h @@ -1,233 +1,225 @@ // -*- C++ -*- // // SimpleKTCut.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_SimpleKTCut_H #define THEPEG_SimpleKTCut_H // // This is the declaration of the SimpleKTCut class. // #include "ThePEG/Cuts/OneCutBase.h" namespace ThePEG { /** * This is a very simple concrete sub-class of OneCutbase simply * requiring a minimum transverse momentum of any outgoing * particle. It is also possible to require a minimum and maximum * pseudorapidity. Optionally the restrictions only apply to particles * matching a specific matcher object. * * @see \ref SimpleKTCutInterfaces "The interfaces" * defined for SimpleKTCut. */ class SimpleKTCut: public OneCutBase { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ SimpleKTCut(Energy minKT=10*GeV) : theMinKT(minKT), theMaxKT(Constants::MaxEnergy), theMinEta(-Constants::MaxRapidity), theMaxEta(Constants::MaxRapidity) {} - - /** - * The destructor. - */ - virtual ~SimpleKTCut(); - //@} public: /** @name Overwritten virtual functions defined in the base class. */ //@{ /** * Return the minimum allowed value of the transverse momentum of an * outgoing parton. */ virtual Energy minKT(tcPDPtr p) const; /** * Return the minimum allowed pseudo-rapidity of an outgoing parton * of the given type. The pseudo-rapidity is measured in the lab * system. */ virtual double minEta(tcPDPtr p) const; /** * Return the maximum allowed pseudo-rapidity of an outgoing parton * of the given type. The pseudo-rapidity is measured in the lab * system. */ virtual double maxEta(tcPDPtr p) const; /** * Return true if a particle with type \a ptype and momentum \a p * passes the cuts. The \a parent contains information about the * kinematics of the hard sub-process. */ virtual bool passCuts(tcCutsPtr parent, tcPDPtr ptype, LorentzMomentum p) const; //@} /** * Describe the currently active cuts in the log file. */ virtual void describe() const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * Helper function used by the interface. */ Energy maxKTMin() const; /** * Helper function used by the interface. */ Energy minKTMax() const; /** * Helper function used by the interface. */ double maxEtaMin() const; /** * Helper function used by the interface. */ double minEtaMax() const; private: /** * The minimum allowed value of the transverse momentum of an * outgoing parton. */ Energy theMinKT; /** * The maximum allowed value of the transverse momentum of an * outgoing parton. */ Energy theMaxKT; /** * The minimum allowed pseudo-rapidity of an outgoing parton. The * pseudo-rapidity is measured in the lab system. */ double theMinEta; /** * The maximum allowed pseudo-rapidity of an outgoing parton. The * pseudo-rapidity is measured in the lab system. */ double theMaxEta; /** * If non-null only particles matching this object will be affected * by this cut. */ PMPtr theMatcher; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initSimpleKTCut; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ SimpleKTCut & operator=(const SimpleKTCut &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of SimpleKTCut. */ template <> struct BaseClassTrait { /** Typedef of the first base class of SimpleKTCut. */ typedef OneCutBase NthBase; }; /** This template specialization informs ThePEG about the name of * the SimpleKTCut class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::SimpleKTCut"; } /** Return the name of the shared library be loaded to get * access to the SimpleKTCut class and every other class it uses * (except the base class). */ static string library() { return "SimpleKTCut.so"; } }; /** @endcond */ } #endif /* THEPEG_SimpleKTCut_H */ diff --git a/Cuts/TwoCutBase.cc b/Cuts/TwoCutBase.cc --- a/Cuts/TwoCutBase.cc +++ b/Cuts/TwoCutBase.cc @@ -1,71 +1,69 @@ // -*- C++ -*- // // TwoCutBase.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the TwoCutBase class. // #include "TwoCutBase.h" #include "Cuts.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/CurrentGenerator.h" using namespace ThePEG; -TwoCutBase::~TwoCutBase() {} - void TwoCutBase::describe() const { CurrentGenerator::log() << fullName() << " has no description.\n\n"; } bool TwoCutBase::passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype, LorentzMomentum pi, LorentzMomentum pj, bool inci, bool incj) const { if ( inci && incj ) return true; else if ( inci ) { if ( -(pj - pi).m2() <= minTij(pitype, pjtype) ) return false; if ( pj.perp() <= minKTClus(tcPDPtr(), pjtype) ) return false; } else if ( incj ) { if ( -(pi - pj).m2() <= minTij(pjtype, pitype) ) return false; if ( pi.perp() <= minKTClus(tcPDPtr(), pitype) ) return false; } else { if ( (pi + pj).m2() <= minSij(pitype, pjtype) ) return false; double deta2 = sqr(pi.eta() - pj.eta()); double dphi = abs(pi.phi() - pj.phi()); if ( dphi > Constants::pi ) dphi = 2.0*Constants::pi - dphi; double dr = sqrt(deta2 + sqr(dphi)); if ( dr < minDeltaR(pitype, pjtype) ) return false; if ( min(pi.perp(), pj.perp())*dr <= minKTClus(pitype, pjtype) ) return false; if ( 2.0*sqr(min(pi.e(), pj.e()))*(1.0 - cos(pi.angle(pj))) < parent->currentSHat()*minDurham(pitype, pjtype) ) return false; } return true; } bool TwoCutBase::passCuts(tcCutsPtr parent, tcPPtr pi, tcPPtr pj, bool inci, bool incj) const { return passCuts(parent, pi->dataPtr(), pj->dataPtr(), pi->momentum(), pj->momentum(), inci, incj); } AbstractNoPIOClassDescription TwoCutBase::initTwoCutBase; // Definition of the static class description member. void TwoCutBase::Init() { static ClassDocumentation documentation ("This class corresponds to a kinematical cut to be made on a pair of " "particles in a hard sub-process."); } diff --git a/Cuts/TwoCutBase.h b/Cuts/TwoCutBase.h --- a/Cuts/TwoCutBase.h +++ b/Cuts/TwoCutBase.h @@ -1,175 +1,167 @@ // -*- C++ -*- // // TwoCutBase.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_TwoCutBase_H #define THEPEG_TwoCutBase_H // // This is the declaration of the TwoCutBase class. // #include "ThePEG/Interface/Interfaced.h" #include "TwoCutBase.fh" #include "Cuts.fh" namespace ThePEG { /** * This class corresponds to a kinematical cut to be made on a pair of * particles in a hard sub-process. * * There are six main virtual functions to be overridden by concrete * sub-classes. minsSij(), minTij(), minDeltaR(), minKTClus() and * minDurham() returns the minimum allowed values of pre defined * kinematical variable. In addition the passCut() function should * return true if a pair of particle with a given types and given * momenta will pass the cuts. * * @see \ref TwoCutBaseInterfaces "The interfaces" defined for * TwoCutBase. */ class TwoCutBase: public Interfaced { public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ TwoCutBase() {} - /** - * The destructor. - */ - virtual ~TwoCutBase(); - //@} - public: /** @name Virtual functions to be overridden by sub-classes. */ //@{ /** * Return the minimum allowed squared invariant mass of two outgoing * partons of type \a pi and \a pj. */ virtual Energy2 minSij(tcPDPtr pi, tcPDPtr pj) const = 0; /** * Return the minimum allowed value of the negative of the squared * invariant mass of an incoming parton of type \a pi and an * outgoing parton of type \a po. */ virtual Energy2 minTij(tcPDPtr pi, tcPDPtr po) const = 0; /** * Return the minimum allowed value of \f$\Delta * R_{ij}=\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ of two * outgoing partons of type \a pi and \a pj. */ virtual double minDeltaR(tcPDPtr pi, tcPDPtr pj) const = 0; /** * Return the minimum allowed value of the longitudinally invariant * \f$k_\perp\f$-algorithms distance measure. This is defined as * \f$\min(p_{\perp i}, p_{\perp * j})\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ for two outgoing * partons, or simply \f$p_{\perp i}\f$ or \f$p_{\perp j}\f$ for a * single outgoing parton. Returns 0 if both partons are incoming. A * null pointer indicates an incoming parton, hence the type of the * incoming parton is irrelevant. */ virtual Energy minKTClus(tcPDPtr pi, tcPDPtr pj) const = 0; /** * Return the minimum allowed value of the Durham * \f$k_\perp\f$-algorithms distance measure. This is defined as * \f$2\min(E_j^2, E_j^2)(1-\cos\theta_{ij})/\hat{s}\f$ for two * outgoing partons. */ virtual double minDurham(tcPDPtr pi, tcPDPtr pj) const = 0; /** * Return true if a pair of particles with type \a pitype and \a * pjtype and momenta \a pi and \a pj respectively passes the * cuts. \a inci and \a inj indicates if the corresponding particles * are incoming. */ virtual bool passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype, LorentzMomentum pi, LorentzMomentum pj, bool inci = false, bool incj = false) const; /** * Return true if the given pair of particles passes the cuts. \a * inci and \a inj indicates if the corresponding particles are * incoming. */ bool passCuts(tcCutsPtr parent, tcPPtr pi, tcPPtr pj, bool inci = false, bool incj = false) const; //@} /** * Describe the currently active cuts in the log file. */ virtual void describe() const; public: /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); private: /** * The static object used to initialize the description of this class. * Indicates that this is an abstract class with persistent data. */ static AbstractNoPIOClassDescription initTwoCutBase; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ TwoCutBase & operator=(const TwoCutBase &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of TwoCutBase. */ template <> struct BaseClassTrait { /** Typedef of the first base class of TwoCutBase. */ typedef Interfaced NthBase; }; /** This template specialization informs ThePEG about the name of * the TwoCutBase class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::TwoCutBase"; } }; /** @endcond */ } #endif /* THEPEG_TwoCutBase_H */ diff --git a/Cuts/V2LeptonsCut.cc b/Cuts/V2LeptonsCut.cc --- a/Cuts/V2LeptonsCut.cc +++ b/Cuts/V2LeptonsCut.cc @@ -1,227 +1,225 @@ // -*- C++ -*- // // V2LeptonsCut.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the V2LeptonsCut class. // #include "V2LeptonsCut.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/PDT/ParticleData.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Repository/CurrentGenerator.h" using namespace ThePEG; -V2LeptonsCut::~V2LeptonsCut() {} - void V2LeptonsCut::describe() const { CurrentGenerator::log() << fullName() << ":\n" << "M = " << theMinM/GeV << " .. " << theMaxM/GeV << " GeV\n\n"; } IBPtr V2LeptonsCut::clone() const { return new_ptr(*this); } IBPtr V2LeptonsCut::fullclone() const { return new_ptr(*this); } Energy2 V2LeptonsCut::minS(const tcPDVector & pv) const { if ( pv.size() != 2 ) return ZERO; if ( !checkTypes(pv[0]->id(), pv[1]->id()) ) return ZERO; return sqr(theMinM); } Energy2 V2LeptonsCut::maxS(const tcPDVector & pv) const { if ( pv.size() != 2 ) return Constants::MaxEnergy2; if ( !checkTypes(pv[0]->id(), pv[1]->id()) ) return Constants::MaxEnergy2; return sqr(theMaxM); } bool V2LeptonsCut::passCuts(tcCutsPtr, const tcPDVector & ptype, const vector & p) const { for ( int i = 0, N = ptype.size() - 1; i < N; ++i ) for ( int j = i + 1, M = ptype.size(); j < M; ++j ) { if ( !checkTypes(ptype[i]->id(), ptype[j]->id()) ) continue; Energy2 s = (p[i] + p[j]).m2(); if ( s <= sqr(theMinM) || s >= sqr(theMaxM) ) return false; } return true; } int V2LeptonsCut::family(long id) const { switch ( abs(id) ) { case ParticleID::eminus: case ParticleID::nu_e: return electron; case ParticleID::muminus: case ParticleID::nu_mu: return muon; case ParticleID::tauminus: case ParticleID::nu_tau: return tau; } return 0; } bool V2LeptonsCut::checkTypes(long id1, long id2) const { // Must be particle anti-particle pair; if ( id1*id2 >= 0 ) return false; // Check that we have leptons, the families are the same and matches // the chosen ones. int fam1 = family(id1); if ( !fam1 ) return false; int fam2 = family(id2); if ( fam2 != fam1 || !(theFamilies&fam1) ) return false; // Check charge combination. int ccomb; if ( (id1%2) && (id2%2) ) ccomb = posneg; else if ( id1%2 ) { if ( id1 > 0 ) ccomb = negneu; else ccomb = posneu; } else if ( id2%2 ) { if ( id2 > 0 ) ccomb = negneu; else ccomb = posneu; } else ccomb = neuneu; return (theCComb&ccomb); } void V2LeptonsCut::persistentOutput(PersistentOStream & os) const { os << ounit(theMinM, GeV) << ounit(theMaxM, GeV) << theFamilies << theCComb; } void V2LeptonsCut::persistentInput(PersistentIStream & is, int) { is >> iunit(theMinM, GeV) >> iunit(theMaxM, GeV) >> theFamilies >> theCComb; } Energy V2LeptonsCut::maxMinM() const { return theMaxM; } Energy V2LeptonsCut::minMaxM() const { return theMinM; } ClassDescription V2LeptonsCut::initV2LeptonsCut; // Definition of the static class description member. void V2LeptonsCut::Init() { static ClassDocumentation documentation ("This class inherits from MultiCutBase and describes cuts on the " "invariant mass of two final state leptons corresponding to the decay " "of a vector boson. It can be used when generating matrix elements to " "avoid the long tails of the resonance."); static Parameter interfaceMinM ("MinM", "The minimum allowed invariant mass of the matched lepton pair.", &V2LeptonsCut::theMinM, GeV, 70.0*GeV, ZERO, Constants::MaxEnergy, true, false, Interface::limited, 0, 0, 0, &V2LeptonsCut::maxMinM, 0); static Parameter interfaceMaxM ("MaxM", "The maximum allowed invariant mass of the matched lepton pair.", &V2LeptonsCut::theMaxM, GeV, 90.0*GeV, ZERO, ZERO, true, false, Interface::lowerlim, 0, 0, &V2LeptonsCut::minMaxM, 0, 0); static Switch interfaceFamilies ("Families", "The different lepton families for which this cut should apply.", &V2LeptonsCut::theFamilies, electron|muon, true, false); static SwitchOption interfaceFamiliesElectron (interfaceFamilies, "Electron", "Only apply cut to electrons and electron neutrinos.", electron); static SwitchOption interfaceFamiliesMuon (interfaceFamilies, "Muon", "Only apply cut to muons and muon neutrinos.", muon); static SwitchOption interfaceFamiliesTau (interfaceFamilies, "Tau", "Only apply cut to taus and tau neutrinos.", tau); static SwitchOption interfaceFamiliesElectronMuon (interfaceFamilies, "ElectronMuon", "Only apply cut to electron and muon leptons.", electron|muon); static SwitchOption interfaceFamiliesAll (interfaceFamilies, "All", "Apply cut to all lepton families.", electron|muon|tau); static Switch interfaceCComb ("CComb", "The charge combination of the lepton pair on which to cut.", &V2LeptonsCut::theCComb, posneu|negneu, true, false); static SwitchOption interfaceCCombAll (interfaceCComb, "All", "Cut on all relevant charge combinations.", posneg|negneu|posneu|neuneu); static SwitchOption interfaceCCombWplus (interfaceCComb, "Wplus", "Cut on positive lepton neutrin pairs.", posneu); static SwitchOption interfaceCCombWminus (interfaceCComb, "Wminus", "Cut on negative lepton anti-neutrin pairs.", negneu); static SwitchOption interfaceCCombW (interfaceCComb, "W", "Cut on charged lepton neutrino pairs.", posneu|negneu); static SwitchOption interfaceCCombGamma (interfaceCComb, "Gamma", "Cut on charged lepton anti-lepton pairs.", posneg); static SwitchOption interfaceCCombZ (interfaceCComb, "Z", "Cut on lepton anti-lepton pairs.", neuneu|posneg); static SwitchOption interfaceCCombZneutrinos (interfaceCComb, "Zneutrinos", "Cut on neutrino anti-neutrino pairs.", neuneu); interfaceMinM.rank(10); interfaceMaxM.rank(9); interfaceMinM.setHasDefault(false); interfaceMaxM.setHasDefault(false); interfaceCComb.setHasDefault(false); interfaceFamilies.setHasDefault(false); } diff --git a/Cuts/V2LeptonsCut.h b/Cuts/V2LeptonsCut.h --- a/Cuts/V2LeptonsCut.h +++ b/Cuts/V2LeptonsCut.h @@ -1,234 +1,226 @@ // -*- C++ -*- // // V2LeptonsCut.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_V2LeptonsCut_H #define THEPEG_V2LeptonsCut_H // // This is the declaration of the V2LeptonsCut class. // #include "ThePEG/Cuts/MultiCutBase.h" namespace ThePEG { /** * This class inherits from MultiCutBase and describes cuts on the * invariant mass of two final state leptons corresponding to the * decay of a vector boson. It can be used when generating matrix * elements to avoid the long tails of the resonance. * * @see \ref V2LeptonsCutInterfaces "The interfaces" * defined for V2LeptonsCut. */ class V2LeptonsCut: public MultiCutBase { /** * Enumeration of the different families. */ enum Family { electron = 1, /**< Lepton Family. */ muon = 2, /**< Muon Family. */ tau = 4 /**< Tau Family. */ }; /** * Enumeration of charge combinations. */ enum CComb { posneg = 1, /**< charged lepton anti-lepton pair. */ negneu = 2, /**< negative lepton anti-neutrino pair. */ posneu = 4, /**< positive lepton anti-neutrino pair. */ neuneu = 8 /**< neutrino anti-neutrino pair. */ }; public: - /** @name Standard constructors and destructors. */ - //@{ /** * The default constructor. */ V2LeptonsCut() : theMinM(70.0*GeV), theMaxM(90.0*GeV), theFamilies(electron|muon), theCComb(negneu|posneu) {} - /** - * The destructor. - */ - virtual ~V2LeptonsCut(); - //@} - public: /** @name Overridden virtual functions defined in the base class. */ //@{ /** * Return the minimum allowed value of the squared invariant mass of * a set of outgoing partons of the given types. Typically used to * cut off the tails of the mass of a resonance for efficiency. */ virtual Energy2 minS(const tcPDVector & pv) const; /** * Return the maximum allowed value of the squared invariant mass of * a set of outgoing partons of the given types. Typically used to * cut off the tails of the mass of a resonance for efficiency. */ virtual Energy2 maxS(const tcPDVector & pv) const; /** * Return true if a set of outgoing particles with typea \a ptype * and corresponding momenta \a p passes the cuts. */ virtual bool passCuts(tcCutsPtr parent, const tcPDVector & ptype, const vector & p) const; //@} /** * Describe the currently active cuts in the log file. */ virtual void describe() const; protected: /** * Check if the PDG id numbers matches this cut. */ bool checkTypes(long id1, long id2) const; /** * Check the family of the given PDG id number. */ int family(long id) const; public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * Helper function used by the interface. */ Energy maxMinM() const; /** * Helper function used by the interface. */ Energy minMaxM() const; private: /** * The minimum invariant mass. */ Energy theMinM; /** * The maximum invariant mass. */ Energy theMaxM; /** * Integer corresponding to the lepton families to match. */ int theFamilies; /** * Integer corresponding to the charge combination to match. */ int theCComb; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initV2LeptonsCut; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ V2LeptonsCut & operator=(const V2LeptonsCut &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of V2LeptonsCut. */ template <> struct BaseClassTrait { /** Typedef of the first base class of V2LeptonsCut. */ typedef MultiCutBase NthBase; }; /** This template specialization informs ThePEG about the name of * the V2LeptonsCut class and the shared object where it is defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::V2LeptonsCut"; } /** Return the name of the shared library be loaded to get * access to the V2LeptonsCut class and every other class it uses * (except the base class). */ static string library() { return "V2LeptonsCut.so"; } }; /** @endcond */ } #endif /* THEPEG_V2LeptonsCut_H */ diff --git a/MatrixElement/MENCDIS.cc b/MatrixElement/MENCDIS.cc --- a/MatrixElement/MENCDIS.cc +++ b/MatrixElement/MENCDIS.cc @@ -1,163 +1,161 @@ // -*- C++ -*- // // MENCDIS.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the MENCDIS class. // #include "MENCDIS.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; MENCDIS::MENCDIS() : mZ2(ZERO) {} MENCDIS::MENCDIS(const MENCDIS & x) : ME2to2QCD(x), mZ2(x.mZ2) {} -MENCDIS::~MENCDIS() {} - unsigned int MENCDIS::orderInAlphaS() const { return 0; } unsigned int MENCDIS::orderInAlphaEW() const { return 2; } void MENCDIS::getDiagrams() const { tcPDPtr gamma = getParticleData(ParticleID::gamma); tcPDPtr Z0 = getParticleData(ParticleID::Z0); tcPDPtr ep = getParticleData(ParticleID::eplus); tcPDPtr em = getParticleData(ParticleID::eminus); for ( int i = -maxFlavour(); i <= maxFlavour(); ++i ) { if ( !i ) continue; tcPDPtr q = getParticleData(i); add(new_ptr((Tree2toNDiagram(3), q, gamma, em, 1, q, 2, em, -1))); add(new_ptr((Tree2toNDiagram(3), q, Z0, em, 1, q, 2, em, -2))); add(new_ptr((Tree2toNDiagram(3), q, gamma, ep, 1, q, 2, ep, -1))); add(new_ptr((Tree2toNDiagram(3), q, Z0, ep, 1, q, 2, ep, -2))); } } Energy2 MENCDIS::scale() const { return -tHat(); } double MENCDIS::me2() const { double lastG = 0.0; double lastIntr = 0.0; double lastZ = 0.0; //pq is a vector in the same direction as the quark with zero mass. Lorentz5Momentum pq = meMomenta()[0]; pq.setMass(ZERO); pq.rescaleEnergy(); double y = 1.0 - pq.dot(meMomenta()[3]) / pq.dot(meMomenta()[1]); Energy4 F2Coeff = sqr(sHat()) * (1 + sqr(1-y)); Energy4 F3Coeff = sqr(sHat()) * (1 - sqr(1-y)); double C = 16 * SM().sin2ThetaW() * ( 1.0 - SM().sin2ThetaW() ); if(mePartonData()[0]->id() < 0){ F3Coeff = -F3Coeff; } if(mePartonData()[1]->id() < 0){ F3Coeff = -F3Coeff; } if( abs(mePartonData()[0]->id())%2 == 0 ){ lastG = F2Coeff * sqr(SM().eu()) / sqr(tHat()); lastIntr = -2*SM().eu()*(F2Coeff*SM().ve()*SM().vu() + 2*F3Coeff*SM().ae()*SM().au()) / (-tHat() * (-tHat() + mZ2) * C); lastZ = ( F2Coeff * (sqr(SM().ae())+sqr(SM().ve())) * (sqr(SM().au())+sqr(SM().vu())) + 4.0 * F3Coeff*SM().ve()* SM().ae()*SM().au()*SM().vu() ) / sqr((-tHat() + mZ2) * C); } else{ lastG = F2Coeff * sqr(SM().ed()) / sqr(tHat()); lastIntr = -2*SM().ed()*(F2Coeff*SM().ve()*SM().vd() + 2*F3Coeff*SM().ae()*SM().ad()) / (-tHat() * (-tHat() + mZ2) * C); lastZ = ( F2Coeff * (sqr(SM().ae())+sqr(SM().ve())) * (sqr(SM().ad())+sqr(SM().vd())) + 4.0 * F3Coeff*SM().ve()* SM().ae()*SM().ad()*SM().vd() ) / sqr((-tHat() + mZ2) * C); } DVector save; meInfo(save << lastG << lastZ); return (lastG + lastIntr + lastZ) * sqr(SM().alphaEM(scale())) * 32.0 * sqr(Constants::pi); } Selector MENCDIS::diagrams(const DiagramVector & diags) const { if ( lastXCombPtr() ) { lastG = meInfo()[0]; lastZ = meInfo()[1]; } Selector sel; for ( DiagramIndex i = 0; i < diags.size(); ++i ) { if ( diags[i]->id() == -1 ) sel.insert(lastG, i); else if ( diags[i]->id() == -2 ) sel.insert(lastZ, i); } return sel; } Selector MENCDIS::colourGeometries(tcDiagPtr diag) const { static ColourLines c("1 4"); static ColourLines cb("-1 -4"); Selector sel; if ( diag->partons()[0]->id() > 0 ) sel.insert(1.0, &c); else sel.insert(1.0, &cb); return sel; } IBPtr MENCDIS::clone() const { return new_ptr(*this); } IBPtr MENCDIS::fullclone() const { return new_ptr(*this); } void MENCDIS::doinit() { ME2to2QCD::doinit(); tcPDPtr Z0 = getParticleData(ParticleID::Z0); mZ2 = sqr(Z0->mass()); } void MENCDIS::persistentOutput(PersistentOStream & os) const { os << ounit(mZ2, GeV2) << lastG << lastZ; } void MENCDIS::persistentInput(PersistentIStream & is, int) { is >> iunit(mZ2, GeV2) >> lastG >> lastZ; } ClassDescription MENCDIS::initMENCDIS; void MENCDIS::Init() { static ClassDocumentation documentation ("The ThePEG::MENCDIS class implements the full" "\\f$e^\\pm q \\rightarrow e^\\pm q\\f$ " "matrix element including the interference terms."); } diff --git a/MatrixElement/MENCDIS.h b/MatrixElement/MENCDIS.h --- a/MatrixElement/MENCDIS.h +++ b/MatrixElement/MENCDIS.h @@ -1,215 +1,210 @@ // -*- C++ -*- // // MENCDIS.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_MENCDIS_H #define ThePEG_MENCDIS_H // This is the declaration of the MENCDIS class. #include "ThePEG/MatrixElement/ME2to2QCD.h" // #include "MENCDIS.fh" // #include "MENCDIS.xh" namespace ThePEG { /** * The MENCDIS class implements the \f$e^\pm q\rightarrow e^\pm q\f$ * matrix element. Both the gamma and \f$Z^0\f$ terms as well * as the interference term is included. Although not a strict QCD * matrix element the class inherits from ME2to2QCD, mainly to inherit * the parameter for the number of active quark flavours. * * @see \ref MENCDISInterfaces "The interfaces" * defined for MENCDIS. * @see ME2to2QCD */ class MENCDIS: public ME2to2QCD { public: /** @name Standard constructors and destructors. */ //@{ /** * Default constructor. */ MENCDIS(); /** * Copy-constructor. */ MENCDIS(const MENCDIS &); - - /** - * Destructor. - */ - virtual ~MENCDIS(); //@} public: /** @name Virtual functions required by the MEBase class. */ //@{ /** * Return the order in \f$\alpha_S\f$ in which this matrix element * is given. Returns . */ virtual unsigned int orderInAlphaS() const; /** * Return the order in \f$\alpha_{EM}\f$ in which this matrix * element is given. Returns 2. */ virtual unsigned int orderInAlphaEW() const; /** * The matrix element for the kinematical configuration * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. * @return the matrix element scaled with sHat() to give a * dimensionless number. */ virtual double me2() const; /** * Add all possible diagrams with the add() function. */ virtual void getDiagrams() const; /** * Return a Selector with possible colour geometries for the selected * diagram weighted by their relative probabilities. * @param diag the diagram chosen. * @return the possible colour geometries weighted by their * relative probabilities. */ virtual Selector colourGeometries(tcDiagPtr diag) const; /** * Get diagram selector. With the information previously supplied with the * setKinematics method, a derived class may optionally * override this method to weight the given diagrams with their * (although certainly not physical) relative probabilities. * @param dv the diagrams to be weighted. * @return a Selector relating the given diagrams to their weights. */ virtual Selector diagrams(const DiagramVector & dv) const; /** * Return the scale associated with the last set phase space point. */ virtual Energy2 scale() const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interface. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); //@} protected: /** * The squared mass of the Z0. */ Energy2 mZ2; /** * The last gamma term to be used to select primary diagram. */ mutable double lastG; /** * The last Z0 term to be used to select primary diagram. */ mutable double lastZ; private: /** * Describe a concrete class with persistent data. */ static ClassDescription initMENCDIS; /** * Private and non-existent assignment operator. */ MENCDIS & operator=(const MENCDIS &) = delete; }; /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of MENCDIS. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of MENCDIS. */ typedef ME2to2QCD NthBase; }; /** This template specialization informs ThePEG about the name of the * MENCDIS class and the shared object where it is defined. */ template <> struct ClassTraits: public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::MENCDIS"; } /** Return the name of the shared library be loaded to get * access to the MENCDIS class and every other class it uses * (except the base class). */ static string library() { return "MENCDIS.so"; } }; /** @endcond */ } #endif /* ThePEG_MENCDIS_H */ diff --git a/PDT/DalitzDecayer.cc b/PDT/DalitzDecayer.cc --- a/PDT/DalitzDecayer.cc +++ b/PDT/DalitzDecayer.cc @@ -1,133 +1,131 @@ // -*- C++ -*- // // DalitzDecayer.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the DalitzDecayer class. // #include "DalitzDecayer.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/Rebinder.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; -DalitzDecayer::~DalitzDecayer() {} - IBPtr DalitzDecayer::clone() const { return new_ptr(*this); } IBPtr DalitzDecayer::fullclone() const { return new_ptr(*this); } void DalitzDecayer::doinit() { Decayer::doinit(); rho = getParticleData(ParticleID::rho0); } bool DalitzDecayer::accept(const DecayMode & dm) const { if ( dm.products().size() != 3 || !dm.cascadeProducts().empty() || !dm.productMatchers().empty() || dm.wildProductMatcher() ) return false; bool ep = false, em = false, gam = false; for ( ParticleMSet::const_iterator pit = dm.products().begin(); pit != dm.products().end(); ++pit ) { if ( (**pit).id() == ParticleID::eplus ) ep = true; else if ( (**pit).id() == ParticleID::eminus ) em = true; else if ( (**pit).id() == ParticleID::gamma ) gam = true; } return ep && em && gam; } ParticleVector DalitzDecayer::decay(const DecayMode & dm, const Particle & parent) const { ParticleVector children = getChildren(dm, parent); tPPtr ep; tPPtr em; tPPtr gam; for ( int i = 0, N = children.size(); i < N; ++i ) { if ( children[i]->id() == ParticleID::eplus ) ep = children[i]; else if ( children[i]->id() == ParticleID::eminus ) em = children[i]; else if ( children[i]->id() == ParticleID::gamma ) gam = children[i]; } Energy2 mee2 = ZERO; Energy2 me2 = ep->mass()*em->mass(); Energy2 mm2 = sqr(parent.mass()); Energy2 mr2 = sqr(rho->mass()); Energy2 gr2 = sqr(rho->width()); Energy2 mee2min = 4.0*me2; do { mee2 = mee2min*pow(mm2/mee2min, rnd()); } while ( rnd() > (1.0 - 2.0*me2/mee2)*sqrt(max(0.0, 1.0 - mee2min/mee2))* pow(1.0 - mee2/mm2, 3.0)* (1.0 + gr2/mr2)/(sqr(1.0 - mee2/mr2) + gr2/mr2) ); LorentzMomentum pee, p0, pp, pm; do { SimplePhaseSpace::CMS(mee2, ep, em); pee = ep->momentum() + em->momentum(); p0 = gam->momentum(); SimplePhaseSpace::CMS(mm2, p0, pee); LorentzRotation r (0.0, 0.0, pee.rho()/pee.e()); r.rotateY(pee.theta()); r.rotateZ(pee.phi()); ep->transform(r); em->transform(r); gam->setMomentum(p0); pp = ep->momentum(); pm = em->momentum(); } while ( rnd() > ((mee2 - 2.0*me2)*(sqr(p0*pp) + sqr(p0*pm)) + mee2min*((p0*pp)*(p0*pm) + sqr(p0*pp) + sqr(p0*pm)))*4.0/ (mee2*sqr(mm2 - mee2)) ); finalBoost(parent, children); setScales(parent, children); return children; } void DalitzDecayer::persistentOutput(PersistentOStream & os) const { os << rho; } void DalitzDecayer::persistentInput(PersistentIStream & is, int) { is >> rho; } void DalitzDecayer::rebind(const TranslationMap & trans) { rho = trans.translate(rho); Decayer::rebind(trans); } IVector DalitzDecayer::getReferences() { IVector ret = Decayer::getReferences(); ret.push_back(rho); return ret; } ClassDescription DalitzDecayer::initDalitzDecayer; // Definition of the static class description member. void DalitzDecayer::Init() { static ClassDocumentation documentation ("This class performs Dalitz decays into gamma e+ e-."); } diff --git a/PDT/DalitzDecayer.h b/PDT/DalitzDecayer.h --- a/PDT/DalitzDecayer.h +++ b/PDT/DalitzDecayer.h @@ -1,186 +1,176 @@ // -*- C++ -*- // // DalitzDecayer.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_DalitzDecayer_H #define THEPEG_DalitzDecayer_H // This is the declaration of the DalitzDecayer class. #include "ThePEG/PDT/Decayer.h" // #include "DalitzDecayer.fh" // #include "DalitzDecayer.xh" namespace ThePEG { /** * The DalitzDecayer inherits from the Decayer class and performs * Dalitz decays into \f$\gamma e^+ e^-\f$. * * @see \ref DalitzDecayerInterfaces "The interfaces" * defined for DalitzDecayer. */ class DalitzDecayer: public Decayer { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * Destructor. - */ - virtual ~DalitzDecayer(); - //@} - -public: - /** @name Virtual functions required by the Decayer class. */ //@{ /** * Check if this decayer can perfom the decay specified by the * given decay mode. * @param dm the DecayMode describing the decay. * @return true if this decayer can handle the given mode, otherwise false. */ virtual bool accept(const DecayMode & dm) const; /** * Perform a decay for a given DecayMode and a given Particle instance. * @param dm the DecayMode describing the decay. * @param p the Particle instance to be decayed. * @return a ParticleVector containing the decay products. */ virtual ParticleVector decay(const DecayMode & dm, const Particle & p) const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interfaces. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ virtual void rebind(const TranslationMap & trans) ; /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); //@} private: /** * Quick access to the rho particle data. */ PDPtr rho; private: /** * Describe a concrete class with persistent data. */ static ClassDescription initDalitzDecayer; /** * Private and non-existent assignment operator. */ DalitzDecayer & operator=(const DalitzDecayer &) = delete; }; } namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of DalitzDecayer. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of DalitzDecayer. */ typedef Decayer NthBase; }; /** This template specialization informs ThePEG about the name of the * DalitzDecayer class and the shared object where it is * defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::DalitzDecayer"; } /** Return the name of the shared library be loaded to get access to * the DalitzDecayer class and every other class it uses * (except the base class). */ static string library() { return "DalitzDecayer.so"; } }; /** @endcond */ } #endif /* THEPEG_DalitzDecayer_H */ diff --git a/PDT/DecayMode.cc b/PDT/DecayMode.cc --- a/PDT/DecayMode.cc +++ b/PDT/DecayMode.cc @@ -1,692 +1,690 @@ // -*- C++ -*- // // DecayMode.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the DecayMode class. // #include "DecayMode.h" #include "DecayMode.xh" #include "ThePEG/Repository/Repository.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Utilities/Rebinder.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/EnumIO.h" using namespace ThePEG; DecayMode::DecayMode() : theBrat(0.0), isOn(false) {} DecayMode::DecayMode(tPDPtr newParticle, double newBrat, bool newOn) : theBrat(newBrat), isOn(newOn), theParent(newParticle) {} DecayMode::DecayMode(const DecayMode & dm) : Interfaced(dm), theTag(dm.theTag), theBrat(dm.theBrat), isOn(dm.isOn), theParent(dm.theParent), theProducts(dm.theProducts), theOrderedProducts(dm.theOrderedProducts), theCascadeProducts(dm.theCascadeProducts), theMatchers(dm.theMatchers), theWildMatcher(dm.theWildMatcher), theExcluded(dm.theExcluded), theOverlap(dm.theOverlap), theDecayer(dm.theDecayer), theAntiPartner(dm.theAntiPartner), theLinks(dm.theLinks) {} -DecayMode::~DecayMode() {} - DMPtr DecayMode::Create(tPDPtr newParent, double newBrat, bool newOn) { DMPtr dm = new_ptr(DecayMode(newParent, newBrat, newOn)); Repository::Register(dm, newParent->fullName() + "/NEWMODE"); if ( !newParent->CC() ) return dm; DMPtr adm = new_ptr(DecayMode(newParent->CC(), newBrat, newOn)); Repository::Register(adm, newParent->CC()->fullName() + "/NEWMODE"); dm->theAntiPartner = adm; adm->theAntiPartner = dm; return dm; } void DecayMode::readSetup(istream & is) { string decnam; is >> theBrat >> ienum(isOn) >> decnam; if ( decnam.empty() ) return; BaseRepository::DirectoryAppend(decnam); setDecayer(BaseRepository::GetObject(decnam)); } IBPtr DecayMode::clone() const { return dmclone(); } DMPtr DecayMode::dmclone() const { return new_ptr(*this); } IBPtr DecayMode::fullclone() const { DMPtr dm = dmclone(); Repository::Register(dm); if ( !CC() ) return dm; DMPtr adm = CC()->dmclone(); Repository::Register(adm); dm->theAntiPartner = adm; adm->theAntiPartner = dm; return dm; } void DecayMode::doupdate() { Interfaced::doupdate(); bool redo = touched(); UpdateChecker::check(decayer(), redo); if ( !redo ) return; if ( theBrat > 0.0 && isOn && !decayer()->accept(*this) ) throw DecModNoAccept(tag(), decayer()->name()); } void DecayMode::rebind(const TranslationMap & trans) { try { theParent = trans.alwaysTranslate(theParent); ParticleMSet newProducts; trans.alwaysTranslate(inserter(newProducts), products().begin(), products().end()); products().swap(newProducts); tPDVector newOrdered; trans.alwaysTranslate(inserter(newOrdered), orderedProducts().begin(), orderedProducts().end()); theOrderedProducts.swap(newOrdered); ModeMSet newCasc; trans.alwaysTranslate(inserter(newCasc), cascadeProducts().begin(), cascadeProducts().end()); cascadeProducts().swap(newCasc); MatcherMSet newMatchers; trans.alwaysTranslate(inserter(newMatchers), productMatchers().begin(), productMatchers().end()); productMatchers().swap(newMatchers); wildProductMatcher() = trans.alwaysTranslate(wildProductMatcher()); ParticleMSet newExclude; trans.alwaysTranslate(inserter(newExclude), excluded().begin(), excluded().end()); excluded().swap(newExclude); theAntiPartner = trans.alwaysTranslate(CC()); for ( int i = 0, N = theLinks.size(); i < N; ++i ) { theLinks[i].first = trans.alwaysTranslate(theLinks[i].first); theLinks[i].second = trans.alwaysTranslate(theLinks[i].second); } } catch (IBPtr ip) { throw DecModRebind(name(), ip->name()); } catch (...) { throw DecModRebind(name(), ""); } } IVector DecayMode::getReferences() { IVector ret; ret.push_back(theParent); ret.insert(ret.end(), products().begin(), products().end()); ret.insert(ret.end(), cascadeProducts().begin(), cascadeProducts().end()); ret.insert(ret.end(), productMatchers().begin(), productMatchers().end()); if ( wildProductMatcher() ) ret.push_back(wildProductMatcher()); ret.insert(ret.end(), excluded().begin(), excluded().end()); if ( CC() ) ret.push_back(CC()); return ret; } bool DecayMode::addOverlap(tcDMPtr d) { bool inc = includes(*d); if ( !inc ) return false; if ( find(theOverlap.begin(), theOverlap.end(), d) != theOverlap.end() ) return true; theOverlap.push_back(d); return true; } void DecayMode::resetOverlap() { theOverlap.clear(); } bool DecayMode:: compareId(const ParticleMSet & s1, const ParticleMSet & si2) const { if ( generator() ) return s1 == si2; ParticleMSet s2 = si2; for ( ParticleMSet::const_iterator p1 = s1.begin(); p1 != s1.end(); ++p1 ) { ParticleMSet::const_iterator p2 = s2.begin(); while ( p2 != s2.end() && (**p2).id() != (**p1).id() ) ++p2; if ( p2 == s2.end() ) return false; s2.erase(p2); } return s2.empty(); } ParticleMSet::const_iterator DecayMode::findId(const ParticleMSet & s, const ParticleData & p) const { for ( ParticleMSet::const_iterator pit = s.begin(); pit != s.end(); ++pit ) if ( (**pit).id() == p.id() ) return pit; return s.end(); } struct IdCmp { bool operator()(tcPDPtr p1, tcPDPtr p2) const { return p1->id() == p2->id(); } }; bool DecayMode::includes(const DecayMode & d) const { // Fast check for ordinary decay modes. if ( cascadeProducts().empty() && productMatchers().empty() && excluded().empty() && !wildProductMatcher() && d.cascadeProducts().empty() && d.productMatchers().empty() && d.excluded().empty() && !d.wildProductMatcher() ) { if ( links().size() != d.links().size() ) return false; if ( !compareId(products(), d.products()) ) return false; LinkVector dlinks = d.links(); for ( int i = 0, N = links().size(); i < N; ++i ) { for ( int j = 0, M = dlinks.size(); j < M; ++j ) { if ( ( links()[i].first->id() == dlinks[j].first->id() && links()[i].second->id() == dlinks[j].second->id() ) || ( links()[i].first->id() == dlinks[j].second->id() && links()[i].second->id() == dlinks[j].first->id() ) ) { dlinks.erase(dlinks.begin() + j); break; } } return false; } return dlinks.empty(); } // First check that none of the excluded products in this are // present in the other. ParticleMSet::const_iterator pit; for ( pit = excluded().begin(); pit != excluded().end(); ++pit ) { if ( findId(d.products(), **pit ) != d.products().end() ) return false; for ( ModeMSet::const_iterator mit = d.cascadeProducts().begin(); mit != d.cascadeProducts().end(); ++mit ) if ( (**pit).id() == (**mit).parent()->id() ) return false; } // Check that all cascade decays in this overlaps with one in the // other. Save the ones that are left ModeMSet cascleft = d.cascadeProducts(); for ( ModeMSet::iterator mit = cascadeProducts().begin(); mit != cascadeProducts().end(); ++mit ) { ModeMSet::iterator mit2 = cascleft.begin(); while ( mit2 != cascleft.end() && !(**mit).includes(**mit2) ) ++mit2; if ( mit2 == cascleft.end() ) return false; } // Check that all cascade product parents in the other matches // something in this. Otherwise expand the cascade product. ParticleMSet partleft = d.products(); MatcherMSet matchleft = d.productMatchers(); ParticleMSet excludeleft = d.excluded(); MatcherMSet wildleft; if ( d.wildProductMatcher() ) wildleft.insert(wildProductMatcher()); ParticleMSet part = products(); MatcherMSet match = productMatchers(); while ( cascleft.size() ) { ModeMSet::iterator cdmit = cascleft.begin(); cDMPtr cdm = *cdmit; ParticleMSet::iterator pit = findId(part, *(cdm->parent())); if ( pit != part.end() ) { cascleft.erase(cdmit); part.erase(pit); } else { MatcherMSet::iterator mit = match.begin(); while ( mit != match.end() && !(**mit).matches(*(cdm->parent())) ) ++mit; if ( mit != match.end() ) { cascleft.erase(cdmit); match.erase(mit); } else { if ( wildProductMatcher() && wildProductMatcher()->matches(*(cdm->parent())) ) { cascleft.erase(cdmit); } else { cascleft.erase(cdmit); partleft.insert(cdm->products().begin(), cdm->products().end()); matchleft.insert(cdm->productMatchers().begin(), cdm->productMatchers().end()); if ( cdm->wildProductMatcher() ) wildleft.insert(cdm->wildProductMatcher()); excludeleft.insert(cdm->excluded().begin(), cdm->excluded().end()); cascleft.insert(cdm->cascadeProducts().begin(), cdm->cascadeProducts().end()); } } } } // Check that all excluded left in the other are absent in this. if ( find_first_of(excludeleft.begin(), excludeleft.end(), part.begin(), part.end(), IdCmp()) != excludeleft.end() ) return false; // Now all particles and matches left in this must match something // in the other. pit = part.begin(); while ( pit != part.end() ) { ParticleMSet::iterator pit2 = findId(partleft, **pit++); if ( pit2 == partleft.end() ) return false; partleft.erase(pit2); } MatcherMSet::const_iterator pmit = match.begin(); while ( pmit != match.end() ) { ParticleMSet::iterator pit2 = partleft.begin(); while ( pit2 != partleft.end() && ! (**pmit).matches(**pit2) ) ++pit2; if ( pit2 != partleft.end() ) { partleft.erase(pit2); } else { MatcherMSet::iterator pmit2 = matchleft.begin(); while ( pmit2 != matchleft.end() && ! (**pmit).matches(**pmit2) ) ++pmit2; if ( pmit2 != matchleft.end() ) { matchleft.erase(pmit2); } else return false; } } // Now all particles and matchers left in the other must be matched // by the wild match in this. if ( wildProductMatcher() ) { pit = partleft.begin(); while ( pit != partleft.end() ) if ( !(wildProductMatcher()->matches(**pit++)) ) return false; pmit = matchleft.begin(); while (pmit != matchleft.end() ) if ( !(wildProductMatcher()->matches(**pmit++)) ) return false; pmit = wildleft.begin(); while (pmit != wildleft.end() ) if ( !(wildProductMatcher()->matches(**pmit++)) ) return false; } else return partleft.empty() && matchleft.empty() && wildleft.empty(); return true; } DMPtr DecayMode::clone(tPDPtr pd) const { DMPtr dm = dmclone(); dm->theParent = pd; Repository::Register(dm, pd->fullName() + "/" + dm->name()); if ( !theDecayer || !theDecayer->accept(*dm) ) dm->isOn = false; if ( pd->CC() ) { DMPtr adm = CC()? CC()->dmclone(): dmclone(); adm->theParent = pd->CC(); Repository::Register(adm, pd->CC()->fullName() + "/" + adm->name()); dm->theAntiPartner = adm; adm->theAntiPartner = dm; if ( !adm->theDecayer->accept(*adm) ) adm->isOn = false; } else dm->theAntiPartner = DMPtr(); return dm; } void DecayMode::synchronize() { if ( !CC() ) return; theBrat = CC()->theBrat; isOn = CC()->isOn; theDecayer = CC()->theDecayer; } struct ParticleOrdering { bool operator()(tcPDPtr p1, tcPDPtr p2) const { return abs(p1->id()) > abs(p2->id()) || ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) || ( p1->id() == p2->id() && p1->fullName() > p2->fullName() ); } }; struct ModeOrdering { bool operator()(tcDMPtr d1, tcDMPtr d2) const { ParticleOrdering ord; return ord(d1->parent(), d2->parent()) || ( !ord(d2->parent(), d1->parent()) && ( d1->tag() < d2->tag() || ( d1->tag() == d2->tag() && d1->fullName() < d2->fullName() ) ) ); } }; struct MatcherOrdering { bool operator()(tcPMPtr m1, tcPMPtr m2) const { return m1->name() < m2->name() || ( m1->name() == m2->name() && m1->fullName() < m2->fullName() ); } }; PVector DecayMode::produceProducts() const { PVector ret; for ( int i = 0, N = orderedProducts().size(); i < N; ++i ) ret.push_back(orderedProducts()[i]->produceParticle()); return ret; } string DecayMode::makeTag() const { string ret; typedef multiset OrderedParticles; typedef multiset OrderedMatchers; typedef multiset OrderedModes; LinkVector dlinks = links(); ret = theParent->PDGName() + "->"; if ( dlinks.empty() ) { OrderedParticles prod(products().begin(), products().end()); for (OrderedParticles::iterator pit = prod.begin(); pit != prod.end(); ++pit ) ret += (**pit).PDGName() + ","; } else { unsigned int dl = 0; for ( int i = 0, N = orderedProducts().size(); i < N; ++i ) { if ( dl < dlinks.size() && orderedProducts()[i] == dlinks[dl].first ) { ret += orderedProducts()[i]->PDGName() + "="; ++dl; } else ret += orderedProducts()[i]->PDGName() + ","; } } OrderedModes casc(cascadeProducts().begin(), cascadeProducts().end()); for ( OrderedModes::iterator dmit = casc.begin();dmit != casc.end(); ++dmit ) ret += "[" + (**dmit).tag() + "],"; OrderedMatchers match(productMatchers().begin(), productMatchers().end()); for ( OrderedMatchers::iterator mit = match.begin(); mit != match.end(); ++mit ) ret += "?" +(**mit).name() + ","; if ( theWildMatcher ) ret += "*" + theWildMatcher->name() + ","; OrderedParticles ex(excluded().begin(), excluded().end()); for ( OrderedParticles::iterator pit = ex.begin(); pit != ex.end(); ++pit ) ret += "!" + (**pit).PDGName() + ","; ret[ret.size()-1] = ';'; return ret; } void DecayMode::brat(double newBrat) { theBrat = newBrat; if ( theBrat <= 0.0 ) switchOff(); if ( CC() && parent()->synchronized() ) CC()->theBrat = newBrat; } double DecayMode::brat() const { return isOn? theDecayer->brat(*this, *theParent, theBrat): 0.0; } double DecayMode::brat(const Particle & p) const { return isOn && p.dataPtr() == parent()? theDecayer->brat(*this, p, theBrat): 0.0; } void DecayMode::switchOn() { isOn = true; if ( CC() && parent()->synchronized() ) CC()->isOn = true; } void DecayMode::switchOff() { isOn = false; if ( CC() && parent()->synchronized() ) CC()->isOn = false; } void DecayMode::addProduct(tPDPtr pd) { products().insert(pd); theOrderedProducts.push_back(pd); if ( CC() ) { CC()->products().insert(pd->CC()? pd->CC(): pd); CC()->theOrderedProducts.push_back(pd->CC()? pd->CC(): pd); } resetTag(); } void DecayMode::addLink(tPDPtr a, tPDPtr b) { theLinks.push_back(make_pair(a, b)); if ( CC() ) CC()->theLinks.push_back(make_pair(a->CC()? a->CC(): a, b->CC()? b->CC(): b)); resetTag(); } void DecayMode::addCascadeProduct(tDMPtr dm) { cascadeProducts().insert(dm); if ( CC() ) CC()->cascadeProducts().insert(dm->CC()? dm->CC(): dm); resetTag(); } void DecayMode::addProductMatcher( tPMPtr pm) { productMatchers().insert(pm); if ( CC() ) CC()->productMatchers().insert(pm->CC()? pm->CC(): pm); resetTag(); } void DecayMode::setWildMatcher(tPMPtr pm) { wildProductMatcher() = pm; if ( CC() ) CC()->wildProductMatcher() = pm->CC()? pm->CC(): pm; resetTag(); } void DecayMode::addExcluded(tPDPtr pd) { excluded().insert(pd); if ( CC() ) CC()->excluded().insert(pd->CC()? pd->CC(): pd); resetTag(); } void DecayMode::decayer(tDecayerPtr dec) { if ( !dec || !dec->accept(*this) ) throw DecModSetupNoAccept(tag(), dec->name()); if ( CC() && parent()->synchronized() ) { if ( !dec->accept(*CC()) ) throw DecModSetupNoAccept(CC()->tag(), dec->name()); CC()->theDecayer = dec; } theDecayer = dec; } DMPtr DecayMode::constructDecayMode(string & tag, vector * save) { DMPtr rdm; DMPtr adm; int level = 0; string::size_type end = 0; while ( end < tag.size() && ( tag[end] != ']' || level ) ) { switch ( tag[end++] ) { case '[': ++level; break; case ']': --level; break; } } string::size_type next = tag.find("->"); if ( next == string::npos ) return rdm; if ( tag.find(';') == string::npos ) return rdm; tPDPtr pd = Repository::findParticle(tag.substr(0,next)); if ( !pd ) return rdm; rdm = ptr_new(); rdm->parent(pd); if ( pd->CC() ) { adm = ptr_new(); adm->parent(pd->CC()); rdm->theAntiPartner = adm; adm->theAntiPartner = rdm; } bool error = false; tag = tag.substr(next+2); tPDPtr lastprod; bool dolink = false; do { switch ( tag[0] ) { case '[': { tag = tag.substr(1); DMPtr cdm = constructDecayMode(tag, save); if ( save ) save->push_back(cdm); if ( cdm ) rdm->addCascadeProduct(cdm); else error = true; } break; case '=': dolink = true; [[fallthrough]]; case ',': case ']': tag = tag.substr(1); break; case '?': { next = min(tag.find(','), tag.find(';')); tPMPtr pm = Repository::findMatcher(tag.substr(1,next-1)); if ( pm ) rdm->addProductMatcher(pm); else error = true; tag = tag.substr(next); } break; case '!': { next = min(tag.find(','), tag.find(';')); tPDPtr pd = Repository::findParticle(tag.substr(1,next-1)); if ( pd ) rdm->addExcluded(pd); else error = true; tag = tag.substr(next); } break; case '*': { next = min(tag.find(','), tag.find(';')); tPMPtr pm = Repository::findMatcher(tag.substr(1,next-1)); if ( pm ) rdm->setWildMatcher(pm); else error = true; tag = tag.substr(next); } break; default: { next = min(tag.find('='), min(tag.find(','), tag.find(';'))); tPDPtr pdp = Repository::findParticle(tag.substr(0,next)); if ( pdp ) rdm->addProduct(pdp); else error = true; tag = tag.substr(next); if ( dolink && lastprod ) { rdm->addLink(lastprod, pdp); dolink = false; } lastprod = pdp; } break; } } while ( tag[0] != ';' && tag.size() ); if ( tag[0] != ';' || error ) { return DMPtr(); } tag = tag.substr(1); for ( DecaySet::const_iterator dit = pd->decayModes().begin(); dit != pd->decayModes().end(); ++dit ) if ( (**dit).tag() == rdm->tag() ) return *dit; if ( save ) { save->push_back(rdm); save->push_back(adm); } else { pd->addDecayMode(rdm); Repository::Register(rdm, pd->fullName() + "/" + rdm->tag()); if ( adm ) Repository::Register(adm, pd->CC()->fullName() + "/" + adm->tag()); } return rdm; } void DecayMode::persistentOutput(PersistentOStream & os) const { multiset prod(products().begin(), products().end()); multiset casc(cascadeProducts().begin(), cascadeProducts().end()); multiset match(productMatchers().begin(), productMatchers().end()); multiset ex(excluded().begin(), excluded().end()); multiset ovlap(overlap().begin(), overlap().end()); os << theTag << theBrat << isOn << theParent << prod << theOrderedProducts << casc << match << theWildMatcher << ex << ovlap << theDecayer << theAntiPartner << theLinks; } void DecayMode::persistentInput(PersistentIStream & is, int) { is >> theTag >> theBrat >> isOn >> theParent >> theProducts >> theOrderedProducts >> theCascadeProducts >> theMatchers >> theWildMatcher >> theExcluded >> theOverlap >> theDecayer >> theAntiPartner >> theLinks; } ClassDescription DecayMode::initDecayMode; void DecayMode::setOn(long i) { isOn = i; } long DecayMode::getOn() const { return isOn; } void DecayMode::setDecayer(DecayerPtr dp) { decayer(dp); } void DecayMode::Init() { static ClassDocumentation documentation ("Represents a specific decay channel of a particle."); static Parameter interfaceBrat ("BranchingRatio", "The branching fraction for this decay mode. Note that if the sum of " "branching ratios for one particle is always renormalized to 1. Also, " "the decaying particle may change this branching ratio if it has a " "ThePEG::WidthGenerator object assigned to it. ", &DecayMode::theBrat, 0.0, 0.0, 1.0, false, false, true); interfaceBrat.setHasDefault(false); static Switch interfaceOn ("OnOff", "Indicates if the decay mode is switched on or off.", 0, 0, false, false, &DecayMode::setOn, &DecayMode::getOn); static SwitchOption interfaceOnYes (interfaceOn, "On", "The decay channel is switched on.", 1); static SwitchOption interfaceOnNo (interfaceOn, "Off", "The decay channel is switched off.", 0); interfaceOn.setHasDefault(false); static Switch interfaceActive ("Active", "Indicates if the decay mode is switched on or off.", 0, 0, false, false, &DecayMode::setOn, &DecayMode::getOn); static SwitchOption interfaceActiveYes (interfaceActive, "Yes", "The decay channel is switched on.", 1); static SwitchOption interfaceActiveNo (interfaceActive, "No", "The decay channel is switched off.", 0); interfaceActive.setHasDefault(false); static Reference interfaceDecayer ("Decayer", "The ThePEG::Decayer object responsible for performing this decay.", &DecayMode::theDecayer, false, false, true, false, &DecayMode::setDecayer); interfaceBrat.rank(10); interfaceDecayer.rank(9); interfaceOn.rank(8); interfaceActive.rank(8); } DecModNoAccept::DecModNoAccept(string tag, string dec) { theMessage << "The Decayer '" << dec << "' is not capable to " << "perform the decay in the DecayMode '" << tag << "'."; severity(warning); } DecModSetupNoAccept::DecModSetupNoAccept(string tag, string dec) { theMessage << "The Decayer '" << dec << "' is not capable to " << "perform the decay in the DecayMode '" << tag << "'."; severity(warning); } DecModRebind::DecModRebind(string tag, string obj) { theMessage << "'Rebind' of DecayMode '" << tag << "' failed because " << "the object '" << obj << "' refered to lacked a translation."; severity(abortnow); } diff --git a/PDT/DecayMode.h b/PDT/DecayMode.h --- a/PDT/DecayMode.h +++ b/PDT/DecayMode.h @@ -1,607 +1,602 @@ // -*- C++ -*- // // DecayMode.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_DecayMode_H #define ThePEG_DecayMode_H // This is the declaration of the DecayMode class. #include "ThePEG/Config/ThePEG.h" #include "ThePEG/Interface/Interfaced.h" #include "DecayMode.fh" #include "MatcherBase.h" #include "Decayer.h" namespace ThePEG { ThePEG_DECLARE_MULTISET(tPDPtr,ParticleMSet); ThePEG_DECLARE_MULTISET(tPMPtr,MatcherMSet); ThePEG_DECLARE_MULTISET(tDMPtr,ModeMSet); /** * The DecayMode class describes a decay channel of a particle. In its * simplest form it contains simply a parent ParticleData object and a * list of decay products, but it can also specify a set of * MatcherBase objects each representing one of a set of possible * decay products. A matcher can also be specified to represents an * unlimited set of decay products. Decay chains can be represented by * specifying other decay channels where the parents are taken to be * intermediate resonances. It is also possible to specify the absence * of intermediate resonances. * * Each decay mode can be uniquely described by a character string on * the form * {decaying-particle-name}->{decay-product-specifier}[,{decay-product-specifier},...]; * where no spaces are allowed anywhere. The decaying-particle-name * should be a path to a particle in the Repository or a * PDG-standardized particle name (see ParticleData::PDGName()) and * the decay-product-specifier can be one of the following: * *
    * *
  • a path to a particle in the Repository or a PDG-standardized * particle name if it is a specific decay product, * *
  • a question mark followed by the name of a particle matcher * object in the Repository if representing one of several different * alternative decay products, * *
  • a star followed by the name of a particle matcher object in * the Repository if representing any number of several different * alternative decay products (note that only one of these * wild-card matchers may be specified, if several are given * only the last one will be taken into account), * *
  • a whole decay mode string enclosed in square brackets if * representing a resonance decay product with a specified decay mode, * *
  • an exclamation mark followed by a path to a particle in the * Repository or a PDG-standardized particle name representing the * exclusion of an intermediate resonance decaying into the other * specified decay products. * *
  • two paths to particles in the Repository or PDG-standardized * particle names with an equal sign between, indicating two coloured * particles which are in a colour-singlet state. * *
* * Note that the order of the specified decay products will be * preserved when the corresponding particles are produced in a decay. * * The possibility of specifying matchers as decay products means that * one decay mode may overlap with another one. When an EventGenerator * is initialized all decay modes are checked so that a given decay * mode afterwards will report if there are other modes which are * matched by its matchers through the overlap() function. * * @see \ref DecayModeInterfaces "The interfaces" * defined for DecayMode. * @see ParticleData * @see MatcherBase */ class DecayMode: public Interfaced { public: /** ParticleData is a friend. */ friend class ParticleData; /** RemnantData is a friend. */ friend class RemnantData; /** The EventGenerator is a friend. */ friend class EventGenerator; public: /** A vector of DecayMode pointers. */ typedef vector ModeVector; /** A vector of pairs of ParticleData pointers. */ typedef vector LinkVector; public: /** * Create a decay mode from a given tag. This function is used * directly by the Repository. If name of the decaying particle is a * valid path to a particle object, the decaymode will be added to * that particle, otherwise it will be added to the default particle * of that name. */ static DMPtr constructDecayMode(string & tag, vector * save = 0); /** @name Standard constructors and destructors. */ //@{ /** * Default constructor. */ DecayMode(); /** * Copy-constructor. */ DecayMode(const DecayMode &); - - /** - * Destructor. - */ - ~DecayMode(); //@} /** * Return a clone of this decay mode with \a pd as the decaying * particle. */ virtual DMPtr clone(tPDPtr pd) const; public: /** * Return the tag for this decay mode. This string is a unique * identifier for this decay mode. */ const string & tag() const { return theTag.size() ? theTag : ( theTag = makeTag() ); } /** * Get a pointer to the particle data object corresponding to * the decaying particle. */ tcPDPtr parent() const { return theParent; } /** * The set of identified decay products. */ const ParticleMSet & products() const { return theProducts; } /** * The set of identified decay products in the order they were specified. */ const tPDVector & orderedProducts() const { return theOrderedProducts; } /** * Produce particles corresponding to the identified decay * products. They will be orderd in the same order they were * sspecified. */ PVector produceProducts() const; /** * The set of identified resonance products with specified decay * modes */ const ModeMSet & cascadeProducts() const { return theCascadeProducts; } /** * The set of matchers each corresponding to one decay product. */ const MatcherMSet & productMatchers() const { return theMatchers; } /** * The pointer to a matcher corresponding to any number of decay * products */ tPMPtr wildProductMatcher() const { return theWildMatcher; } /** * The set particles corresponding to excluded intermediate * resonances. */ const ParticleMSet & excluded() const { return theExcluded; } /** * Return the branching ratio to be used. */ double brat() const; /** * Calculate the branching ratio for a particular particle instance. */ double brat(const Particle &) const; /** * Get the decayer assigned to this mode. */ tDecayerPtr decayer() const { return theDecayer; } /** * Check if another decay mode is included in this one. */ bool includes(const DecayMode &) const; /** * Return a pointer to the corresponding decaymode for the * antiparticle decay. */ tDMPtr CC() const { return theAntiPartner; } /** * Check if another decay mode has the same final state as this * one. */ bool operator == (const DecayMode & d) const { return tag() == d.tag() ; } /** * Return a vector of pairs of decay products which are linked * together (e.g. colourless q-qbar pairs). */ const LinkVector & links() const { return theLinks; } /** * Return the list of overlapping decay modes. */ const ModeVector & overlap() const { return theOverlap; } /** * Modify this mode to have properties corresponding to its anti-partner. */ void synchronize(); /** * Check whether this decay mode is switched on */ bool on() const { return isOn; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interface. */ static void Init(); protected: /** @name Standard Interfaced functions. */ //@{ /** * Check sanity of the object during the setup phase. */ virtual void doupdate(); /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ virtual void rebind(const TranslationMap & trans) ; /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); //@} protected: /** * Set a pointer to the particle data object corresponding to * the decaying particle. */ void parent(tPDPtr pd) { theParent = pd; } /** * Set the branching ratio to be used. */ void brat(double); /** * Switch on this decay mode. */ void switchOn(); /** * Switch off this decay mode. */ void switchOff(); /** * Set the decayer. The set method returns false if the decayer * does not claim to be able to handle the decay. */ void decayer(tDecayerPtr); /** * Add identified decay products. */ void addProduct(tPDPtr); /** * Add a pair of decay products which are linked together * (e.g. colourless q-qbar pairs). */ void addLink(tPDPtr a, tPDPtr b); /** * Add identified resonant product with specified decay mode. */ void addCascadeProduct(tDMPtr); /** * Add a mathcer corresponding to one decay product. */ void addProductMatcher(tPMPtr); /** * Add a matcher corresponding to any number of decay products. */ void setWildMatcher(tPMPtr); /** * Add a particle corresponding to an excluded intermediate * resonance. */ void addExcluded(tPDPtr); /** * Protected creation and clone methods. */ static DMPtr Create(tPDPtr newParent, double newBrat = 0.0, bool newOn = false); /** * Protected constructor. */ DecayMode(tPDPtr newParticle, double newBrat, bool newOn); /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} /** * Protected special clone function. */ DMPtr dmclone() const; /** * Read setup info from a standard stream used by the * Repository. The following information must be supplied in a * white-space separated list: the branching ratio, on or off (true * or false), and the name of a Decayer. */ virtual void readSetup(istream & is); /** * The set of identified decay products. */ ParticleMSet & products() { return theProducts; } /** * The set of identified resonant products with specified decay * modes */ ModeMSet & cascadeProducts() { return theCascadeProducts; } /** * The set of matchers each corresponding to one decay product. */ MatcherMSet & productMatchers() { return theMatchers; } /** * The pointer to a matcher corresponding to any number of decay * products */ tPMPtr & wildProductMatcher() { return theWildMatcher; } /** * The set particles corresponding to excluded intermediate * resonances. */ ParticleMSet & excluded() { return theExcluded; } /** * Set the pointer to the corresponding decaymode for the * antiparticle decay. */ void CC(tDMPtr cc) {theAntiPartner = cc;} private: /** * Add a decay mode to the list of overlapping modes if included. */ bool addOverlap(tcDMPtr); /** * Remove all decay modes from the list of overlapping modes. */ void resetOverlap(); /** * Check if two sets of particles have equivalent types. */ bool compareId(const ParticleMSet &, const ParticleMSet &) const; /** * Check if a particle set contains a given particle ID. */ ParticleMSet::const_iterator findId(const ParticleMSet &, const ParticleData &) const; /** * Use the members in this decay channel and generate the * corresponding tag. */ string makeTag() const; /** * Delete the tag (it will be regenerated later if asked for). */ void resetTag() { theTag = ""; if ( CC() ) CC()->theTag = ""; } private: /** * Utility function for the interface. */ void setOn(long); /** * Utility function for the interface. */ long getOn() const; /** * Utility function for the interface. */ void setDecayer(DecayerPtr); private: /** * The tag. */ mutable string theTag; /** * The branching ratio. */ double theBrat; /** * True if this mode is switched on. */ bool isOn; /** * Pointer to a particle data object corresponding to the decaying * particle. */ tPDPtr theParent; /** * The set of specified decay particles. */ ParticleMSet theProducts; /** * The set of specified decay particles in the order they was specified. */ tPDVector theOrderedProducts; /** * The set of matching decay channels corresponding to a specified * with a specified subsequent decay mode. */ ModeMSet theCascadeProducts; /** * The set of matching decay products. Each of the matchers * correspond to one particle. */ MatcherMSet theMatchers; /** * A particle matcher which corresponds to zero or more particles. */ tPMPtr theWildMatcher; /** * A set of particles which are not allowed as intermediate * resonances. */ ParticleMSet theExcluded; /** * A list of decay modes which are included in this one. */ ModeVector theOverlap; /** * The decayer object responsible for performing the decay. */ DecayerPtr theDecayer; /** * The corresponding decay mode of the anti particle. */ tDMPtr theAntiPartner; /** * The vector of pairs of decay products which are linked together * (e.g. colourless q-qbar pairs). */ LinkVector theLinks; private: /** * Describe a concrete class with persistent data. */ static ClassDescription initDecayMode; /** * Private and non-existent assignment operator. */ DecayMode & operator=(const DecayMode &) = delete; }; /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of DecayMode. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of DecayMode. */ typedef Interfaced NthBase; }; /** This template specialization informs ThePEG about the name of the * DecayMode class. */ template <> struct ClassTraits: public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::DecayMode"; } }; /** @endcond */ } #endif /* ThePEG_DecayMode_H */ diff --git a/PDT/MatcherBase.cc b/PDT/MatcherBase.cc --- a/PDT/MatcherBase.cc +++ b/PDT/MatcherBase.cc @@ -1,201 +1,199 @@ // -*- C++ -*- // // MatcherBase.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the MatcherBase class. // #include "MatcherBase.h" #include "DecayMode.h" #include "ThePEG/Utilities/Rebinder.h" #include "ThePEG/Repository/Repository.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Utilities/EnumIO.h" #include "ThePEG/Interface/ClassDocumentation.h" using namespace ThePEG; MatcherBase::MatcherBase() : theMaxMass(ZERO), theMinMass(ZERO), commonMass(-1.0*GeV), commonWidth(-1.0*GeV), commonCTau(-1.0*mm), commonCharge(PDT::ChargeUndefined), commonSpin(PDT::SpinUndefined), commonColour(PDT::ColourUndefined), commonStable(-1) {} MatcherBase::MatcherBase(const MatcherBase & m) : Interfaced(m), theMaxMass(m.theMaxMass), theMinMass(m.theMinMass), commonMass(m.commonMass), commonWidth(m.commonWidth), commonCTau(m.commonCTau), commonCharge(m.commonCharge), commonSpin(m.commonSpin), commonColour(m.commonColour), commonStable(m.commonStable), theAntiPartner(m.theAntiPartner) {} -MatcherBase::~MatcherBase() {} - void MatcherBase::doupdate() { Interfaced::doupdate(); tPDSet oldParticles; tPMSet oldMatchers; Energy oldMass = commonMass; Energy oldWidth = commonWidth; Length oldCTau = commonCTau; PDT::Spin oldSpin = commonSpin; PDT::Charge oldCharge = commonCharge; PDT::Colour oldColour = commonColour; int oldStable = commonStable; matchingParticles.swap(oldParticles); matchingMatchers.swap(oldMatchers); if ( generator() ) { for ( ParticleMap::const_iterator it = generator()->particles().begin(); it != generator()->particles().end(); ++it ) addPIfMatch(it->second); addMIfMatchFrom(generator()->matchers()); } else { addPIfMatchFrom(Repository::allParticles()); addMIfMatchFrom(Repository::allMatchers()); } if ( matchingParticles != oldParticles || matchingMatchers != oldMatchers || oldMass != commonMass || oldWidth != commonWidth || oldCTau != commonCTau || oldSpin != commonSpin || oldCharge != commonCharge || oldColour != commonColour || oldStable != commonStable ) touch(); } void MatcherBase::clear() { matchingParticles.clear(); matchingMatchers.clear(); theMaxMass = ZERO; theMinMass = ZERO; commonMass = -1.0*GeV; commonWidth = -1.0*GeV; commonCTau = -1.0*mm; commonSpin = PDT::SpinUndefined; commonCharge = PDT::ChargeUndefined; commonColour = PDT::ColourUndefined; commonStable = -1; } void MatcherBase::addMIfMatch(tPMPtr pm) { if ( member(matchingMatchers, pm) ) return; pm->update(); tPDSet::const_iterator i = pm->matchingParticles.begin(); while ( i != pm->matchingParticles.end() ) if ( !member(matchingParticles, *i++) ) return; matchingMatchers.insert(pm); } void MatcherBase::addPIfMatch(tPDPtr pd) { if ( !pd || !check(*pd) || member(matchingParticles, pd) ) return; if ( matchingParticles.empty() ) { commonMass = pd->mass(); theMinMass = pd->mass(); theMaxMass = pd->mass(); commonWidth = pd->width(); commonCTau = pd->cTau(); commonCharge = pd->iCharge(); commonSpin = pd->iSpin(); commonColour = pd->iColour(); commonStable = pd->stable(); } else { if ( commonMass != pd->mass() ) commonMass = -1.0*GeV; theMinMass = min(theMinMass, pd->mass()); theMaxMass = min(theMaxMass, pd->mass()); if ( commonWidth != pd->width() ) commonWidth = -1.0*GeV; if ( commonCTau != pd->cTau() ) commonCTau = -1.0*mm; if ( commonCharge != pd->iCharge() ) { switch ( commonCharge ) { case PDT::ChargeUndefined: break; case PDT::Positive: if ( PDT::negative(pd->iCharge()) ) commonCharge = PDT::Charged; else if ( !PDT::positive(pd->iCharge()) ) commonCharge = PDT::ChargeUndefined; break; case PDT::Negative: if ( PDT::positive(pd->iCharge()) ) commonCharge = PDT::Charged; else if ( !PDT::negative(pd->iCharge()) ) commonCharge = PDT::ChargeUndefined; break; case PDT::Charged: if ( !PDT::charged(pd->iCharge()) ) commonCharge = PDT::ChargeUndefined; break; default: if ( PDT::positive(commonCharge) ) { if ( PDT::positive(pd->iCharge()) ) commonCharge = PDT::Positive; else if ( PDT::negative(pd->iCharge()) ) commonCharge = PDT::Charged; else commonCharge = PDT::ChargeUndefined; } else if ( PDT::negative(commonCharge) ) { if ( PDT::negative(pd->iCharge()) ) commonCharge = PDT::Negative; else if ( PDT::positive(pd->iCharge()) ) commonCharge = PDT::Charged; else commonCharge = PDT::ChargeUndefined; } else commonCharge = PDT::ChargeUndefined; } } if ( commonSpin != pd->iSpin() ) commonSpin = PDT::SpinUndefined; if ( commonColour != pd->iColour() ) { if ( PDT::coloured(commonColour) && PDT::coloured(pd->iColour()) ) commonColour = PDT::Coloured; else commonColour = PDT::ColourUndefined; if ( commonStable != pd->stable() ) commonStable = -1; } } matchingParticles.insert(pd); } struct ParticleOrdering { bool operator()(tcPDPtr p1, tcPDPtr p2) const { return abs(p1->id()) > abs(p2->id()) || ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) || ( p1->id() == p2->id() && p1->fullName() > p2->fullName() ); } }; struct MatcherOrdering { bool operator()(tcPMPtr m1, tcPMPtr m2) const { return m1->name() < m2->name() || ( m1->name() == m2->name() && m1->fullName() < m2->fullName() ); } }; void MatcherBase::persistentOutput(PersistentOStream & os ) const { multiset parts(particles().begin(), particles().end()); multiset match(matchers().begin(), matchers().end()); os << parts << match << ounit(theMaxMass, GeV) << ounit(theMinMass, GeV) << ounit(commonMass, GeV) << ounit(commonWidth, GeV) << ounit(commonCTau, mm) << oenum(commonCharge) << oenum(commonSpin) << oenum(commonColour) << commonStable << theAntiPartner; } void MatcherBase::persistentInput(PersistentIStream & is, int) { is >> matchingParticles >> matchingMatchers >> iunit(theMaxMass, GeV) >> iunit(theMinMass, GeV) >> iunit(commonMass, GeV) >> iunit(commonWidth, GeV) >> iunit(commonCTau, mm) >> ienum(commonCharge) >> ienum(commonSpin) >> ienum(commonColour) >> commonStable >> theAntiPartner; } AbstractClassDescription MatcherBase::initMatcherBase; void MatcherBase::Init() { static ClassDocumentation documentation ("This is the base class for objects representing groups of particle " "types."); } diff --git a/PDT/MatcherBase.h b/PDT/MatcherBase.h --- a/PDT/MatcherBase.h +++ b/PDT/MatcherBase.h @@ -1,420 +1,415 @@ // -*- C++ -*- // // MatcherBase.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_MatcherBase_H #define ThePEG_MatcherBase_H // This is the declaration of the MatcherBase class. #include "ParticleData.h" #include "ThePEG/EventRecord/Particle.h" namespace ThePEG { /** * MatcherBase is an abstract base class to be used for objects * representing groups of ParticleData objects. Concrete * implementations will typically use the templated Matcher class for * easy building of a full sub-class. * * @see ParticleData * @see Matcher * */ class MatcherBase: public Interfaced { public: /** Repository needs to be a friend. */ friend class Repository; /** * Convenient typedef. */ typedef set tPDSet; /** * Convenient typedef. */ typedef set tPMSet; public: /** @name Standard constructors and destructors. */ //@{ /** * Default constructor. */ MatcherBase(); /** * Copy-constructor. */ MatcherBase(const MatcherBase &); - - /** - * Destructor. - */ - virtual ~MatcherBase(); //@} public: /** @name Virtual functions to be overridden by sub-classes. */ //@{ /** * Check if a particle type meets the criteria. */ virtual bool check(const ParticleData &) const = 0; /** * Specialized clone method for MatcherBase used by the * Repository. A sub class must make sure that also the MatcherBase * object corresponding to the complex conjugate of this is cloned. */ virtual PMPtr pmclone() const = 0; //@} /** @name Check if something is matched. */ //@{ /** * Check if a Particle meets the criteria. */ bool checkp(const Particle & p) const { return check(p.data()); } /** * Check if a given particle type belongs to the set of * matches. This function looks for the same ParticleData object in * the set of all particles matched by this matcher. May be quicker * than to go through the check proceedure. */ bool matches(const ParticleData & pd) const { return member(matchingParticles, PDPtr(const_cast(&pd))); } /** * Check if a given particle belongs to the set of matches. This * function looks for the corresponding ParticleData object in the * set of all particles matched by this matcher. May be quicker than * to go through the check proceedure. */ bool matches(const Particle & p) const { return matches(p.data()); } /** * Check if a given particle matcher belongs to the set of * matches. This function looks for the same MatcherBase object in * the set of all matchers matched by this matcher. */ bool matches(const MatcherBase & pm) const { return member(matchingMatchers, PMPtr(const_cast(&pm))); } //@} /** @name Access the sets of matching particles and matchers. */ //@{ /** * Access to the set of matching particles. */ const tPDSet & particles() const { return matchingParticles; } /** * Access to the set of matching matchers. */ const tPMSet & matchers() const { return matchingMatchers; } //@} /** @name Access common properties of all matched particles. */ //@{ /** * Returns the minimum mass of the matching particles. */ Energy minMass() const { return theMinMass; } /** * Returns the maximum mass of the matching particles. */ Energy maxMass() const { return theMaxMass; } /** * Returns the common mass of the matching particles. If all matching * particles do not have exactly the same mass, -1.0 GeV is returned. */ Energy mass() const { return commonMass; } /** * Returns the common width of the matching particles. If all matching * particles do not have exactly the same width, -1.0 GeV is returned. */ Energy width() const { return commonWidth; } /** * Returns the common decay length of the matching particles. If all * matching particles do not have exactly the same decay length -1.0 * mm is returned. */ Length cTau() const { return commonCTau; } /** * Return common charge. If all matching particles have the same * charge the common charge is returned. Otherwise if all are * positive (negative), PDT::Positive (PDT::Negative) is * returned. Otherwise if all are charged, PDT::Charged is * returned. Otherwise PDT::ChargeUndefined is returned. */ PDT::Charge iCharge() const { return commonCharge; } /** * Are the particles charged? If all matching particles are charged, return * true, otherwise false. */ bool charged() const { return PDT::charged(commonCharge); } /** * Are the particles positively charged? If all matching particles * are positively charged, return true, otherwise false. */ bool positive() const { return PDT::positive(commonCharge); } /** * Are the particles negatively charged? If all matching particles * are negatively charged, return true, otherwise false. */ bool negative() const { return PDT::negative(commonCharge); } /** * Return common spin. If all matching particles have the same spin, * the common spin is returned. Otherwise PDT::SpinUndefined is * returned. */ PDT::Spin iSpin() const { return commonSpin; } /** * If all matching particles have the same colour, the common colour * is returned. Otherwise if all are coloured, PDT::Coloured is * returned. Otherwise PDT::ColourUndefined is returned. */ PDT::Colour iColour() const { return commonColour; } /** * Are the particles coloured? If all matching particles are * coloured, return true, otherwise false. */ bool coloured() const { return PDT::coloured(commonColour); } /** * Are the particles stable? Returns (0)1 if all matching particles * are (un)stable. Otherwise -1 is returned. */ int stable() const { return commonStable; } //@} /** * Get the matcher object matching the antiparticles of this. If * no-one exists null is returned. */ tPMPtr CC() const { return theAntiPartner; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interface. */ static void Init(); protected: /** @name Standard Interfaced functions. */ //@{ /** * Check sanity of the object during the setup phase. */ virtual void doupdate(); //@} protected: /** * Add a particle to the set of matching particles if it meets the * criteria. */ void addPIfMatch(tPDPtr); /** * Add a particle matcher to the set of matching matchers if it * meets the criteria. */ void addMIfMatch(tPMPtr); /** * Add a number of particles to the set of matching particles if * they meets the criteria. */ template void addPIfMatch(Iterator first, Iterator last) { for ( ; first != last; ++first ) addPIfMatch(*first); } /** * Add a number of particles to the set of matching particles if * they meets the criteria. */ template void addPIfMatchFrom(const Cont & c) { addPIfMatch(c.begin(), c.end()); } /** * Add a number of particle matchers to the set of matching * matchers if they meets the criteria. */ template void addMIfMatch(Iterator first, Iterator last) { for ( ; first != last; ++first ) addMIfMatch(*first); } /** * Add a number of particle matchers to the set of matching * matchers if they meets the criteria. */ template void addMIfMatchFrom(const Cont & c) { addMIfMatch(c.begin(), c.end()); } /** * Clear information about matching particles and matchers. */ void clear(); /** * Set antipartner. */ static void setCC(tPMPtr pm, tPMPtr apm) { pm->theAntiPartner = apm; apm->theAntiPartner = pm; } private: /** * The set of particle data objects matched by this matcher. */ tPDSet matchingParticles; /** * A set of matchers which matches a subset of this matcher. */ tPMSet matchingMatchers; /** * The maximum mass of all matching particles. */ Energy theMaxMass; /** * The minimum mass of all matching particles. */ Energy theMinMass; /** * The common mass of all matching particles. */ Energy commonMass; /** * The common width of all matching particles. */ Energy commonWidth; /** * The common decay length of all matching particles. */ Length commonCTau; /** * The common charge of all matching particles. */ PDT::Charge commonCharge; /** * The common spin of all matching particles. */ PDT::Spin commonSpin; /** * The common colour of all matching particles. */ PDT::Colour commonColour; /** * The common stability of all matching particles. */ int commonStable; /** * Pointer to a matcher object which matches all anti particles * which are matched by this matcher. */ tPMPtr theAntiPartner; private: /** * The static object used to initialize the description of this class. * Indicates that this is an abstract class with persistent data. */ static AbstractClassDescription initMatcherBase; /** * Private and non-existent assignment operator. */ MatcherBase & operator=(const MatcherBase &) = delete; }; /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of MatcherBase. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of MatcherBase. */ typedef Interfaced NthBase; }; /** This template specialization informs ThePEG about the name of the * MatcherBase class. */ template <> struct ClassTraits: public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::MatcherBase"; } }; /** @endcond */ } #endif /* ThePEG_MatcherBase_H */ diff --git a/PDT/Onium3GDecayer.cc b/PDT/Onium3GDecayer.cc --- a/PDT/Onium3GDecayer.cc +++ b/PDT/Onium3GDecayer.cc @@ -1,134 +1,132 @@ // -*- C++ -*- // // Onium3GDecayer.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the Onium3GDecayer class. // #include "Onium3GDecayer.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Handlers/HandlerGroup.h" #include "ThePEG/Handlers/Hint.h" #include "ThePEG/Handlers/EventHandler.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; -Onium3GDecayer::~Onium3GDecayer() {} - IBPtr Onium3GDecayer::clone() const { return new_ptr(*this); } IBPtr Onium3GDecayer::fullclone() const { return new_ptr(*this); } bool Onium3GDecayer::accept(const DecayMode & dm) const { if ( dm.products().size() != 3 || !dm.cascadeProducts().empty() || !dm.productMatchers().empty() || dm.wildProductMatcher() ) return false; if ( !VectorMesonMatcher::Check(*dm.parent()) ) return false; vector flv = PDT::flavourContent(*dm.parent()); if ( abs(flv[0]) < 4 || flv[0] + flv[1] != 0 ) return false; int ng = 0; int np = 0; for ( int i = 0; i < 3; ++i ) if ( dm.orderedProducts()[i]->id() == ParticleID::g ) ++ng; else if ( dm.orderedProducts()[i]->id() == ParticleID::gamma ) ++np; if ( ng < 2 || ng + np != 3 ) return false; return true; } ParticleVector Onium3GDecayer::decay(const DecayMode & dm, const Particle & parent) const { PVector children = FlatDecayer::decay(dm, parent); PVector gluons; for ( int i = 0, N = children.size(); i < N; ++i ) { children[i]->scale(sqr(parent.mass())); if ( children[i]->id() == ParticleID::g ) gluons.push_back(children[i]); } for ( int i = 0, N = gluons.size(); i < N; ++i ) gluons[i]->colourNeighbour(gluons[(i + 1)%N]); HintPtr h = ptr_new(); h->tag(children.begin(), children.end()); using namespace Group; generator()->currentEventHandler()-> addStep(main, shower()? cascade: hadron, tStepHdlPtr(), h); return children; } double Onium3GDecayer::reweight(const DecayMode &, const Particle & parent, const ParticleVector & ch) const { vector x(3); Energy2 m2 = parent.momentum().mass2(); x[0] = 2.0*ch[1]->momentum()*ch[2]->momentum()/m2; x[1] = 2.0*ch[2]->momentum()*ch[0]->momentum()/m2; x[2] = 2.0*ch[0]->momentum()*ch[1]->momentum()/m2; for ( int i = 0; i < 3; ++i ) if ( ch[i]->id() == ParticleID::gamma && (1.0 - x[i])*m2 < sqr(minGGMass()) ) return 0.0; return 0.5*(sqr((1.0 - x[0])/(x[1]*x[2])) + sqr((1.0 - x[1])/(x[2]*x[0])) + sqr((1.0 - x[2])/(x[0]*x[1]))); } void Onium3GDecayer::persistentOutput(PersistentOStream & os) const { os << doShower << ounit(theMinGGMass,GeV); } void Onium3GDecayer::persistentInput(PersistentIStream & is, int) { is >> doShower >> iunit(theMinGGMass,GeV); } ClassDescription Onium3GDecayer::initOnium3GDecayer; // Definition of the static class description member. void Onium3GDecayer::Init() { static ClassDocumentation documentation ("This class performs the decay of a spin-1 onium resonance into " "three gluons or two gluons and a photon. After the decay the " "collision handler is instructed to restart the generation from the " "hadronization (or optionally the parton cascade) stage."); static Switch interfaceShower ("Shower", "Should the produced gluons be showered or only hadronized?", &Onium3GDecayer::doShower, true, true, false); static SwitchOption interfaceShowerYes (interfaceShower, "Yes", "The produced gluons should be showered before hadronization.", true); static SwitchOption interfaceShowerNo (interfaceShower, "No", "The produced gluons should be hadronized whithout preceeding shower.", false); static Parameter interfaceMinGGMass ("MinGGMass", "The minimum invariant mass of the two gluons allowed in gamma-g-g " "decays.", &Onium3GDecayer::theMinGGMass, GeV, 2.0*GeV, ZERO, 10.0*GeV, true, false, true); interfaceShower.rank(10); } diff --git a/PDT/Onium3GDecayer.h b/PDT/Onium3GDecayer.h --- a/PDT/Onium3GDecayer.h +++ b/PDT/Onium3GDecayer.h @@ -1,195 +1,187 @@ // -*- C++ -*- // // Onium3GDecayer.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_Onium3GDecayer_H #define THEPEG_Onium3GDecayer_H // This is the declaration of the Onium3GDecayer class. #include "ThePEG/PDT/FlatDecayer.h" namespace ThePEG { /** * The Onium3GDecayer class inherits from performs FlatDecayer and * will reweight the flat phase space suitable to describe the decay * of a spin-1 onium resonance into three gluons or two gluons and a * photon. After the decay the collision handler is instructed to * restart the generation from the hadronization (or optionally the * parton cascade) stage. * * @see \ref Onium3GDecayerInterfaces "The interfaces" * defined for Onium3GDecayer. * @see FlatDecayer * @see ParticleData */ class Onium3GDecayer: public FlatDecayer { public: - /** @name Standard constructors and destructors. */ - //@{ /** * Default constructor. */ Onium3GDecayer() : doShower(true), theMinGGMass(2.0*GeV) {} - /** - * Destructor. - */ - virtual ~Onium3GDecayer(); - //@} - public: /** @name Virtual functions required by the Decayer class. */ //@{ /** * Check if this decayer can perfom the decay specified by the * given decay mode. * @param dm the DecayMode describing the decay. * @return true if this decayer can handle the given mode, otherwise false. */ virtual bool accept(const DecayMode & dm) const; /** * Perform a decay for a given DecayMode and a given Particle instance. * @param dm the DecayMode describing the decay. * @param p the Particle instance to be decayed. * @return a ParticleVector containing the decay products. */ virtual ParticleVector decay(const DecayMode & dm, const Particle & p) const; /** * Give a weight to a phase space point. To be overridden by * subclasses. For a given decay mode, \a dm, decaying \a parent * particle and decayproducts, \a children, distributed according to * a flat distribution in phase space, return a weight (less or * equal to unity) modifying the flat distribution to the desired * one. Note that the chosen phase space point may be rejected, but * the chosen decay channel will not. This means that the weight * returned by this function does not influence the branching * ratios. */ virtual double reweight(const DecayMode & dm, const Particle & parent, const ParticleVector & children) const; //@} /** * Return true if the produced gluons should be showered. */ bool shower() const { return doShower; } /** * Return the minimum invariant mass between two gluons in gamma-g-g * decays. */ Energy minGGMass() const { return theMinGGMass; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interfaces. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * If true the produced gluons should be showered. */ bool doShower; /** * The minimum invariant mass between two gluons in gamma-g-g * decays. */ Energy theMinGGMass; private: /** * Describe a concrete class with persistent data. */ static ClassDescription initOnium3GDecayer; /** * Private and non-existent assignment operator. */ Onium3GDecayer & operator=(const Onium3GDecayer &) = delete; }; } namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of Onium3GDecayer. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of Onium3GDecayer. */ typedef FlatDecayer NthBase; }; /** This template specialization informs ThePEG about the name of the * Onium3GDecayer class and the shared object where it is * defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::Onium3GDecayer"; } /** Return the name of the shared library be loaded to get access to * the Onium3GDecayer class and every other class it uses * (except the base class). */ static string library() { return "Onium3GDecayer.so"; } }; /** @endcond */ } #endif /* THEPEG_Onium3GDecayer_H */ diff --git a/PDT/ParticleData.cc b/PDT/ParticleData.cc --- a/PDT/ParticleData.cc +++ b/PDT/ParticleData.cc @@ -1,1077 +1,1075 @@ // -*- C++ -*- // // ParticleData.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the ParticleData class. // #include "ParticleData.h" #include "ParticleData.xh" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/Utilities/HoldFlag.h" #include "ThePEG/Utilities/Rebinder.h" #include "ThePEG/Utilities/StringUtils.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Command.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Repository/Repository.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Config/algorithm.h" #include "ThePEG/Utilities/Exception.h" #include "ThePEG/Utilities/EnumIO.h" #include "ThePEG/Repository/UseRandom.h" namespace ThePEG { ParticleData::ParticleData() : theId(0), thePDGName(""), theMass(-1.0*GeV), theWidth(-1.0*GeV), theHardProcessMass(-1.0*GeV), hardProcessMassSet(false), theHardProcessWidth(-1.0*GeV), hardProcessWidthSet(false), theWidthUpCut(-1.0*GeV), theWidthLoCut(-1.0*GeV), theCTau(-1.0*mm), theCharge(PDT::ChargeUnknown), theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), theColouredInteraction(PDT::ColouredUnknown), isStable(true), theVariableRatio(false), syncAnti(false), theDefMass(-1.0*GeV), theDefWidth(-1.0*GeV), theDefCut(-1.0*GeV), theDefCTau(-1.0*mm), theDefCharge(PDT::ChargeUnknown), theDefSpin(PDT::SpinUnknown), theDefColour(PDT::ColourUnknown), theDefColouredInteraction(PDT::ColouredUnknown) {} ParticleData:: ParticleData(PID newId, const string & newPDGName) : theId(newId), thePDGName(newPDGName), theMass(-1.0*GeV), theWidth(-1.0*GeV), theHardProcessMass(-1.0*GeV), hardProcessMassSet(false), theHardProcessWidth(-1.0*GeV), hardProcessWidthSet(false), theWidthUpCut(-1.0*GeV), theWidthLoCut(-1.0*GeV), theCTau(-1.0*mm), theCharge(PDT::ChargeUnknown), theSpin(PDT::SpinUnknown), theColour(PDT::ColourUnknown), theColouredInteraction(PDT::ColouredUnknown), isStable(true), theVariableRatio(false), syncAnti(false), theDefMass(-1.0*GeV), theDefWidth(-1.0*GeV), theDefCut(-1.0*GeV), theDefCTau(-1.0*mm), theDefCharge(PDT::ChargeUnknown), theDefSpin(PDT::SpinUnknown), theDefColour(PDT::ColourUnknown), theDefColouredInteraction(PDT::ColouredUnknown) {} -ParticleData::~ParticleData() {} - PDPtr ParticleData::Create(PID newId, const string & newPDGName) { return new_ptr(ParticleData(newId, newPDGName)); } PDPair ParticleData:: Create(PID newId, const string & newPDGName, const string & newAntiPDGName) { PDPair pap; pap.first = new_ptr(ParticleData(newId, newPDGName)); pap.second = new_ptr(ParticleData(-newId, newAntiPDGName)); antiSetup(pap); return pap; } void ParticleData::readSetup(istream & is) { long id; is >> id >> thePDGName >> iunit(theDefMass, GeV) >> iunit(theDefWidth, GeV) >> iunit(theDefCut, GeV) >> iunit(theDefCTau, mm) >> ienum(theDefCharge) >> ienum(theDefColour) >> ienum(theDefSpin) >> ienum(isStable); theId = id; theMass = theDefMass; theWidth = theDefWidth; theWidthUpCut = theDefCut; theWidthLoCut = theDefCut; theCTau = theDefCTau; theCharge = theDefCharge; theColour = theDefColour; theColouredInteraction = PDT::NotColoured; if ( abs(long(theId)) < 9 || long(theId) == ParticleID::g ) theColouredInteraction = PDT::ColouredQCD; theSpin = theDefSpin; if ( PDGName() == "-" ) thePDGName = name(); return; } void ParticleData::antiSetup(const PDPair & pap) { pap.first->theAntiPartner = pap.second; pap.second->theAntiPartner = pap.first; pap.first->syncAnti = pap.second->syncAnti = true; } PDPtr ParticleData::pdclone() const { return new_ptr(*this); } IBPtr ParticleData::clone() const { return pdclone(); } IBPtr ParticleData::fullclone() const { PDPtr pd = pdclone(); Repository::Register(pd); pd->theDecaySelector.clear(); pd->theDecayModes.clear(); pd->isStable = true; PDPtr apd; if ( CC() ) { apd = CC()->pdclone(); Repository::Register(apd); apd->theDecaySelector.clear(); apd->theDecayModes.clear(); apd->isStable = true; pd->theAntiPartner = apd; apd->theAntiPartner = pd; pd->syncAnti = syncAnti; apd->syncAnti = CC()->syncAnti; } HoldFlag<> dosync(pd->syncAnti, true); for ( DecaySet::const_iterator it = theDecayModes.begin(); it != theDecayModes.end(); ++it ) pd->addDecayMode(*it); return pd; } Energy ParticleData::mass(Energy mi) { theMass = mi; if ( synchronized() && CC() ) CC()->theMass = theMass; return theMass; } Energy ParticleData::width(Energy wi) { theWidth = wi; if ( synchronized() && CC() ) CC()->theWidth = theWidth; return theWidth; } Energy ParticleData::widthUpCut(Energy wci) { theWidthUpCut = wci; if ( synchronized() && CC() ) CC()->theWidthUpCut = theWidthUpCut; return theWidthUpCut; } Energy ParticleData::widthLoCut(Energy wci) { theWidthLoCut = wci; if ( synchronized() && CC() ) CC()->theWidthLoCut = theWidthLoCut; return theWidthLoCut; } Length ParticleData::cTau(Length ti) { theCTau = ti; if ( synchronized() && CC() ) CC()->theCTau = theCTau; return theCTau; } PDT::Charge ParticleData::iCharge(PDT::Charge ci) { theCharge = ci; if ( synchronized() && CC() ) CC()->theCharge = PDT::Charge(-ci); return theCharge; } PDT::Spin ParticleData::iSpin(PDT::Spin si) { theSpin = si; if ( synchronized() && CC() ) CC()->theSpin = si; return si; } PDT::Colour ParticleData::iColour(PDT::Colour ci) { theColour = ci; if ( synchronized() && CC() ) CC()->theColour = PDT::Colour(-ci); return theColour; } void ParticleData::stable(bool s) { isStable = s; if ( synchronized() && CC() ) CC()->isStable = s; } void ParticleData::synchronized(bool h) { syncAnti = h; if ( CC() ) CC()->syncAnti = h; } void ParticleData::variableRatio(bool varRatio) { theVariableRatio=varRatio; } void ParticleData::addDecayMode(tDMPtr dm) { if ( member(theDecayModes, dm) ) return; cPDPtr parent = dm->parent(); if ( !parent ) parent = this; if ( parent != this ) { dm = dm->clone(this); } theDecayModes.insert(dm); theDecaySelector.insert(dm->brat(), dm); if ( CC() ) { if ( !synchronized() ) dm->CC()->switchOff(); CC()->theDecayModes.insert(dm->CC()); CC()->theDecaySelector.insert(dm->CC()->brat(), dm->CC()); } } void ParticleData::removeDecayMode(tDMPtr dm) { theDecayModes.erase(theDecayModes.find(dm)); if(theDecayModes.empty()) isStable = true; theDecaySelector.erase(dm); if ( !CC() ) return; CC()->theDecayModes.erase(dm->CC()); if(CC()->theDecayModes.empty()) CC()->isStable = true; CC()->theDecaySelector.erase(dm->CC()); } void ParticleData::synchronize() { if ( !CC() ) return; isStable = CC()->isStable; theMass = CC()->theMass; theHardProcessMass = CC()->theHardProcessMass; hardProcessMassSet = CC()->hardProcessMassSet; theWidth = CC()->theWidth; theHardProcessWidth = CC()->theHardProcessWidth; hardProcessWidthSet = CC()->hardProcessWidthSet; theWidthUpCut = CC()->theWidthUpCut; theWidthLoCut = CC()->theWidthLoCut; theCTau = CC()->theCTau; theCharge = PDT::Charge(-CC()->theCharge); theSpin = CC()->theSpin; theColour = PDT::antiColour(CC()->theColour); theColouredInteraction = CC()->theColouredInteraction; theMassGenerator = CC()->theMassGenerator; theWidthGenerator = CC()->theWidthGenerator; syncAnti = CC()->syncAnti; theDecaySelector.clear(); for ( DecaySet::iterator it = theDecayModes.begin(); it != theDecayModes.end(); ++it ) { (*it)->synchronize(); theDecaySelector.insert((*it)->brat(), *it); } } void ParticleData::doupdate() { Interfaced::doupdate(); bool redo = touched(); for_each(theDecayModes, UpdateChecker(redo)); UpdateChecker::check(theMassGenerator, redo); UpdateChecker::check(theWidthGenerator, redo); if ( !redo ) return; theDecaySelector.clear(); for ( DecaySet::const_iterator dit = theDecayModes.begin(); dit != theDecayModes.end(); ++dit ) { tDMPtr dm = *dit; dm->resetOverlap(); for ( DecaySet::const_iterator dit2 = theDecayModes.begin(); dit2 != theDecayModes.end(); ++dit2 ) if ( dit2 != dit ) dm->addOverlap(dm); if ( dm->brat() > 0.0 ) theDecaySelector.insert(dm->brat(), dm); } if ( theMassGenerator && !theMassGenerator->accept(*this) ) throw UpdateException(); if ( theWidthGenerator && !theWidthGenerator->accept(*this) ) throw UpdateException(); if ( theWidthGenerator ) theDecaySelector = theWidthGenerator->rate(*this); touch(); } tDMPtr ParticleData::selectMode(Particle & p) const { if ( &(p.data()) != this ) return tDMPtr(); try { if ( !theWidthGenerator || !theVariableRatio ) return theDecaySelector.select(UseRandom::current()); DecaySelector local; if ( theWidthGenerator ) local = theWidthGenerator->rate(p); else for ( DecaySet::const_iterator mit = theDecayModes.begin(); mit != theDecayModes.end(); ++mit ) local.insert((*mit)->brat(p), *mit); return local.select(UseRandom::current()); } catch (range_error & e) { return tDMPtr(); } } void ParticleData::rebind(const TranslationMap & trans) { if ( CC() ) theAntiPartner = trans.translate(theAntiPartner); DecaySet newModes; DecaySelector newSelector; for ( DecaySet::iterator it = theDecayModes.begin(); it != theDecayModes.end(); ++it ) { DMPtr dm; dm = trans.translate(*it); if ( !dm ) throw RebindException(); newModes.insert(dm); newSelector.insert(dm->brat(), dm); } theDecayModes.swap(newModes); theDecaySelector.swap(newSelector); } IVector ParticleData::getReferences() { IVector refs = Interfaced::getReferences(); if ( CC() ) refs.push_back(CC()); refs.insert(refs.end(), theDecayModes.begin(), theDecayModes.end()); return refs; } void ParticleData::massGenerator(tMassGenPtr mg) { if ( mg && !mg->accept(*this) ) return; if ( mg && synchronized() && CC() && !mg->accept(*CC()) ) return; theMassGenerator = mg; if ( synchronized() && CC() ) CC()->theMassGenerator = mg; } void ParticleData::widthGenerator(tWidthGeneratorPtr newGen) { if ( newGen && !newGen->accept(*this) ) return; if ( newGen && synchronized() && CC() && !newGen->accept(*CC()) ) return; theWidthGenerator = newGen; if ( synchronized() && CC() ) CC()->theWidthGenerator = newGen; } Energy ParticleData::generateMass() const { return massGenerator()? massGenerator()->mass(*this): mass(); } Energy ParticleData::generateWidth(Energy m) const { return widthGenerator()? widthGenerator()->width(*this, m): width(); } Length ParticleData::generateLifeTime(Energy m, Energy w) const { return widthGenerator() ? widthGenerator()->lifeTime(*this, m, w) : UseRandom::rndExp(cTau()); } PPtr ParticleData::produceParticle(const Lorentz5Momentum & pp) const { PPtr p = new_ptr(Particle(this)); p->set5Momentum(pp); return p; } PPtr ParticleData::produceParticle(const LorentzMomentum & pp) const { PPtr p(produceParticle(Lorentz5Momentum(pp))); return p; } PPtr ParticleData::produceParticle(const LorentzMomentum & pp, Energy m) const { PPtr p(produceParticle(Lorentz5Momentum(pp, m))); return p; } PPtr ParticleData::produceParticle(Energy m, const Momentum3 & pp) const { PPtr p(produceParticle(Lorentz5Momentum(m, pp))); return p; } PPtr ParticleData::produceParticle(const Momentum3 & pp) const { PPtr p(produceParticle(Lorentz5Momentum(generateMass(), pp))); return p; } PPtr ParticleData:: produceParticle(Energy plus, Energy minus, Energy px, Energy py) const { PPtr p(produceParticle(LorentzMomentum(px, py, 0.5*(plus-minus), 0.5*(plus+minus)))); return p; } void ParticleData::setMass(Energy mi) { mass(mi); } void ParticleData::setHardProcessMass(Energy mi) { theHardProcessMass = mi; hardProcessMassSet = true; ParticleData * apd = CC().operator->(); if ( synchronized() && apd ) { apd->theHardProcessMass = theHardProcessMass; apd->hardProcessMassSet = true; } } void ParticleData::setHardProcessWidth(Energy mi) { theHardProcessWidth = mi; hardProcessWidthSet = true; ParticleData * apd = CC().operator->(); if ( synchronized() && apd ) { apd->theHardProcessWidth = theHardProcessWidth; apd->hardProcessWidthSet = true; } } string ParticleData::doUnsetHardProcessMass(string) { hardProcessMassSet = false; theHardProcessMass = -1.*GeV; return ""; } string ParticleData::doAdjustNominalMass(string) { if ( hardProcessMassSet ) setMass(theHardProcessMass); return ""; } string ParticleData::doUnsetHardProcessWidth(string) { hardProcessWidthSet = false; theHardProcessWidth = -1.*GeV; return ""; } Energy ParticleData::defMass() const { return theDefMass; } void ParticleData::setWidth(Energy wi) { width(wi); } Energy ParticleData::getWidth() const { return width(); } Energy ParticleData::defWidth() const { return theDefWidth; } void ParticleData::setCut(Energy ci) { widthCut(ci); } Energy ParticleData::getCut() const { return (theWidthUpCut >= ZERO && theWidthLoCut >= ZERO)? max(theWidthUpCut, theWidthLoCut): min(theWidthUpCut, theWidthLoCut); } Energy ParticleData::defCut() const { return theDefCut; } void ParticleData::setUpCut(Energy ci) { widthUpCut(ci); } Energy ParticleData::getUpCut() const { return theWidthUpCut; } void ParticleData::setLoCut(Energy ci) { widthLoCut(ci); } Energy ParticleData::getLoCut() const { return theWidthLoCut; } void ParticleData::setCTau(Length ti) { cTau(ti); } Length ParticleData::getCTau() const { return cTau(); } Length ParticleData::defCTau() const { return theDefCTau; } void ParticleData::setStable(long is) { stable(is); } long ParticleData::getStable() const { return stable(); } void ParticleData::setSync(long is) { synchronized(is); } long ParticleData::getSync() const { return synchronized(); } void ParticleData::setVariableRatio(long is) { variableRatio(is); } long ParticleData::getVariableRatio() const { return variableRatio(); } string ParticleData::doSync(string) { synchronize(); return ""; } void ParticleData::setMassGenerator(MassGenPtr gi) { massGenerator(gi); } void ParticleData::setWidthGenerator(WidthGeneratorPtr wg) { widthGenerator(wg); } void ParticleData::setColour(long c) { theColour = PDT::Colour(c); } long ParticleData::getColour() const { return theColour; } long ParticleData::defColour() const { return theDefColour; } void ParticleData::setColouredInteraction(long c) { theColouredInteraction = PDT::ColouredInteraction(c); } long ParticleData::getColouredInteraction() const { return theColouredInteraction; } long ParticleData::defColouredInteraction() const { return theDefColour; } void ParticleData::setCharge(int c) { theCharge = PDT::Charge(c); } string ParticleData::ssetCharge(string arg) { istringstream is(arg); long i; if ( is >> i ) { theCharge = PDT::Charge(i); return "New charge is " + arg; } if ( arg == "unknown" ) theCharge = PDT::ChargeUnknown; else if ( arg == "charged" ) theCharge = PDT::Charged; else if ( arg == "positive" ) theCharge = PDT::Positive; else if ( arg == "negative" ) theCharge = PDT::Negative; else throw ParticleChargeCommand(*this, arg); return "New charge is " + arg; } int ParticleData::getCharge() const { return theCharge; } int ParticleData::defCharge() const { return theDefCharge; } void ParticleData::setSpin(int s) { theSpin = PDT::Spin(s); } int ParticleData::getSpin() const { return theSpin; } int ParticleData::defSpin() const { return theDefSpin; } ClassDescription ParticleData::initParticleData; struct ParticleOrdering { bool operator()(tcPDPtr p1, tcPDPtr p2) const { return abs(p1->id()) > abs(p2->id()) || ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) || ( p1->id() == p2->id() && p1->fullName() > p2->fullName() ); } }; struct ModeOrdering { bool operator()(const tcDMPtr & d1, const tcDMPtr & d2) const { ParticleOrdering ord; return ord(d1->parent(), d2->parent()) || ( !ord(d2->parent(), d1->parent()) && ( d1->tag() < d2->tag() || ( d1->tag() == d2->tag() && d1->fullName() < d2->fullName() ) ) ); } }; void ParticleData::persistentOutput(PersistentOStream & os) const { multiset modes(theDecayModes.begin(), theDecayModes.end()); os << long(theId) << thePDGName << ounit(theMass, GeV) << ounit(theWidth, GeV) << ounit(theHardProcessMass,GeV) << hardProcessMassSet << ounit(theHardProcessWidth,GeV) << hardProcessWidthSet << ounit(theWidthUpCut, GeV) << ounit(theWidthLoCut, GeV) << ounit(theCTau, mm) << oenum(theCharge) << oenum(theSpin) << oenum(theColour) << oenum(theColouredInteraction); os << theMassGenerator << isStable << modes << theDecaySelector << theWidthGenerator << theVariableRatio << theAntiPartner << syncAnti << ounit(theDefMass, GeV) << ounit(theDefWidth, GeV) << ounit(theDefCut, GeV) << ounit(theDefCTau, mm) << oenum(theDefColour) << oenum(theDefCharge) << oenum(theDefSpin) << oenum(theDefColouredInteraction); } void ParticleData::persistentInput(PersistentIStream & is, int) { long id; is >> id >> thePDGName >> iunit(theMass, GeV) >> iunit(theWidth, GeV) >> iunit(theHardProcessMass,GeV) >> hardProcessMassSet >> iunit(theHardProcessWidth,GeV) >> hardProcessWidthSet >> iunit(theWidthUpCut, GeV) >> iunit(theWidthLoCut, GeV) >> iunit(theCTau, mm) >> ienum(theCharge) >> ienum(theSpin) >> ienum(theColour) >> ienum(theColouredInteraction) >> theMassGenerator >> isStable >> theDecayModes >> theDecaySelector >> theWidthGenerator >> theVariableRatio >> theAntiPartner >> syncAnti >> iunit(theDefMass, GeV) >> iunit(theDefWidth, GeV) >> iunit(theDefCut, GeV) >> iunit(theDefCTau, mm) >> ienum(theDefColour) >> ienum(theDefCharge) >> ienum(theDefSpin) >> ienum(theDefColouredInteraction); theId = id; } void ParticleData::Init() { static ClassDocumentation documentation ("There is no documentation for the ThePEG::ParticleData class"); static Parameter interfaceMass ("NominalMass", "The nominal mass in GeV of the particle. The actual mass " "of a particle instance is generated depending on the " "nominal mass and the width and is generated by the " "Mass_generator object associated with the " "particle.", &ParticleData::theMass, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setMass, 0, 0, 0, &ParticleData::defMass); static Parameter interfaceHardProcessMass ("HardProcessMass", "The mass in GeV of the particle to be used in calculating hard process cross sections.", &ParticleData::theHardProcessMass, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setHardProcessMass, 0, 0, 0, 0); static Parameter interfaceDefMass ("DefaultMass", "The default nominal mass in GeV of the particle. The actual mass " "of a particle instance is generated depending on the " "nominal mass and the width and is generated by the " "Mass_generator object associated with the " "particle.", &ParticleData::theDefMass, GeV, ZERO, ZERO, Constants::MaxEnergy, false, true, Interface::lowerlim); interfaceDefMass.setHasDefault(false); static Parameter interfaceWidth ("Width", "The width of the particle in GeV.", 0, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setWidth, &ParticleData::getWidth, 0, 0, &ParticleData::defWidth); static Parameter interfaceHardProcessWidth ("HardProcessWidth", "The width in GeV of the particle to be used in calculating hard process cross sections.", &ParticleData::theHardProcessWidth, GeV, ZERO, ZERO, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setHardProcessWidth, 0, 0, 0, 0); static Parameter interfaceDefWidth ("DefaultWidth", "The default width of the particle in GeV.", &ParticleData::theDefWidth, GeV, ZERO, ZERO, Constants::MaxEnergy, false, true, Interface::lowerlim); interfaceDefWidth.setHasDefault(false); static Parameter interfaceWidthUpCut ("WidthUpCut", "The upper hard cutoff in GeV in generated mass, which is the maximum " "allowed upwards deviation from the nominal mass. A negative value " "corresponds to no limit.", 0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setUpCut, &ParticleData::getUpCut, 0, 0, &ParticleData::defCut); static Parameter interfaceWidthLoCut ("WidthLoCut", "The lower hard cutoff in GeV in generated mass, which is the maximum " "allowed downwards deviation from the nominal mass. A negative value " "corresponds to no limit.", 0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setLoCut, &ParticleData::getLoCut, 0, 0, &ParticleData::defCut); static Parameter interfaceWidthCut ("WidthCut", "The hard cutoff in GeV in generated mass, which is the maximum " "allowed deviation from the nominal mass. Sets both the upper and lower " "cut. (The displayed value is the maximium of the upper and lower cut.) " "A negative value corresponds to no limit.", 0, GeV, ZERO, -1.0*GeV, Constants::MaxEnergy, false, false, Interface::lowerlim, &ParticleData::setCut, &ParticleData::getCut, 0, 0, &ParticleData::defCut); interfaceWidthCut.setHasDefault(false); static Parameter interfaceDefWidthCut ("DefaultWidthCut", "The default hard cutoff in GeV in generated mass, which is the maximum " "allowed deviation from the nominal mass. For the actual cutoff, the " "upper and lower cut can be set separately.", &ParticleData::theDefCut, GeV, ZERO, ZERO, Constants::MaxEnergy, false, true, Interface::lowerlim); interfaceDefWidthCut.setHasDefault(false); static Parameter interfaceCTau ("LifeTime", "c times the average lifetime of the particle measuerd in mm." "The actual lifetime of a particle instance is generated " "from this number by the Mass_generator " "object associated with the particle.", 0, mm, ZERO, ZERO, Constants::MaxLength, false, false, Interface::lowerlim, &ParticleData::setCTau, &ParticleData::getCTau, 0, 0, &ParticleData::defCTau); interfaceCTau.setHasDefault(false); static Parameter interfaceDefCTau ("DefaultLifeTime", "c times the default average lifetime of the particle measuerd in mm." "The actual lifetime of a particle instance is generated " "from this number by the Mass_generator " "object associated with the particle.", &ParticleData::theDefCTau, mm, ZERO, ZERO, Constants::MaxLength, false, true, Interface::lowerlim); interfaceDefCTau.setHasDefault(false); static Switch interfaceColour ("Colour", "The colour quantum number of this particle type.", 0, -1, false, false, &ParticleData::setColour, &ParticleData::getColour, &ParticleData::defColour); static SwitchOption interfaceColourUndefined (interfaceColour, "Undefined", "The coulur is undefined.", -1); static SwitchOption interfaceColourNeutral (interfaceColour, "Neutral", "This particle is colour neutral.", 0); static SwitchOption interfaceColour3 (interfaceColour, "Triplet", "This particle is a colour triplet.", 3); static SwitchOption interfaceColour3bar (interfaceColour, "AntiTriplet", "This particle is a colour anti-triplet.", -3); static SwitchOption interfaceColour6 (interfaceColour, "Sextet", "This particle is a colour sextet.", 6); static SwitchOption interfaceColour6bar (interfaceColour, "AntiSextet", "This particle is a colour anti-sextet.", -6); static SwitchOption interfaceColour8 (interfaceColour, "Octet", "This particle is a colour octet.", 8); static Switch interfaceDefColour ("DefaultColour", "The default colour quantum number of this particle type.", &ParticleData::theDefColour, PDT::Colour(-1), false, true); static SwitchOption interfaceDefColourUndefined (interfaceDefColour, "Undefined", "The coulur is undefined.", -1); static SwitchOption interfaceDefColourNeutral (interfaceDefColour, "Neutral", "This particle is colour neutral.", 0); static SwitchOption interfaceDefColour3 (interfaceDefColour, "Triplet", "This particle is a colour triplet.", 3); static SwitchOption interfaceDefColour3bar (interfaceDefColour, "AntiTriplet", "This particle is a colour anti-triplet.", -3); static SwitchOption interfaceDefColour6 (interfaceDefColour, "Sextet", "This particle is a colour sextet.", 6); static SwitchOption interfaceDefColour6bar (interfaceDefColour, "AntiSextet", "This particle is a colour anti-sextet.", -6); static SwitchOption interfaceDefColour8 (interfaceDefColour, "Octet", "This particle is a colour octet.", 8); interfaceDefColour.setHasDefault(false); static Switch interfaceColouredInteraction ("ColouredInteraction", "The coloured interaction of this particle type.", 0, -1, false, false, &ParticleData::setColouredInteraction, &ParticleData::getColouredInteraction, &ParticleData::defColouredInteraction); static SwitchOption interfaceColouredInteractionUndefined (interfaceColouredInteraction, "Undefined", "The coloured interaction is undefined.", -2); static SwitchOption interfaceColouredInteractionNotColoured (interfaceColouredInteraction, "NotColoured", "There are no coloured interactions.", -1); static SwitchOption interfaceColouredInteractionQCD (interfaceColouredInteraction, "QCD", "This particle is a QCD particle.", 0); static Switch interfaceDefColouredInteraction ("DefaultColouredInteraction", "The default coloured interaction of this particle type.", &ParticleData::theDefColouredInteraction, PDT::ColouredInteraction(-1), false, true); static SwitchOption interfaceDefColouredInteractionUndefined (interfaceDefColouredInteraction, "Undefined", "The coloured interaction is undefined.", -2); static SwitchOption interfaceDefColouredInteractionNotColoured (interfaceDefColouredInteraction, "NotColoured", "There are no coloured interactions.", -1); static SwitchOption interfaceDefColouredInteractionQCD (interfaceDefColouredInteraction, "QCD", "This particle is a QCD particle.", 0); static Parameter interfaceCharge ("Charge", "The charge of this particle in units of e/3. " "See also the command interface SetCharge.", 0, 0, -24, 24, false, false, true, &ParticleData::setCharge, &ParticleData::getCharge, 0, 0, &ParticleData::defCharge); static Parameter interfaceDefCharge ("DefaultCharge", "The default charge of this particle in units of e/3. " "See also the command interface SetCharge.", &ParticleData::theDefCharge, PDT::Charge(0), PDT::Charge(-24), PDT::Charge(24), false, true, true); interfaceDefCharge.setHasDefault(false); static Command interfaceSetCharge ("SetCharge", "Set the charge of this particle. The argument should be given as an " "interger giving three times the unit charge, or 'unknown', " "'charged', 'positive' or 'negative'", &ParticleData::ssetCharge); static Parameter interfaceSpin ("Spin", "The spin quantim number of this particle on the form 2j+1.", 0, 0, 0, 9, false, false, true, &ParticleData::setSpin, &ParticleData::getSpin, 0, 0, &ParticleData::defSpin); static Parameter interfaceDefSpin ("DefaultSpin", "The default spin quantim number of this particle on the form 2j+1.", &ParticleData::theDefSpin, PDT::Spin(0), PDT::Spin(0), PDT::Spin(9), false, true, true); interfaceDefSpin.setHasDefault(false); static Switch interfaceStable ("Stable", "Indicates if the particle is stable or not.", 0, 0, false, false, &ParticleData::setStable, &ParticleData::getStable, 0); static SwitchOption interfaceStableYes (interfaceStable, "Stable", "This particle is stable", 1); static SwitchOption interfaceStableNo (interfaceStable, "Unstable", "This particle is not stable", 0); interfaceStable.setHasDefault(false); static Switch interfaceVariableRatio ("VariableRatio", "Indicates if the branching ratios of the particle are allowed" " to vary for given Particle instances depending on the mass of the instance.", 0, 0, false, false, &ParticleData::setVariableRatio, &ParticleData::getVariableRatio, 0); static SwitchOption interfaceVariableRatioYes (interfaceVariableRatio, "Yes", "The branching ratio varies.", 1); static SwitchOption interfaceVariableRatioNo (interfaceVariableRatio, "No", "The branching ratio does not vary.", 0); static Switch interfaceSync ("Synchronized", "Indicates if the changes to this particle is propagated to " "its anti-partner or not. Note that setting this switch does not " "actually synchronize the properties with the anti-partner, " "it only assures that following changes are propagated. " "To sync the particle with its anti-particle, use the " "Synchronize command.", 0, 1, false, false, &ParticleData::setSync, &ParticleData::getSync, 0); static SwitchOption interfaceSyncYes (interfaceSync, "Synchronized", "Changes to this particle will propagate to its " "anti-partner", 1); static SwitchOption interfaceSyncNo (interfaceSync, "Not_synchronized", "Changes to this particle will propagate to its " "anti-partner", 0); interfaceSync.setHasDefault(false); static Command interfaceSynchronize ("Synchronize", "Synchronizes this particle so that all its properties " "correspond to those of its anti-partner", &ParticleData::doSync, false); static Reference interfaceMassGenerator ("Mass_generator", "An object derived from the ThePEG::MassGenerator" "class, which is able to generate a mass for a given " "particle instance", &ParticleData::theMassGenerator, false, false, true, true, &ParticleData::setMassGenerator, 0, 0); static Reference interfaceWidthGenerator ("Width_generator", "An object derived from the ThePEG::WidthGenerator class, " "which is able to calculate the full and partial widths for" "this particle type and for a given instance of this " "particle type.", &ParticleData::theWidthGenerator, false, false, true, true, &ParticleData::setWidthGenerator, 0, 0); static RefVector interfaceDecayModes ("DecayModes", "The list of decay modes defined for this particle type.", 0, -1, false, false, false, false, 0, &ParticleData::insDecayModes, &ParticleData::delDecayModes, &ParticleData::getDecayModes); static Command interfaceSelectDecayModes ("SelectDecayModes", "Only the decay modes which are given as (white-space separated) " "decay tags will be switched on, all others will be switched off. " "If no argument or 'none' is given, all decay modes are switched off. " "If the argument is 'all', all decay modes are switched on.", &ParticleData::doSelectDecayModes, false); static Command interfacePrintDecayModes ("PrintDecayModes", "Print all decay modes of this particle.", &ParticleData::doPrintDecayModes, true); static Command interfaceUnsetHardProcessMass ("UnsetHardProcessMass", "Unset a previously set hard process mass.", &ParticleData::doUnsetHardProcessMass, false); static Command interfaceAdjustNominalMass ("AdjustNominalMass", "Unset a previously set hard process mass.", &ParticleData::doAdjustNominalMass, false); static Command interfaceUnsetHardProcessWidth ("UnsetHardProcessWidth", "Unset a previously set hard process width.", &ParticleData::doUnsetHardProcessWidth, false); interfaceStable.rank(14); interfaceDecayModes.rank(13); interfaceMass.rank(12); interfaceWidth.rank(11); interfaceWidthCut.rank(10); interfaceCTau.rank(9); interfaceMassGenerator.rank(8); interfaceWidthGenerator.rank(7); interfaceWidthUpCut.rank(-0.1); interfaceWidthLoCut.rank(-0.1); } string ParticleData::doPrintDecayModes(string) { multimap > sorted; for ( DecaySet::iterator it = decayModes().begin(); it != decayModes().end(); ++it ) sorted.insert(make_pair((**it).brat(), *it)); ostringstream os; for ( multimap >::iterator it = sorted.begin(); it != sorted.end(); ++it ) os << it->second->tag() << (it->second->on()? " ": " (off) ") << it->first << endl; return os.str(); } string ParticleData::doSelectDecayModes(string args) { DecaySet on; while ( !args.empty() ) { string arg = StringUtils::car(args); if ( arg == "all" ) { on = decayModes(); break; } if ( arg == "none" ) { on.clear(); break; } string name = arg; args = StringUtils::cdr(args); if ( arg.empty() ) continue; if ( arg[0] != '/' ) arg = fullName() + "/" + arg; DMPtr dm = Repository::GetPtr(arg); if ( !dm ) return "Error: No decay mode with tag '" + name + "' exists."; on.insert(dm); } for ( DecaySet::iterator it = decayModes().begin(); it != decayModes().end(); ++it ) { if ( on.find(*it) != on.end() ) { (**it).switchOn(); on.erase(*it); } else { (**it).switchOff(); } } if ( !on.empty() ) return "Error: decay mode '" + (**on.begin()).tag() + "'was not available."; return ""; } void ParticleData::insDecayModes(DMPtr dm, int) { addDecayMode(dm); } void ParticleData::delDecayModes(int i) { vector mv = getDecayModes(); if ( i >= 0 && static_cast(i) < mv.size() ) removeDecayMode(mv[i]); } vector ParticleData::getDecayModes() const { return vector(theDecayModes.begin(), theDecayModes.end()); } ParticleChargeCommand:: ParticleChargeCommand(const ParticleData & pd, string arg) { theMessage << "Cannot set the charge of particle '" << pd.name() << "' to '" << arg << "'."; severity(warning); } void ParticleData::doinit() { Interfaced::doinit(); if( theMassGenerator ) theMassGenerator->init(); if( theWidthGenerator ) theWidthGenerator->init(); } void ParticleData::doinitrun() { Interfaced::doinitrun(); if( theMassGenerator ) theMassGenerator->initrun(); if( theWidthGenerator ) theWidthGenerator->initrun(); } } diff --git a/PDT/ParticleData.h b/PDT/ParticleData.h --- a/PDT/ParticleData.h +++ b/PDT/ParticleData.h @@ -1,1004 +1,996 @@ // -*- C++ -*- // // ParticleData.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_ParticleData_H #define ThePEG_ParticleData_H // This is the declaration of the ParticleData class. #include "ThePEG/Config/ThePEG.h" #include "ThePEG/PDT/PDT.h" #include "ThePEG/PDT/PID.h" #include "ThePEG/Vectors/LorentzVector.h" #include "ThePEG/Vectors/ThreeVector.h" #include "ThePEG/Interface/Interfaced.h" #include "ThePEG/Utilities/Selector.h" #include "ThePEG/PDT/WidthGenerator.h" #include "ThePEG/PDT/MassGenerator.h" #include "ThePEG/PDT/DecayMode.fh" #include "ThePEG/Utilities/ClassTraits.h" #include "ThePEG/Utilities/ClassDescription.h" namespace ThePEG { /** * ParticleData inherits from InterfacedBase and represents the * properties of a particle type. It is also able to produce instances * of this Particle type and, among other things, to decay them. * * @see \ref ParticleDataInterfaces "The interfaces" * defined for ParticleData. */ class ParticleData: public Interfaced { public: /** The Repository is a friend. */ friend class Repository; /** The EventGenerator is a friend. */ friend class EventGenerator; /** DecayMode is a friend. */ friend class DecayMode; /** A selector of DecayMode objects. */ typedef Selector DecaySelector; public: - /** @name Standard constructors and destructors. */ - //@{ /** * Default constructor. */ ParticleData(); - /** - * Destructor. - */ - virtual ~ParticleData(); - //@} - /** @name The Create methods are special interfaces for ParticleData classes. */ //@{ /** * Create a Particle which is its own anti-particle. */ static PDPtr Create(PID newId, const string & newPDGName); /** * Create a particle - anti particle pair. */ static PDPair Create(PID newId, const string & newPDGName, const string & newAntiPDGName); //@} public: /** @name Acces to number and name. */ //@{ /** * Return the PDG id number. */ long id() const { return theId; } /** * Return the generic PDG name. Note that this is not really * standardised. */ const string & PDGName() const { return thePDGName; } /** * Return the generic PDG name. Note that this is not really * standardised. */ const string & genericName() const { return thePDGName; } //@} /** @name Functions used for producing Particle instances. */ //@{ /** * Produce a particle specifying momentum. */ PPtr produceParticle(const Lorentz5Momentum &) const; /** * Produce a particle specifying momentum. */ PPtr produceParticle(const LorentzMomentum &) const; /** * Produce a particle specifying 4-momentum and a mass. */ PPtr produceParticle(const LorentzMomentum &, Energy m) const; /** * Produce a particle specifying 3-momentum. */ PPtr produceParticle(const Momentum3 & pp = Momentum3()) const; /** * Produce a particle specifying mass and 3-momentum. */ PPtr produceParticle(Energy m, const Momentum3 & pp = Momentum3()) const; /** * Produce a particle specifying light-cone momentum components and * transverse momentum components. */ PPtr produceParticle(Energy plus, Energy minus, Energy px, Energy py) const; /** * Generate a mass for an instance of this particle type. */ Energy generateMass() const; /** * Generate a width for an instance of this particle type. Given a * \a mass of an instance of this particle type, calculate its width. */ Energy generateWidth(Energy mass) const; /** * Generate a mass for an instance of this particle type. Given a \a * mass and a \a width of an instance of this particle type, * generate a life time. */ Length generateLifeTime(Energy mass, Energy width) const; // Given a mass and a width of an instance of this particle type, // generate a life time. //@} /** @name Access the decay modes. */ //@{ /** * Return the nominal decay selector for this particle. Ie. the * decay modes weighted by their nominal branching ratios. */ const DecaySelector & decaySelector() const { return theDecaySelector; } /** * Selects a decay mode randomly according to the branching * ratios. The nominal branching ratios may be changed for the * particular Particle instance \a p, iether by an assigned * WidthGenerator or the respective Decayers. */ tDMPtr selectMode(Particle & p) const; /** * Access all the decay modes, including those which are * switched off, or have zero branching ratio */ const DecaySet & decayModes() const { return theDecayModes; } //@} /** * Set the nominal mass */ Energy mass(Energy); /** * Return the nominal mass. */ Energy mass() const { return theMass; } /** * Return the mass to be used when evaluating hard process cross sections. */ Energy hardProcessMass() const { return hardProcessMassSet ? theHardProcessMass : mass(); } /** * Return the maximum possible mass of this particle type. */ Energy massMax() const { return mass() + widthUpCut(); } /** * Return the minimum possible mass of this particle type. */ Energy massMin() const { return max(mass() - widthLoCut(), ZERO); } /** * Return the constituent mass of this particle if relevant. This * version simply returns the nominal mass. */ virtual Energy constituentMass() const { return mass(); } /** * Set the width. */ Energy width(Energy); /** * Get the width. If no width is specified, it is calculated from * the lifetime. */ Energy width() const { return theWidth >= ZERO ? theWidth : ( theCTau > Length() ? hbarc/theCTau : ( theCTau == Length() ? Constants::MaxEnergy : ZERO ) ); } /** * Set the width cut. Both upper and lower cut is set. */ Energy widthCut(Energy wci) { widthUpCut(wci); return widthLoCut(wci); } /** * Get the width cut. */ Energy widthCut() const { return max(widthUpCut(), widthLoCut()); } /** * Set the upper width cut. */ Energy widthUpCut(Energy); /** * Get the upper width cut. */ Energy widthUpCut() const { return theWidthUpCut >= ZERO? theWidthUpCut: Constants::MaxEnergy; } /** * Set the lower width cut. */ Energy widthLoCut(Energy); /** * Get the lower width cut. */ Energy widthLoCut() const { return theWidthLoCut >= ZERO? theWidthLoCut: Constants::MaxEnergy; } /** * Set the life time cTau. */ Length cTau(Length); /** * Get the life time cTau cTau. If no life time is specified, it is * calculated from the width. If the width is also not specified, * the lifetime is assumed to be zero for ustable particles and * infinite for stable ones. */ Length cTau() const { return theCTau > Length() ? theCTau : ( theWidth > ZERO ? hbarc/theWidth : ( stable() ? Constants::MaxLength : Length() ) ); } /** * Return the width to be used when evaluating hard process cross sections. */ Energy hardProcessWidth() const { return hardProcessWidthSet ? theHardProcessWidth : width(); } /** * Set the charge. The charge should be given * in units of e/3 using the PDT::Charge enum. */ PDT::Charge iCharge(PDT::Charge); /** * Get the charge. The charge is returned in standard units and in * iCharge the charge is returned in units of e/3. */ Charge charge() const { return eplus*double(theCharge)/3.0; } /** * Get the charge. The charge is returned in units of e/3. */ PDT::Charge iCharge() const { return theCharge; } /** * Return true if charged. */ bool charged() const { return PDT::charged(theCharge); } /** * Return true if positively charged. */ bool positive() const { return PDT::positive(theCharge); } /** * Return true if negatively charged. */ bool negative() const { return PDT::negative(theCharge); } /** * Set the spin. The spin should be given as 2J+1 (in units of * hbar/2) using the PDT::Spin enum. */ PDT::Spin iSpin(PDT::Spin); /** * Get the spin.The spin is returned in standard units. */ AngularMomentum spin() const { return hbar_Planck*double(theSpin-1)*0.5; } /** * Get the spin. The spin is returned as 2J+1 in units of hbar/2. */ PDT::Spin iSpin() const { return theSpin; } /** * Set the colour of the particle in units of PDT::Colour. */ PDT::Colour iColour(PDT::Colour); /** * Get the colour of the particle in units of PDT::Colour. */ PDT::Colour iColour() const { return theColour; } /** * Return true if coloured. */ bool coloured() const { return PDT::coloured(iColour()); } /** * Return true if (\a anti) coloured or colour-octet. */ bool hasColour(bool anti = false) const { return anti? hasAntiColour(): ( iColour() == PDT::Colour3 || iColour() == PDT::Colour6 || iColour() == PDT::Colour8 ); } /** * Return true if anti coloured or colour-octet. */ bool hasAntiColour() const { return iColour() == PDT::Colour3bar || iColour() == PDT::Colour6bar || iColour() == PDT::Colour8; } /** * Return what kind of colour charge this particle carries */ PDT::ColouredInteraction colouredInteraction() const { return theColouredInteraction; } /** * Specify if particle is to be considered stable according to \a * stab. */ void stable(bool stab); /** * Return true if particle is to be considered stable. If the decay * table is empty the function always returns true, even if the * member variable is false. */ bool stable() const { return isStable; } /** * Get the pointer to the corresponding anti partner. */ tPDPtr CC() const { return theAntiPartner; } /** * Specify if the anti partner chould be changed automatically when * this object is changed according to \a sync. */ void synchronized(bool sync); /** * Return true if the anti partner chould be changed automatically * when this object is changed. */ bool synchronized() const { return syncAnti; } /** * If there is an anti-partner, update this object to have correct * anti-properties. */ void synchronize(); /** * Set the mass generator object. */ void massGenerator(tMassGenPtr); /** * Get the mass generator object. */ tMassGenPtr massGenerator() const { return theMassGenerator; } /** * Set the width generator object. */ void widthGenerator(tWidthGeneratorPtr); /** * Get the width generator object. */ tWidthGeneratorPtr widthGenerator() const { return theWidthGenerator; } /** * Specify if the branching ratio of the Particle instances should vary with their * masses. */ void variableRatio(bool varRatio); /** * Return true if the branching ratio should vary with the mass of the Particle * instance. */ bool variableRatio() const { return theVariableRatio; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} /** * Special clone function used by the Repository. Also makes copies * the decay modes and the anti-partner if it exists and if * synchronized() is true. */ virtual PDPtr pdclone() const; /** * Protected constructor only to be used by subclasses or by the * Create method. */ ParticleData(PID newId, const string & newPDGName); /** * Read setup info from a standard stream. The following information * must be supplied in a white-space separated list: PDG number, * generic name, default mass (GeV), default width (GeV), width cut * (GeV), the lifetime ctau (mm), the charge, the colour, the spin, * stable (true) or not (false). Note that if a minus sign is given * instead of a generic name, the name of the object will be used * instead. */ virtual void readSetup(istream & is); /** * Used by subclasses or by the Create method to setup * anti-relationship. */ static void antiSetup(const PDPair & pap); protected: /** @name Standard Interfaced functions. */ //@{ /** * Check sanity of the object during the setup phase. */ virtual void doupdate(); /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Rebind pointer to other Interfaced objects. Called in the setup phase * after all objects used in an EventGenerator has been cloned so that * the pointers will refer to the cloned objects afterwards. * @param trans a TranslationMap relating the original objects to * their respective clones. * @throws RebindException if no cloned object was found for a given * pointer. */ virtual void rebind(const TranslationMap & trans) ; /** * Return a vector of all pointers to Interfaced objects used in this * object. * @return a vector of pointers. */ virtual IVector getReferences(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); //@} protected: /** * Add a decay mode for this particle. */ void addDecayMode(tDMPtr); /** * Remove a decay mode for this particle. */ void removeDecayMode(tDMPtr); private: /** * Id number according to the STDHEP/PDG standard. */ PID theId; /** * Name and Id number according to the STDHEP/PDG standard. */ string thePDGName; /** * Nominal mass. */ Energy theMass; /** * Width. */ Energy theWidth; /** * The mass to be used when evaluating hard process cross sections. */ Energy theHardProcessMass; /** * True, if a hard process mass has been set. */ bool hardProcessMassSet; /** * The width to be used when evaluating hard process cross sections. */ Energy theHardProcessWidth; /** * True, if a hard process width has been set. */ bool hardProcessWidthSet; /** * Upper width cut. */ Energy theWidthUpCut; /** * Lower width cut. */ Energy theWidthLoCut; /** * Lifetime. */ Length theCTau; /** * Three times the charge. */ PDT::Charge theCharge; /** * 2 times the spin plus one. */ PDT::Spin theSpin; /** * The colour for this particle. */ PDT::Colour theColour; /** * The coloured interaction of this particle */ PDT::ColouredInteraction theColouredInteraction; /** * The nonabelian interaction of this particle */ /** * A pointer to an object capable to generate a mass for a particle * of this type. */ MassGenPtr theMassGenerator; /** * True if the particle is considered stable. */ bool isStable; /** * A selector of decay modes weighted by the nominal branching * ratios. */ DecaySelector theDecaySelector; /** * The set of all decay modes. */ DecaySet theDecayModes; /** * A pointer to an object capable to generate the branching * fractions for different decay modes for this particle type. The * object will be asked to generate branching fractions every time * the ParticleData object it updated and will modify the branching * fractions for every particle instance if variableRatio is true. */ WidthGeneratorPtr theWidthGenerator; /** * Determine whether the branching fractions are allowed to change * on a particle-by-particle basis. */ bool theVariableRatio; /** * Pointer to the object corresponding to the antiparticle. Set to * null if it is its own antiparticle. */ tPDPtr theAntiPartner; /** * If syncAnti is true all changes to this object will be transfered * to the antiParticle. */ bool syncAnti; /** * Helper variable to keep track of the default mass. */ Energy theDefMass; /** * Helper variable to keep track of the default width. */ Energy theDefWidth; /** * Helper variable to keep track of the default width cut. */ Energy theDefCut; /** * Helper variable to keep track of the default lifetime. */ Length theDefCTau; /** * Helper variable to keep track of the default charge. */ PDT::Charge theDefCharge; /** * Helper variable to keep track of the default spin. */ PDT::Spin theDefSpin; /** * Helper variable to keep track of the default colour. */ PDT::Colour theDefColour; /** * Helper variable to keep track of the default coloured interaction. */ PDT::ColouredInteraction theDefColouredInteraction; /** * Utility function for the interface. */ void setMass(Energy); /** * Utility function for the interface. */ void setHardProcessMass(Energy); /** * Reset the hard process mass */ string doUnsetHardProcessMass(string); /** * Adjust the nominal mass to the hard process mass if a reshuffling * is not desirable. */ string doAdjustNominalMass(string); /** * Utility function for the interface. */ Energy defMass() const; /** * Utility function for the interface. */ void setWidth(Energy); /** * Utility function for the interface. */ void setHardProcessWidth(Energy); /** * Reset the hard process mass */ string doUnsetHardProcessWidth(string); /** * Utility function for the interface. */ Energy getWidth() const; /** * Utility function for the interface. */ Energy defWidth() const; /** * Utility function for the interface. */ void setCut(Energy); /** * Utility function for the interface. */ Energy getCut() const; /** * Utility function for the interface. */ Energy defCut() const; /** * Utility function for the interface. */ void setUpCut(Energy); /** * Utility function for the interface. */ Energy getUpCut() const; /** * Utility function for the interface. */ void setLoCut(Energy); /** * Utility function for the interface. */ Energy getLoCut() const; /** * Utility function for the interface. */ void setCTau(Length); /** * Utility function for the interface. */ Length getCTau() const; /** * Utility function for the interface. */ Length defCTau() const; /** * Utility function for the interface. */ void setStable(long); /** * Utility function for the interface. */ long getStable() const; /** * Utility function for the interface. */ void setSync(long); /** * Utility function for the interface. */ long getSync() const; /** * Utility function for the interface. */ void setVariableRatio(long); /** * Utility function for the interface. */ long getVariableRatio() const; /** * Utility function for the interface. */ string doSync(string); /** * Utility function for the interface. */ void setMassGenerator(MassGenPtr); /** * Utility function for the interface. */ void setWidthGenerator(WidthGeneratorPtr); /** * Utility function for the interface. */ void setCharge(int); /** * Utility function for the interface. */ string ssetCharge(string); /** * Utility function for the interface. */ int getCharge() const; /** * Utility function for the interface. */ int defCharge() const; /** * Utility function for the interface. */ void setSpin(int); /** * Utility function for the interface. */ int getSpin() const; /** * Utility function for the interface. */ int defSpin() const; /** * Utility function for the interface. */ void setColour(long); /** * Utility function for the interface. */ long getColour() const; /** * Utility function for the interface. */ long defColour() const; /** * Utility function for the interface. */ void setColouredInteraction(long); /** * Utility function for the interface. */ long getColouredInteraction() const; /** * Utility function for the interface. */ long defColouredInteraction() const; /** * Utility function for the interface. */ void insDecayModes(DMPtr dm, int); /** * Utility function for the interface. */ void delDecayModes(int i); /** * Utility function for the interface. */ vector getDecayModes() const; /** * Utility function for the interface. */ string doSelectDecayModes(string); /** * Utility function for the interface. */ string doPrintDecayModes(string); /** * Describe a concrete class with persistent data. */ static ClassDescription initParticleData; }; /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of ParticleData. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of ParticleData. */ typedef Interfaced NthBase; }; /** This template specialization informs ThePEG about the name of the * ParticleData class. */ template <> struct ClassTraits: public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::ParticleData"; } }; /** @endcond */ } #endif /* ThePEG_ParticleData_H */ diff --git a/PDT/QuarksToHadronsDecayer.cc b/PDT/QuarksToHadronsDecayer.cc --- a/PDT/QuarksToHadronsDecayer.cc +++ b/PDT/QuarksToHadronsDecayer.cc @@ -1,236 +1,234 @@ // -*- C++ -*- // // QuarksToHadronsDecayer.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the QuarksToHadronsDecayer class. // #include "QuarksToHadronsDecayer.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; -QuarksToHadronsDecayer::~QuarksToHadronsDecayer() {} - IBPtr QuarksToHadronsDecayer::clone() const { return new_ptr(*this); } IBPtr QuarksToHadronsDecayer::fullclone() const { return new_ptr(*this); } bool QuarksToHadronsDecayer::accept(const DecayMode & dm) const { int col = 0; int acol = 0; if ( !dm.productMatchers().empty() ) { for ( MatcherMSet::const_iterator it = dm.productMatchers().begin(); it != dm.productMatchers().end(); ++it ) { const auto & tmp=**it; if ( typeid(tmp) == typeid(MatchLightQuark) ) ++col; else if ( typeid(tmp) == typeid(MatchLightAntiQuark) ) ++acol; else return false; } if ( col != 1 || col != acol ) return false; } if ( dm.orderedProducts().size() + col + acol < 2 || !dm.cascadeProducts().empty() || dm.wildProductMatcher() ) return false; for ( int i = 0, N = dm.orderedProducts().size(); i < N; ++i ) { if ( DiquarkMatcher::Check(*dm.orderedProducts()[i]) ) { if ( i + 1 != N ) return false; if ( dm.orderedProducts()[i]->id() < 0 ) ++col; else ++acol; } if ( QuarkMatcher::Check(*dm.orderedProducts()[i]) ) { if ( dm.orderedProducts()[i]->id() > 0 ) ++col; else ++acol; } } if ( acol != col || col < 1 || col > 2 ) return false; return true; } PVector QuarksToHadronsDecayer::decay(const DecayMode & dm, const Particle & parent) const { PVector children; tcPDVector quarks; if ( !dm.productMatchers().empty() ) { tcPDPtr pd = getParticleData(flavourGenerator()->selectQuark()); quarks.push_back(pd); quarks.push_back(pd->CC()); } Energy summq = ZERO; Energy summp = ZERO; tPDVector prods = dm.orderedProducts(); for ( int i = 0, N = prods.size(); i < N; ++i ) if ( QuarkMatcher::Check(*prods[i]) || DiquarkMatcher::Check(*prods[i])) { quarks.push_back(prods[i]); summq += quarks.back()->mass(); } else { children.push_back(prods[i]->produceParticle()); summp += children.back()->mass(); } Energy summh = ZERO; PVector hadrons; if ( !quarks.empty() ) do { hadrons = getHadrons(getN(parent.mass(), summq, quarks.size()), quarks); summh = ZERO; for ( int i = 0, N = hadrons.size(); i < N; ++i ) summh += hadrons[i]->mass(); } while ( hadrons.empty() || summp + summh >= parent.mass() ); children.insert(children.end(), hadrons.begin(), hadrons.end()); distribute(parent, children); finalBoost(parent, children); setScales(parent, children); return children; } int QuarksToHadronsDecayer::getN(Energy m0, Energy summq, int Nq) const { int Nh = fixedN(); if ( Nh >= 2 ) return Nh; double c = c1()*log((m0 - summq)/c2()) + c3(); if ( c < 0.0 ) return minN(); while ( true ) { using namespace Constants; Nh = int(0.5 + double(Nq)/4.0 + c + sqrt(-2.0*c*log(max(1.0e-10, rnd())))*sin(2.0*pi*rnd())); if ( Nh >= minN() ) return Nh; } } PVector QuarksToHadronsDecayer:: getHadrons(int Nh, tcPDVector quarks) const { PVector hadrons; Nh -= quarks.size()/2; while ( Nh-- > 0 ) { int i = irnd(quarks.size() - 1); tcPDPair hq = flavourGenerator()->alwaysGenerateHadron(quarks[i]); hadrons.push_back(hq.first->produceParticle()); quarks[i] = hq.second; } if ( DiquarkMatcher::Check(*quarks[0]) && DiquarkMatcher::Check(*quarks[1]) ) return PVector(); tcPDPtr h = flavourGenerator()->alwaysGetHadron(quarks[0], quarks[1]); hadrons.push_back(h->produceParticle()); if ( quarks.size() <= 2 ) return hadrons; if ( DiquarkMatcher::Check(*quarks[2]) && DiquarkMatcher::Check(*quarks[3]) ) return PVector(); h = flavourGenerator()->alwaysGetHadron(quarks[2], quarks[3]); hadrons.push_back(h->produceParticle()); return hadrons; } void QuarksToHadronsDecayer:: distribute(const Particle & parent, PVector & children) const { do { try { SimplePhaseSpace::CMSn(children, parent.mass()); } catch ( ImpossibleKinematics & e) { children.clear(); return; } } while ( reweight(parent, children) < rnd() ); } double QuarksToHadronsDecayer:: reweight(const Particle &, const PVector &) const { return 1.0; } void QuarksToHadronsDecayer::persistentOutput(PersistentOStream & os) const { os << theFixedN << theMinN << theC1 << ounit(theC2,GeV) << theC3 << theFlavourGenerator; } void QuarksToHadronsDecayer::persistentInput(PersistentIStream & is, int) { is >> theFixedN >> theMinN >> theC1 >> iunit(theC2,GeV) >> theC3 >> theFlavourGenerator; } ClassDescription QuarksToHadronsDecayer::initQuarksToHadronsDecayer; // Definition of the static class description member. void QuarksToHadronsDecayer::Init() { static ClassDocumentation documentation ("This class decays particles to nq (2 or 4) quarks which then are " "decayes to hadrons according to phase space. The number of final " "hadrons can either be given by a fixed number or as a Gaussian " "multiplicity distribution centered around c+nq/4+c3 and a width " "sqrt(c), where c = c1 log((m - summ)/c2), m is the mass of the " "decaying particle, summ the sum of the quark masses and ci real " "parameters."); static Parameter interfaceFixedN ("FixedN", "The fixed number of hadrons to be produced. If less than 2, the " "number is instead given by a gaussian multiplicity distribution.", &QuarksToHadronsDecayer::theFixedN, 0, 0, 10, true, false, true); static Parameter interfaceMinN ("MinN", "The minimum hadrons to be produced.", &QuarksToHadronsDecayer::theMinN, 2, 2, 10, true, false, true); static Parameter interfaceC1 ("C1", "The c1 parameter of the gaussian multiplicity distribution centered " "around c1 log((m - summ)/c2) +c3.", &QuarksToHadronsDecayer::theC1, 4.5, 0.0, 10.0, true, false, true); static Parameter interfaceC2 ("C2", "The c2 parameter of the gaussian multiplicity distribution centered " "around c1 log((m - summ)/c2) +c3.", &QuarksToHadronsDecayer::theC2, GeV, 0.7*GeV, ZERO, 10.0*GeV, true, false, true); static Parameter interfaceC3 ("C3", "The c3 parameter of the gaussian multiplicity distribution centered " "around c1 log((m - summ)/c2) +c3.", &QuarksToHadronsDecayer::theC3, 0.0, 0.0, 10.0, true, false, true); static Reference interfaceFlavourGenerator ("FlavourGenerator", "The object in charge of generating hadrons spieces from given quark " "flavours.", &QuarksToHadronsDecayer::theFlavourGenerator, true, false, true, false, true); interfaceFixedN.rank(10); interfaceMinN.rank(9); interfaceFlavourGenerator.rank(8); interfaceMinN.setHasDefault(false);; } diff --git a/PDT/QuarksToHadronsDecayer.h b/PDT/QuarksToHadronsDecayer.h --- a/PDT/QuarksToHadronsDecayer.h +++ b/PDT/QuarksToHadronsDecayer.h @@ -1,264 +1,256 @@ // -*- C++ -*- // // QuarksToHadronsDecayer.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_QuarksToHadronsDecayer_H #define THEPEG_QuarksToHadronsDecayer_H // This is the declaration of the QuarksToHadronsDecayer class. #include "ThePEG/PDT/Decayer.h" #include "ThePEG/Handlers/FlavourGenerator.h" namespace ThePEG { ThePEG_DECLARE_CLASS_POINTERS(FlavourGenerator, FlavGenPtr); /** * The QuarksToHadronsDecayer class inherits from Decayer and is able * to decay particles to \f$n_q\f$ (2 or 4) quarks which then are * decayed to hadrons according to phase space. The number of final * hadrons can either be given by a fixed number or as a Gaussian * multiplicity distribution centered around \f$c+n_q/4+c_3\f$ and a * width \f$\sqrt{c}\f$, where \f$c = c_1 \log((m - \sum m)/c_2)\f$, * \f$m\f$ is the mass of the decaying particle, \f$\sum m\f$ the sum * of the quark masses and \f$c_i\f$ real parameters. * * @see \ref QuarksToHadronsDecayerInterfaces "The interfaces" * defined for QuarksToHadronsDecayer. * @see ParticleData * */ class QuarksToHadronsDecayer: public Decayer { public: - /** @name Standard constructors and destructors. */ - //@{ /** * Default constructor. */ QuarksToHadronsDecayer() : theFixedN(0), theMinN(2), theC1(4.5), theC2(0.7*GeV), theC3(0.0) {} - /** - * Destructor. - */ - virtual ~QuarksToHadronsDecayer(); - //@} - public: /** @name Virtual functions required by the Decayer class. */ //@{ /** * Check if this decayer can perfom the decay specified by the * given decay mode. * @param dm the DecayMode describing the decay. * @return true if this decayer can handle the given mode, otherwise false. */ virtual bool accept(const DecayMode & dm) const; /** * Perform a decay for a given DecayMode and a given Particle instance. * @param dm the DecayMode describing the decay. * @param p the Particle instance to be decayed. * @return a ParticleVector containing the decay products. */ virtual ParticleVector decay(const DecayMode & dm, const Particle & p) const; //@} /** * Get the number of hadrons to be produced, given the mass of the * decaying particle, \a m0, and the number, \a Nq and summed masses * of the quarks, \a summq. */ virtual int getN(Energy m0, Energy summq, int Nq) const; /** * Produce \a Nh hadrons from the specified \a quarks. The last * quark is considered to be a spectator quark. */ virtual PVector getHadrons(int Nh, tcPDVector quarks) const; /** * Distribute the produced children in phase space. This default * version uses a flat phase space which can be reweighted by * overriding the reweight() function. */ virtual void distribute(const Particle & parent, PVector & children) const; /** * Called by distribute() to reweight the default flat phase * spece. Can be overridden by sub-classes and should return a * number between 0 and 1. This version returns 1. */ virtual double reweight(const Particle & parent, const PVector & children) const; public: /** * Return the fixed number of hadrons to be produced. If less than * 2, the number is instead given by a gaussian multiplicity * distribution. */ int fixedN() const { return theFixedN; } /** * Return the minimum number of hadrons to be produced. */ int minN() const { return theMinN; } /** * Return the parameter \f$c_1\f$ used for the multiplicity * distriution. */ double c1() const { return theC1; } /** * Return the parameter \f$c_2\f$ used for the multiplicity * distriution. */ Energy c2() const { return theC2; } /** * Return the parameter \f$c_3\f$ used for the multiplicity * distriution. */ double c3() const { return theC3; } /** * Return a pointer to the flavour generator to be used. */ tcFlavGenPtr flavourGenerator() const { return theFlavourGenerator; } public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interfaces. */ static void Init(); protected: protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * The fixed number of hadrons to be produced. If less than 2, the * number is instead given by a gaussian multiplicity distribution. */ int theFixedN; /** * The minimum hadrons to be produced. */ int theMinN; /** * The parameter \f$c_1\f$ of the multiplicity distribution. */ double theC1; /** * The parameter \f$c_2\f$ of the multiplicity distribution. */ Energy theC2; /** * The parameter \f$c_3\f$ of the multiplicity distribution. */ double theC3; /** * The object in charge of generating hadrons spieces from given * quark flavours. */ FlavGenPtr theFlavourGenerator; private: /** * Describe a concrete class with persistent data. */ static ClassDescription initQuarksToHadronsDecayer; /** * Private and non-existent assignment operator. */ QuarksToHadronsDecayer & operator=(const QuarksToHadronsDecayer &) = delete; }; } namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of QuarksToHadronsDecayer. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of QuarksToHadronsDecayer. */ typedef Decayer NthBase; }; /** This template specialization informs ThePEG about the name of the * QuarksToHadronsDecayer class and the shared object where it is * defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::QuarksToHadronsDecayer"; } /** Return the name of the shared library be loaded to get access to * the QuarksToHadronsDecayer class and every other class it uses * (except the base class). */ static string library() { return "QuarksToHadronsDecayer.so"; } }; /** @endcond */ } #endif /* THEPEG_QuarksToHadronsDecayer_H */ diff --git a/PDT/SimpleBaryonRemnantDecayer.cc b/PDT/SimpleBaryonRemnantDecayer.cc --- a/PDT/SimpleBaryonRemnantDecayer.cc +++ b/PDT/SimpleBaryonRemnantDecayer.cc @@ -1,397 +1,395 @@ // -*- C++ -*- // // SimpleBaryonRemnantDecayer.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the SimpleBaryonRemnantDecayer class. // #include "SimpleBaryonRemnantDecayer.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/PDT/RemnantData.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/Utilities/UtilityBase.h" #include "ThePEG/Utilities/SimplePhaseSpace.h" #include "ThePEG/Utilities/HoldFlag.h" #include "ThePEG/Utilities/Throw.h" #include "ThePEG/PDF/BeamParticleData.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/EventRecord/Step.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; -SimpleBaryonRemnantDecayer::~SimpleBaryonRemnantDecayer() {} - IBPtr SimpleBaryonRemnantDecayer::clone() const { return new_ptr(*this); } IBPtr SimpleBaryonRemnantDecayer::fullclone() const { return new_ptr(*this); } bool SimpleBaryonRemnantDecayer::accept(const DecayMode &) const { return true; } bool SimpleBaryonRemnantDecayer:: canHandle(tcPDPtr particle, tcPDPtr parton) const { return BaryonMatcher::Check(*particle) && StandardQCDPartonMatcher::Check(*parton); } bool SimpleBaryonRemnantDecayer:: checkExtract(tcPPtr parent, tcPPtr parton, const LorentzMomentum & pnew) const { return pnew.e() > parent->nominalMass() + parton->data().constituentMass(); } ParticleVector SimpleBaryonRemnantDecayer:: decay(const DecayMode & dm, const Particle & p, Step & step) const { ParticleVector children; tcRemPPtr remnant = dynamic_ptr_cast(&p); if ( !remnant ) return children; tRemPDPtr rpd = data(remnant); PVector ex = extracted(remnant); tcPPtr particle = parent(remnant); if ( !particle || ex.empty() || !rpd ) return children; // We can't handle multiple extractions (yet) if ( ex.size() != 1 ) return children; tPPtr parton = ex[0]; tPVector subsys = getSubSystem(particle, parton); tPVector subpart; LorentzMomentum pitot = Utilities::sumMomentum(subsys) + remnant->momentum(); Energy2 s = ZERO; Energy2 shat = ZERO; LorentzMomentum psub; Energy minmass = particle->nominalMass() + 2.0*parton->nominalMass() + margin(); unsigned int closeskip = 0; while ( closeskip < subsys.size() ) { subpart = tPVector(subsys.begin() + closeskip, subsys.end()); while ( !subpart.empty() ) { psub = Utilities::sumMomentum(subpart); s = max((remnant->momentum() + psub).m2(), ZERO); shat = max(psub.m2(), ZERO); if ( subpart.size() == 1 ) shat = max(subpart[0]->momentum().mass2(), ZERO); if ( sqrt(s) > sqrt(shat) + minmass ) break; subpart.pop_back(); } if ( !subpart.empty() ) break; ++closeskip; } if ( subpart.empty() ) { if ( respectDISKinematics() ) { // If we couldn't find any way of shuffling momentum and this may // have been a DIS event, try to include the scattered lepton as // well. { HoldFlag nodis(respectDIS, 0); children = decay(dm, p, step); } if ( respectDISKinematics() == 1 ) Throw() << "The decay of the remnant '" << p.PDGName() << "' changed the kinematics of a scattered lepton in a DIS event.\n" << *step.collision()->event() << Exception::warning; return children; } else { Throw() << "Could not decay remnant '" << p.PDGName() << "' since not enough energy-momentum was available." << Exception::eventerror; } } const BaryonContent & bi = getBaryonInfo(particle->dataPtr()); // Check if we are extracting a valence quark int iq = parton->id(); vector vflav = bi.flav; vector::iterator v = find(vflav.begin(), vflav.end(), bi.sign*iq); double pval = 0.0; if ( v != vflav.end() ) { vflav.erase(v); tcPDFPtr pdf; const BeamParticleData * beamp = dynamic_cast(&*particle->dataPtr()); if ( beamp ) pdf = beamp->pdf(); if ( pdf && !specialValence() ) { Energy2 scale = abs(parton->scale()); double x = shat/s; pval = pdf->xfvx(particle->dataPtr(), parton->dataPtr(), scale, x)/ pdf->xfx(particle->dataPtr(), parton->dataPtr(), scale, x); } else { pval = 1; } } Energy mr = ZERO; while ( true ) { children.clear(); if ( rndbool(pval) ) { // A simple valence remnant. int idqr = 1000*max(vflav[0], vflav[1]) + 100*min(vflav[0], vflav[1]) + 3; if ( vflav[0] != vflav[1] && rndbool(0.25) ) idqr -= 2; children.push_back(getParticleData(bi.sign*idqr)->produceParticle()); mr = children[0]->mass(); } else { // We haven't extracted a valence so we first divide up the baryon // in a quark and a diquark. pair r = bi.flavsel.select(UseRandom::current()); int iqr = r.first*bi.sign; int idqr = r.second*bi.sign; if ( iq == ParticleID::g ) { children.push_back(getParticleData(iqr)->produceParticle()); children.push_back(getParticleData(idqr)->produceParticle()); } else if ( iq*iqr > 0 ) { children.push_back(getParticleData(idqr)->produceParticle()); children.push_back(flavourGenerator().getHadron (getParticleData(-iq), getParticleData(iqr))->produceParticle()); } else { children.push_back(getParticleData(iqr)->produceParticle()); children.push_back(flavourGenerator().getHadron (getParticleData(-iq), getParticleData(idqr))->produceParticle()); } TransverseMomentum ptr = pTGenerator()->generate(); Energy2 mt02 = children[0]->momentum().mass2() + ptr.pt2(); Energy2 mt12 = children[1]->momentum().mass2() + ptr.pt2(); double z = zGenerator().generate(children[1]->dataPtr(), children[0]->dataPtr(), mt12); mr = sqrt(mt02/(1.0 - z) + mt12/z); if ( sqrt(s) <= sqrt(shat) + mr ) continue; children[0]->set3Momentum(static_cast (lightCone((1.0 - z)*mr, mt02/((1.0 - z)*mr), ptr))); children[1]->set3Momentum(static_cast (lightCone(z*mr, mt12/(z*mr), -ptr))); } break; } // Make copies of all final particles in the hard subsystem which // will take recoil. for ( unsigned int i = 0, N = subsys.size(); i < N; ++i ) { if ( subsys[i]->birthStep() != &step ) subsys[i] = step.copyParticle(subsys[i]); if ( i >= closeskip && i - closeskip < subpart.size() ) subpart[i - closeskip] = subsys[i]; } // Boost part of the hard subsystem to give energy to the new // remnants. LorentzMomentum pr = remnant->momentum(); LorentzRotation R = Utilities::getBoostToCM(make_pair(psub, pr)); Energy pz = SimplePhaseSpace::getMagnitude(s, sqrt(shat), mr); if ( subpart.size() > 1 ) { LorentzRotation Rs(-(R*psub).boostVector()); Rs.boost(0.0, 0.0, pz/sqrt(sqr(pz) + shat)); Rs = Rs*R; R.invert(); Rs = R*Rs; Utilities::transform(subpart, Rs); } else { subpart[0]->set5Momentum( Lorentz5Momentum(ZERO, ZERO, pz, sqrt(sqr(pz) + shat), sqrt(shat))); R.invert(); Utilities::transform(subpart, R); } LorentzRotation Rr(0.0, 0.0, -pz/sqrt(sqr(pz) + sqr(mr))); Rr = R*Rr; Utilities::transform(children, Rr); // Give the remnants and subsystem a transverse momentum by Lorentz // rotations. LorentzMomentum pr0 = ( pr = Utilities::sumMomentum(children) ); LorentzMomentum psub0 = ( psub = Utilities::sumMomentum(subsys) ); LorentzMomentum ksub = pr + psub - particle->momentum(); R = Utilities::boostToCM(make_pair(&psub, &pr)); TransverseMomentum kt; do { kt = pTGenerator()->generate(); } while ( kt.pt() >= psub.z() ); LorentzRotation Rtot = R; Rtot.rotateY(asin(kt.pt()/psub.z())); Rtot.rotateZ(kt.phi()); Rtot = R.inverse()*Rtot; psub = Rtot*psub0; pr = Rtot*pr0; Utilities::transform(children, Rtot); if ( subsys.size() > 1 ) Utilities::transform(subsys, Utilities::getTransformToMomentum(psub0, psub, ksub)); else subsys[0]->setMomentum(psub); // Make small z-boosts to correct Utilities::transform(subsys, getZBoost(Utilities::sumMomentum(subsys), psub)); LorentzMomentum pftot = Utilities::sumMomentum(subsys) + Utilities::sumMomentum(children); R = getZBoost(pftot, pitot); Utilities::transform(subsys, R); Utilities::transform(children, R); return children; } const SimpleBaryonRemnantDecayer::BaryonContent & SimpleBaryonRemnantDecayer::getBaryonInfo(tcPDPtr baryon) const { map::iterator it = baryonmap.find(baryon); if ( it != baryonmap.end() ) return it->second; BaryonContent & bi = baryonmap[baryon]; int pid = baryon->id(); bi.sign = pid < 0? -1: 1; bi.flav = vector(3); bi.flav[0] = (pid = abs(pid)/10)%10; bi.flav[1] = (pid /= 10)%10; bi.flav[2] = (pid /= 10)%10; bi.flavsel = VSelector< pair >(); for ( int iq1 = 0; iq1 < 3; ++iq1 ) { int iq2 = (iq1 + 1)%3; int iq3 = (iq2 + 1)%3; int idq = 1000*max(bi.flav[iq2], bi.flav[iq3]) + 100*min(bi.flav[iq2], bi.flav[iq3]) + 3; bi.flavsel.insert(3.0, make_pair(bi.flav[iq1], idq)); if ( bi.flav[iq2] == bi.flav[iq3] ) continue; bi.flavsel.insert(1.0, make_pair(bi.flav[iq1], idq - 2)); } return bi; } bool SimpleBaryonRemnantDecayer::preInitialize() const { return RemnantDecayer::preInitialize() || !theZGenerator || !theFlavourGenerator; } void SimpleBaryonRemnantDecayer::doinit() { RemnantDecayer::doinit(); if ( !theZGenerator ) { theZGenerator = dynamic_ptr_cast (generator()->preinitCreate("ThePEG::SimpleZGenerator", fullName() + "/ZGen", "SimpleZGenerator.so")); } if ( !theFlavourGenerator ) { theFlavourGenerator = dynamic_ptr_cast (generator()->preinitCreate("ThePEG::SimpleFlavour", fullName() + "/FlavGen", "SimpleFlavour.so")); } } void SimpleBaryonRemnantDecayer:: persistentOutput(PersistentOStream & os) const { os << theZGenerator << theFlavourGenerator << ounit(theMargin,GeV) << useSpecialValence; } void SimpleBaryonRemnantDecayer:: persistentInput(PersistentIStream & is, int) { is >> theZGenerator >> theFlavourGenerator >> iunit(theMargin,GeV) >> useSpecialValence; } ClassDescription SimpleBaryonRemnantDecayer::initSimpleBaryonRemnantDecayer; // Definition of the static class description member. void SimpleBaryonRemnantDecayer::Init() { static ClassDocumentation documentation ("The SimpleBaryonRemnantDecayer class inherits from the RemnantDecayer " "class and is able to decay RemnantParticles produced by the " "SoftRemnantHandler class for the cases when a single parton has been " "extracted from a baryon."); static Reference interfaceZGenerator ("ZGenerator", "The object responsible for generating momentum fractions in case " "of more than one remnant. If not set and the controlling EventGenerator " "has a default ZGenerator object, this will be used. Otherwise a " "SimpleZGenerator object created with default settings in the " "initialization will be used instead.", &SimpleBaryonRemnantDecayer::theZGenerator, true, false, true, true, true); static Reference interfaceFlavourGenerator ("FlavourGenerator", "The object responsible for handling the flavour contents of a baryon. " "If not set and the controlling EventGenerator " "has a default FlavourGenerator object, this will be used. Otherwise a " "SimpleFlavour object created with default settings in the " "initialization will be used instead.", &SimpleBaryonRemnantDecayer::theFlavourGenerator, true, false, true, true, true); static Parameter interfaceMargin ("EnergyMargin", "The energy margin (in GeV) to be added to the sum of the parent and " "parton masses to determine if it is possible to construct the remnants " "with the given (upper limit of the) virtuality of the extracted parton.", &SimpleBaryonRemnantDecayer::theMargin, GeV, 1.0*GeV, ZERO, 10.0*GeV, false, false, true); static Switch interfaceSpecialValence ("SpecialValence", "If true, an extracted valence quark will always give a di-quark remnant.", &SimpleBaryonRemnantDecayer::useSpecialValence, false, true, false); static SwitchOption interfaceSpecialValenceYes (interfaceSpecialValence, "Yes", "An extracted valence quark will always give a di-quark remnant.", true); static SwitchOption interfaceSpecialValenceNo (interfaceSpecialValence, "No", "An extracted valence flavour may be considered to be a sea-quark.", false); interfaceZGenerator.rank(8); interfaceFlavourGenerator.rank(7); } diff --git a/PDT/SimpleBaryonRemnantDecayer.h b/PDT/SimpleBaryonRemnantDecayer.h --- a/PDT/SimpleBaryonRemnantDecayer.h +++ b/PDT/SimpleBaryonRemnantDecayer.h @@ -1,308 +1,303 @@ // -*- C++ -*- // // SimpleBaryonRemnantDecayer.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_SimpleBaryonRemnantDecayer_H #define THEPEG_SimpleBaryonRemnantDecayer_H // // This is the declaration of the SimpleBaryonRemnantDecayer class. // #include "ThePEG/PDT/RemnantDecayer.h" #include "ThePEG/Handlers/ZGenerator.h" #include "ThePEG/Handlers/FlavourGenerator.h" #include "ThePEG/Utilities/VSelector.h" namespace ThePEG { /** * The SimpleBaryonRemnantDecayer class inherits from the * RemnantDecayer class and is able to decay RemnantParticles produced * by the SoftRemnantHandler class for the cases when a single parton * has been extracted from a baryon. * * @see \ref SimpleBaryonRemnantDecayerInterfaces "The interfaces" * defined for SimpleBaryonRemnantDecayer. */ class SimpleBaryonRemnantDecayer: public RemnantDecayer { public: /** A pointer to a ZGenerator object. */ typedef Ptr::pointer ZGPtr; /** A pointer to a FlavourGenerator object. */ typedef Ptr::pointer FlGPtr; public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ SimpleBaryonRemnantDecayer() : theMargin(1.0*GeV), useSpecialValence(false) {} /** * The copy constructor. */ SimpleBaryonRemnantDecayer(const SimpleBaryonRemnantDecayer & x) : RemnantDecayer(x), theZGenerator(x.theZGenerator), theFlavourGenerator(x.theFlavourGenerator), theMargin(x.theMargin), useSpecialValence(x.useSpecialValence) {} - - /** - * The destructor. - */ - virtual ~SimpleBaryonRemnantDecayer(); //@} public: /** @name Virtual functions required by the RemnantDecayer class. */ //@{ /** * Check if this decayer can perfom the decay specified by the * given decay mode. * @param dm the DecayMode describing the decay. * @return true if this decayer can handle the given mode, otherwise false. */ virtual bool accept(const DecayMode & dm) const; /** * Perform a decay for a given DecayMode and a given Particle * instance. This version allows the decaying particle to borrow * energy/momentum from its sublings in the current step. This will * be called by the standard DecayHandler if the needsFullStep() * function returns true. * * @param dm the DecayMode describing the decay. * @param p the Particle instance to be decayed. * @param step the current step in which to find possible siblings to * shuffle energy with. * @return a ParticleVector containing the decay products. */ virtual ParticleVector decay(const DecayMode & dm, const Particle & p, Step & step) const; /** * Return true if this decayer can handle the extraction of the \a * extracted parton from the given \a particle. */ virtual bool canHandle(tcPDPtr parent, tcPDPtr extracted) const; /** * Return true if this decayer can handle the extraction of the \a * extracted parton instance from the given \a particle instance. \a * pnew is the momentum of the resulting remnant. The default * version simply checks if the energy is positive. */ virtual bool checkExtract(tcPPtr parent, tcPPtr extracted, const LorentzMomentum & pnew) const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Return true if this object needs to be initialized before all * other objects because it needs to extract cuts from the event file. */ virtual bool preInitialize() const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); public: /** * Warning Exception used when DIS kinematics was not respected. */ struct NoDISRespect: public Exception {}; /** * Exception thrown if the decay of a remnant was impossible. */ struct DecayFailed: public Exception {}; public: /** * Return a reference to the object responsible for generating * momentum fractions in case of more than one remnant. */ ZGenerator & zGenerator() const { return *theZGenerator; } /** * Return a reference to the object responsible for handling the * flavour contents of a baryon. */ FlavourGenerator & flavourGenerator() const { return *theFlavourGenerator; } /** * Return the energy margin to be added to the sum of the parent and * parton masses to determine if it is possible to construct the * remnants with the given (upper limit of the) virtuality of the * extracted parton. */ Energy margin() const { return theMargin; } /** * If true an extracted valens quark will always give a di-quark remnant. */ bool specialValence() const { return useSpecialValence; } protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} public: /** * Simple struct to store info about baryon quark and di-quark * constituents. */ struct BaryonContent { /** The valence flavours of the corresponding baryon. */ vector flav; /** Different divisions into quark-diquark weighted by their respective probabilities. */ VSelector< pair > flavsel; /** -1 if the particle is an anti-particle. +1 otherwise. */ int sign; }; /** * Return info about baryon quark and di-quark constituents. */ const BaryonContent & getBaryonInfo(tcPDPtr baryon) const; private: /** * The object responsible for generating momentum fractions in case * of more than one remnant. */ ZGPtr theZGenerator; /** * The object responsible for handling the flavour contents of a * baryon. */ FlGPtr theFlavourGenerator; /** * The energy margin to be added to the sum of the parent and parton * masses to determine if it is possible to construct the remnants * with the given (upper limit of the) virtuality of the extracted * parton. */ Energy theMargin; /** * If true an extracted valens quark will always give a di-quark remnant. */ bool useSpecialValence; /** * A map of info about baryon quark and di-quark constituents. */ mutable map baryonmap; private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ClassDescription initSimpleBaryonRemnantDecayer; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ SimpleBaryonRemnantDecayer & operator=(const SimpleBaryonRemnantDecayer &) = delete; }; } #include "ThePEG/Utilities/ClassTraits.h" namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the * base classes of SimpleBaryonRemnantDecayer. */ template <> struct BaseClassTrait { /** Typedef of the first base class of SimpleBaryonRemnantDecayer. */ typedef RemnantDecayer NthBase; }; /** This template specialization informs ThePEG about the name of the * SimpleBaryonRemnantDecayer class and the shared object where it is * defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::SimpleBaryonRemnantDecayer"; } }; /** @endcond */ } #endif /* THEPEG_SimpleBaryonRemnantDecayer_H */ diff --git a/PDT/Tau2HadronsDecayer.cc b/PDT/Tau2HadronsDecayer.cc --- a/PDT/Tau2HadronsDecayer.cc +++ b/PDT/Tau2HadronsDecayer.cc @@ -1,73 +1,71 @@ // -*- C++ -*- // // Tau2HadronsDecayer.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the Tau2HadronsDecayer class. // #include "Tau2HadronsDecayer.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; -Tau2HadronsDecayer::~Tau2HadronsDecayer() {} - IBPtr Tau2HadronsDecayer::clone() const { return new_ptr(*this); } IBPtr Tau2HadronsDecayer::fullclone() const { return new_ptr(*this); } bool Tau2HadronsDecayer::accept(const DecayMode & dm) const { if ( dm.products().size() < 3 || !dm.cascadeProducts().empty() || !dm.productMatchers().empty() || dm.wildProductMatcher() ) return false; if ( abs(dm.parent()->id()) != ParticleID::tauminus ) return false; for ( ParticleMSet::const_iterator pit = dm.products().begin(); pit != dm.products().end(); ++pit ) if ( (**pit).id()*dm.parent()->id() == ParticleID::tauminus*ParticleID::nu_tau ) return true; return false; } double Tau2HadronsDecayer::reweight(const DecayMode &, const Particle & parent, const ParticleVector & children) const { tPPtr nu; for ( int i = 0, N = children.size(); i < N; ++i ) if ( parent.id()*children[i]->id() == ParticleID::tauminus*ParticleID::nu_tau ) { nu = children[i]; break; } double xnu = 2.0*nu->momentum().e()/parent.mass(); return 0.5*xnu*(3.0 - xnu); } void Tau2HadronsDecayer::persistentOutput(PersistentOStream &) const {} void Tau2HadronsDecayer::persistentInput(PersistentIStream &, int) {} ClassDescription Tau2HadronsDecayer::initTau2HadronsDecayer; // Definition of the static class description member. void Tau2HadronsDecayer::Init() { static ClassDocumentation documentation ("This class will perform the decays of tau to neutrimo + hadrons " "according to phase space, with an extra weight xnu(3-nxu)."); } diff --git a/PDT/Tau2HadronsDecayer.h b/PDT/Tau2HadronsDecayer.h --- a/PDT/Tau2HadronsDecayer.h +++ b/PDT/Tau2HadronsDecayer.h @@ -1,156 +1,146 @@ // -*- C++ -*- // // Tau2HadronsDecayer.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_Tau2HadronsDecayer_H #define THEPEG_Tau2HadronsDecayer_H // This is the declaration of the Tau2HadronsDecayer class. #include "ThePEG/PDT/FlatDecayer.h" namespace ThePEG { /** * The Tau2HadronsDecayer class inherits FlatDecayer and can perform * the decays of tau to neutrino + hadrons according to phase space, * with an extra weight \f$x_\nu(3-x_\nu)\f$. * * @see \ref Tau2HadronsDecayerInterfaces "The interfaces" * defined for Tau2HadronsDecayer. */ class Tau2HadronsDecayer: public FlatDecayer { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * Destructor. - */ - virtual ~Tau2HadronsDecayer(); - //@} - -public: - /** @name Virtual functions required by the Decayer class. */ //@{ /** * Check if this decayer can perfom the decay specified by the * given decay mode. * @param dm the DecayMode describing the decay. * @return true if this decayer can handle the given mode, otherwise false. */ virtual bool accept(const DecayMode & dm) const; /** * Give a weight to a phase space point. To be overridden by * subclasses. For a given decay mode, \a dm, decaying \a parent * particle and decayproducts, \a children, distributed according to * a flat distribution in phase space, return a weight (less or * equal to unity) modifying the flat distribution to the desired * one. Note that the chosen phase space point may be rejected, but * the chosen decay channel will not. This means that the weight * returned by this function does not influence the branching * ratios. */ virtual double reweight(const DecayMode & dm, const Particle & parent, const ParticleVector & children) const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interfaces. */ static void Init(); protected: protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * Describe a concrete class with persistent data. */ static ClassDescription initTau2HadronsDecayer; /** * Private and non-existent assignment operator. */ Tau2HadronsDecayer & operator=(const Tau2HadronsDecayer &) = delete; }; } namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of Tau2HadronsDecayer. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of Tau2HadronsDecayer. */ typedef FlatDecayer NthBase; }; /** This template specialization informs ThePEG about the name of the * Tau2HadronsDecayer class and the shared object where it is * defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::Tau2HadronsDecayer"; } /** Return the name of the shared library be loaded to get access to * the Tau2HadronsDecayer class and every other class it uses * (except the base class). */ static string library() { return "Tau2HadronsDecayer.so"; } }; /** @endcond */ } #endif /* THEPEG_Tau2HadronsDecayer_H */ diff --git a/PDT/V2PPDecayer.cc b/PDT/V2PPDecayer.cc --- a/PDT/V2PPDecayer.cc +++ b/PDT/V2PPDecayer.cc @@ -1,102 +1,100 @@ // -*- C++ -*- // // V2PPDecayer.cc is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the V2PPDecayer class. // #include "V2PPDecayer.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/PDT/DecayMode.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDT/StandardMatchers.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace ThePEG; -V2PPDecayer::~V2PPDecayer() {} - IBPtr V2PPDecayer::clone() const { return new_ptr(*this); } IBPtr V2PPDecayer::fullclone() const { return new_ptr(*this); } bool V2PPDecayer::accept(const DecayMode & dm) const { if ( dm.products().size() != 2 || !dm.cascadeProducts().empty() || !dm.productMatchers().empty() || dm.wildProductMatcher() ) return false; for ( ParticleMSet::const_iterator it = dm.products().begin(); it != dm.products().end(); ++it ) if ( !PseudoScalarMesonMatcher::Check(**it) ) return false; return ( VectorMesonMatcher::Check(*dm.parent()) ); } ParticleVector V2PPDecayer::decay(const DecayMode & dm, const Particle & parent) const { grandParent = tPPtr(); sibling = tPPtr(); if ( parent.parents().size() == 1 && PseudoScalarMesonMatcher::Check(parent.parents()[0]->data()) ) grandParent = parent.parents()[0]; if ( grandParent && grandParent->children().size() == 2 ) { tParticleSet siblings = parent.siblings(); if ( siblings.size() == 1 && (PseudoScalarMesonMatcher::Check((**siblings.begin()).data()) || (**siblings.begin()).id() == ParticleID::gamma ) ) sibling = *siblings.begin(); } return FlatDecayer::decay(dm, parent); } double V2PPDecayer::reweight(const DecayMode &, const Particle & parent, const ParticleVector & children) const { if ( !sibling || !grandParent ) return 1.0; LorentzMomentum gp = grandParent->momentum(); gp.boost(-parent.momentum().boostVector()); LorentzMomentum pp(ZERO, ZERO, ZERO, parent.mass()); Energy2 p10 = pp*gp; Energy2 p12 = pp*children[0]->momentum(); Energy2 p02 = gp*children[0]->momentum(); Energy2 m02 = gp.m2(); Energy2 m12 = pp.m2(); Energy2 m22 = children[0]->momentum().mass2(); if ( grandParent->id() == ParticleID::gamma ) return m12*(2.0*p10*p12*p02 - m12*sqr(p02) - m02*sqr(p12) - m22*sqr(p10) + m12*m02*m22)/((sqr(p10) - m12*m02)*(sqr(p12) - m12*m22)); else return sqr(p10*p12 - m12*p02)/((sqr(p10) - m12*m02)*(sqr(p12) - m12*m22)); } void V2PPDecayer::persistentOutput(PersistentOStream & os) const { os << grandParent << sibling; } void V2PPDecayer::persistentInput(PersistentIStream & is, int) { is >> grandParent >> sibling; } ClassDescription V2PPDecayer::initV2PPDecayer; // Definition of the static class description member. void V2PPDecayer::Init() { static ClassDocumentation documentation ("This class performs the decay of a vector meson into two " "pseudo-scalars according to a flat phase space. If, however the " "decaying particle comes from a pseudo-scalar and has only one " "sibling which is a pseudo-scalar (or a photon) the decay is " "reweighted with cos^2 (sin^2 for photon) of the angle between one " "of the decay products and its grand parent. "); } diff --git a/PDT/V2PPDecayer.h b/PDT/V2PPDecayer.h --- a/PDT/V2PPDecayer.h +++ b/PDT/V2PPDecayer.h @@ -1,181 +1,171 @@ // -*- C++ -*- // // V2PPDecayer.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef THEPEG_V2PPDecayer_H #define THEPEG_V2PPDecayer_H // This is the declaration of the V2PPDecayer class. #include "ThePEG/PDT/FlatDecayer.h" namespace ThePEG { /** * The V2PPDecayer class performs the decay of a vector meson into two * pseudo-scalars according to a flat phase space. If, however the * decaying particle comes from a pseudo-scalar and has only one * sibling which is a pseudo-scalar (or a photon) the decay is * reweighted with \f$\cos^2\f$ (\f$\sin^2\f$ for photon) of the angle * between one of the decay products and its grand parent. * * @see \ref V2PPDecayerInterfaces "The interfaces" * defined for V2PPDecayer. * @see FlatDecayer * @see ParticleData */ class V2PPDecayer: public FlatDecayer { public: - /** @name Standard constructors and destructors. */ - //@{ - /** - * Destructor. - */ - virtual ~V2PPDecayer(); - //@} - -public: - /** @name Virtual functions required by the Decayer class. */ //@{ /** * Check if this decayer can perfom the decay specified by the * given decay mode. * @param dm the DecayMode describing the decay. * @return true if this decayer can handle the given mode, otherwise false. */ virtual bool accept(const DecayMode & dm) const; /** * Perform a decay for a given DecayMode and a given Particle instance. * @param dm the DecayMode describing the decay. * @param p the Particle instance to be decayed. * @return a ParticleVector containing the decay products. */ virtual ParticleVector decay(const DecayMode & dm, const Particle & p) const; /** * Give a weight to a phase space point. To be overridden by * subclasses. For a given decay mode, \a dm, decaying \a parent * particle and decayproducts, \a children, distributed according to * a flat distribution in phase space, return a weight (less or * equal to unity) modifying the flat distribution to the desired * one. Note that the chosen phase space point may be rejected, but * the chosen decay channel will not. This means that the weight * returned by this function does not influence the branching * ratios. */ virtual double reweight(const DecayMode & dm, const Particle & parent, const ParticleVector & children) const; //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * Standard Init function used to initialize the interfaces. */ static void Init(); protected: protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} private: /** * The grand parent in case reweighting should be done. */ mutable tPPtr grandParent; /** * The decaying particles sibling in case reweighting should be done. */ mutable tPPtr sibling; private: /** * Describe a concrete class with persistent data. */ static ClassDescription initV2PPDecayer; /** * Private and non-existent assignment operator. */ V2PPDecayer & operator=(const V2PPDecayer &) = delete; }; } namespace ThePEG { /** @cond TRAITSPECIALIZATIONS */ /** This template specialization informs ThePEG about the base classes * of V2PPDecayer. */ template <> struct BaseClassTrait: public ClassTraitsType { /** Typedef of the first base class of . */ typedef FlatDecayer NthBase; }; /** This template specialization informs ThePEG about the name of the * V2PPDecayer class and the shared object where it is * defined. */ template <> struct ClassTraits : public ClassTraitsBase { /** Return a platform-independent class name */ static string className() { return "ThePEG::V2PPDecayer"; } /** Return the name of the shared library be loaded to get access to * the V2PPDecayer class and every other class it uses * (except the base class). */ static string library() { return "V2PPDecayer.so"; } }; /** @endcond */ } #endif /* THEPEG_V2PPDecayer_H */ diff --git a/Utilities/ClassDescription.h b/Utilities/ClassDescription.h --- a/Utilities/ClassDescription.h +++ b/Utilities/ClassDescription.h @@ -1,487 +1,481 @@ // -*- C++ -*- // // ClassDescription.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 1999-2019 Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_ClassDescription_H #define ThePEG_ClassDescription_H #include "ThePEG/Config/ThePEG.h" #include "ClassDescription.fh" #include "ThePEG/Utilities/Named.h" #include "ThePEG/Persistency/PersistentOStream.fh" #include "ThePEG/Persistency/PersistentIStream.fh" #include "ClassTraits.h" #include "DescriptionList.h" namespace ThePEG { /** * ClassDescriptionBase is the base class for all class description * classes. ClassDescriptionBase is the non-templated base class for * the templated ClassDescriptionTBase, ClassDescription, * AbstractClassDescription, NoPIOClassDescription and * AbstractNoPIOClassDescription classes. An instantiation of one of * these classes represents a meta class encapsulating information * about the template argument class. This information is obtained * from the templated ClassTraits class which can be specialized for * any given class should the default information not be * satisfactory. Information is also obtained from the templated * BaseClassTraits class which must be specialized for each class * declaring a typedef for each of its base classes. * * The information about a class stored in a * ClassDescriptionBase objects is the following:
a * platform-independent class name,
a reference to the * type_info
an integer version number,
a vector * of ClassDescriptionBase* corresponding to the base * classes,
methods for reading/writing members of a class from/to * a PersistentIStream/PersistentOStream and
a method for creating * an object of a class. * * The ClassDescriptionBase objects should be created before main() is * executed, and shouold therfore be instantiated as static member * variables. Only one ClassDescriptionBase object shall be * instantiated for each class to be described. The * ClassDescriptionBase objects are automatically stored in a purely * static DescriptionList class. * * AbstractClassDescription and AbstractNoPIOClassDescription should * be used for abstract base classes, while NoPIOClassDescription and * AbstractNoPIOClassDescription should be used for classes which do * not have any members which need to be read and written * persistently. * * @see ClassTraits * @see PersistentIStream * @see PersistentOStream * @see DescriptionList */ class ClassDescriptionBase: public Named { public: /** A vector of class descriptions. */ typedef vector DescriptionVector; protected: /** * The constructor used by sub-classes. * @param newName the platform independent name of the class. * @param newInfo the type_info object corresponding to the class. * @param newVersion the implementation version of the class. * @param newLibrary the name of a file containing the dynamic * @param abst true if the class is abstract. * library where the class is implemented. */ ClassDescriptionBase(string newName, const type_info & newInfo, int newVersion, string newLibrary, bool abst) : Named(newName), theVersion(newVersion), theLibrary(newLibrary), theInfo(newInfo), isAbstract(abst), done(false) {} public: /** * Empty destructor. */ virtual ~ClassDescriptionBase(); /** * The standart RTTI type_info object for the described class. */ const type_info & info() const { return theInfo; } /** * The version of the described class. */ int version() const { return theVersion; } /** * The name of a file containing the dynamic * library where the class is implemented. */ string library() const { return theLibrary; } /** * Return true if this object was set up properly. */ bool check() const { return done; } /** * Return the descriptions of the base classes of the described * class. */ const DescriptionVector & descriptions() const { return theBaseClasses; } /** * Set up the base class information for this object. */ virtual void setup() = 0; /** * Create an object of the described class. */ virtual BPtr create() const = 0; /** * Output the members of an object of the described class to a * persistent stream. * @param b the object to be written. * @param os the persistent stream. */ virtual void output(tcBPtr b, PersistentOStream & os) const = 0; /** * Read the members of an object of the described class from a * persistent stream. * @param b the object to be read. * @param is the persistent stream. * @param oldVersion the version number of the object when it was written. */ virtual void input(tBPtr b, PersistentIStream & is, int oldVersion) const = 0; /** * Return true if the class described by the argument is a base * class of the class described by this. */ bool isA(const ClassDescriptionBase & base) const; /** * Return true if the corresponding class is abstract. */ bool abstract() const { return isAbstract; } protected: /** * Set the base classes. * @param first an iterator refering to the first base class * @param last an iterator giving the end of the range of base class * descriptions. */ void baseClasses(DescriptionVector::iterator first, DescriptionVector::iterator last) { theBaseClasses = DescriptionVector(first, last); done = true; } private: /** * The version of the described class. */ int theVersion; /** * The library file where this class may be found. */ string theLibrary; /** * The type_info object for the described class */ const type_info & theInfo; /** * The vector of base classes. */ DescriptionVector theBaseClasses; /** * True if this class is abstract. */ bool isAbstract; /** * True if this object was set up properly. */ bool done; }; /** * A helper class for tracing the base classes of a class to be * described */ template ::NthBase> struct ClassDescriptionHelper { /** Add base classes */ static void addBases(vector & c){ const ClassDescriptionBase * b = DescriptionList::find(typeid(B)); if ( !b ) return; c.push_back(b); ClassDescriptionHelper::addBases(c); } }; /** @cond TRAITSPECIALIZATIONS */ /** * A helper class for tracing the base classes of a class to be * described */ template struct ClassDescriptionHelper { /** Add base classes */ static void addBases(vector & ) {} }; /** @endcond */ /** * An intermediate templated base class derived from * ClassDescriptionBase. */ template class ClassDescriptionTBase: public ClassDescriptionBase { public: /** The traits class for the template argument class. */ typedef ClassTraits Traits; public: /** * Default constructor. If \a abst is true then the corresponding * class is abstract. */ ClassDescriptionTBase(bool abst) : ClassDescriptionBase(Traits::className(), typeid(T), Traits::version(), Traits::library(), abst) { DescriptionList::Register(*this); T::Init(); } - - /** - * The descructor. - */ - virtual ~ClassDescriptionTBase() {} - /** * Set up the base class information for this object. */ virtual void setup() { DescriptionVector bases; ClassDescriptionHelper::addBases(bases); baseClasses(bases.begin(), bases.end()); } }; /** * A concreate implementation of ClassDescriptionBase describing an * abstract class with persistent data. */ template class AbstractClassDescription: public ClassDescriptionTBase { public: /** The traits class for the template argument class. */ typedef ClassTraits Traits; public: /** * Default constructor. */ AbstractClassDescription() : ClassDescriptionTBase(true) {} /** * Do not create an object of the described class (which is * abstract). Just return the null pointer. */ virtual BPtr create() const { throw std::logic_error("Tried to instantiate virtual class " + Named::name()); } /** * Output the members of an object of the described class to a * persistent stream. * @param b the object to be written. * @param os the persistent stream. */ virtual void output(tcBPtr b, PersistentOStream & os) const { Traits::output(Traits::cast(b), os); } /** * Read the members of an object of the described class from a * persistent stream. * @param b the object to be read. * @param is the persistent stream. * @param oldVersion the version number of the object when it was written. */ virtual void input(tBPtr b, PersistentIStream & is, int oldVersion) const { Traits::input(Traits::cast(b), is, oldVersion); } }; /** * A concreate implementation of ClassDescriptionBase describing a * concrete class with persistent data. */ template class ClassDescription: public ClassDescriptionTBase { public: /** The traits class for the template argument class. */ typedef ClassTraits Traits; public: /** * Default constructor. */ ClassDescription() : ClassDescriptionTBase(false) {} /** * Create an object of the described class. */ virtual BPtr create() const { return Traits::create(); } /** * Output the members of an object of the described class to a * persistent stream. * @param b the object to be written. * @param os the persistent stream. */ virtual void output(tcBPtr b, PersistentOStream & os) const { Traits::output(Traits::cast(b), os); } /** * Read the members of an object of the described class from a * persistent stream. * @param b the object to be read. * @param is the persistent stream. * @param oldVersion the version number of the object when it was written. */ virtual void input(tBPtr b, PersistentIStream & is, int oldVersion) const { Traits::input(Traits::cast(b), is, oldVersion); } }; /** * A concreate implementation of ClassDescriptionBase describing a * concrete class without persistent data. */ template class NoPIOClassDescription: public ClassDescriptionTBase { public: /** The traits class for the template argument class. */ typedef ClassTraits Traits; public: /** * Default constructor. */ NoPIOClassDescription() : ClassDescriptionTBase(false) {} /** * Create an object of the described class. */ virtual BPtr create() const { return Traits::create(); } /** * Do nothing since the described class has no persistent data. */ virtual void output(tcBPtr, PersistentOStream &) const {} /** * Do nothing since the described class has no persistent data. */ virtual void input(tBPtr, PersistentIStream &, int) const {} }; /** * A concreate implementation of ClassDescriptionBase describing an * abstract class without persistent data. */ template class AbstractNoPIOClassDescription: public ClassDescriptionTBase { public: /** The traits class for the template argument class. */ typedef ClassTraits Traits; public: /** * Default constructor. */ AbstractNoPIOClassDescription() : ClassDescriptionTBase(true) {} /** * Do not create an object of the described class (which is * abstract). Just return the null pointer. */ virtual BPtr create() const { throw std::logic_error("Tried to instantiate virtual class " + Named::name()); } /** * Do nothing since the described class has no persistent data. */ virtual void output(tcBPtr, PersistentOStream & ) const {} /** * Do nothing since the described class has no persistent data. */ virtual void input(tBPtr, PersistentIStream &, int) const {} }; } #define ThePEG_DECLARE_CLASS_DESCRIPTION(Class) \ /** Describe a concrete class with persistent data. */ \ static ClassDescription init ## Class \ #define ThePEG_DECLARE_ABSTRACT_CLASS_DESCRIPTION(Class) \ /** Describe an abstract class with persistent data. */ \ static AbstractClassDescription init ## Class \ #define ThePEG_DECLARE_NOPIO_CLASS_DESCRIPTION(Class) \ /** Describe a concrete class without persistent data. */ \ static NoPIOClassDescription init ## Class \ #define ThePEG_DECLARE_ABSTRACT_NOPIO_CLASS_DESCRIPTION(Class) \ /** Describe an abstract class without persistent data. */ \ static AbstractNoPIOClassDescription init ## Class \ #define ThePEG_IMPLEMENT_CLASS_DESCRIPTION(Class) \ ClassDescription Class::init ## Class \ #define ThePEG_IMPLEMENT_ABSTRACT_CLASS_DESCRIPTION(Class) \ AbstractClassDescription Class::init ## Class \ #define ThePEG_IMPLEMENT_NOPIO_CLASS_DESCRIPTION(Class) \ NoPIOClassDescription Class::init ## Class \ #define ThePEG_IMPLEMENT_ABSTRACT_NOPIO_CLASS_DESCRIPTION(Class) \ AbstractNoPIOClassDescription Class::init ## Class \ #endif /* ThePEG_ClassDescription_H */ diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -1,175 +1,175 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([ThePEG],[devel],[http://www.thep.lu.se/ThePEG/],[ThePEG]) AC_CONFIG_AUX_DIR([Config]) AC_CONFIG_MACRO_DIR([m4]) THEPEG_LIBTOOL_VERSION_INFO(30,0,0) AC_CONFIG_SRCDIR([EventRecord/SubProcess.h]) AC_CONFIG_HEADERS([Config/config.h]) AC_CANONICAL_HOST case "${host}" in *-darwin[[0156]].*) AC_MSG_ERROR([ThePEG requires OS X 10.3 or later]) ;; *-darwin7.*) if test "x$MACOSX_DEPLOYMENT_TARGET" != "x10.3"; then AC_MSG_ERROR( [Please export the MACOSX_DEPLOYMENT_TARGET variable, set to 10.3]) fi ;; esac AC_LANG(C++) AM_INIT_AUTOMAKE([1.9 gnu dist-bzip2 subdir-objects -Wall]) dnl also include std-options once --version and --help exist m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl Checks for C++ compiler. Handle C++11 flags. AC_PROG_CXX AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory]) dnl check for unistd AC_CHECK_HEADER([unistd.h],[], [AC_MSG_ERROR([ThePEG needs "unistd.h". Check your system is POSIX-compliant.])]) dnl Checks for programs. AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_LN_S LT_PREREQ([2.2]) LT_INIT([disable-static dlopen pic-only]) VL_LIB_READLINE THEPEG_CHECK_GSL THEPEG_SEARCH_LHAPDF THEPEG_CHECK_HEPMC THEPEG_CHECK_RIVET FASTJET_CHECK_FASTJET AX_CHECK_ZLIB dnl AX_CHECK_BZ2LIB THEPEG_DEFINE_ENVDEFAULT(ThePEG_GZREAD_FILE,GZREAD_FILE,gunzip -c,[The command which, taking the name of a gzipped file as argument, unzips it and prints it to stdout. Default is "gunzip -c"]) THEPEG_DEFINE_ENVDEFAULT(ThePEG_GZWRITE_FILE,GZWRITE_FILE,[gzip -c > ],[The command which, taking the name of a gzipped file as argument, reads stdin, zips it and writes it to the file. Default is "gzip -c > ".]) THEPEG_DEFINE_ENVDEFAULT(ThePEG_BZ2READ_FILE,BZ2READ_FILE,bunzip2 -c,[The command which, taking the name of a bzipped file as argument, unzips it and prints it to stdout. Default is "bunzip2 -c".]) THEPEG_DEFINE_ENVDEFAULT(ThePEG_BZ2WRITE_FILE,BZ2WRITE_FILE,[bzip2 -c > ],[The command which, taking the name of a bzipped file as argument, reads stdin, zips it and writes it to the file. Default is "bzip2 -c > ".]) THEPEG_CHECK_EXPM1 THEPEG_CHECK_LOG1P THEPEG_CHECK_DLOPEN AX_COMPILER_VENDOR case "${ax_cv_cxx_compiler_vendor}" in clang) case "${host}" in *linux*) AC_MSG_WARN([ ***************************************************************************** clang/LLVM ignores the CPU floating-point environment. All floating point exception trapping will be disabled. *****************************************************************************]) ;; esac esac THEPEG_CHECK_FPUCONTROL THEPEG_CHECK_FENV AM_CPPFLAGS="-I\$(top_builddir)/include \$(GSLINCLUDE)" case "${ax_cv_cxx_compiler_vendor}" in gnu) - AM_CXXFLAGS="-pedantic -Wall -W" + AM_CXXFLAGS="-pedantic -Wall -W -Wno-use-after-free" ;; clang) AM_CXXFLAGS="-pedantic -Wall -Wno-overloaded-virtual -Wno-unused-function" dnl -Wno-unneeded-internal-declaration ;; intel) AM_CXXFLAGS="-strict-ansi -Wall -wd13000,1418,981,444,383,1599,1572,2259,980" ;; esac AC_SUBST(AM_CPPFLAGS) AC_SUBST(AM_CXXFLAGS) dnl do an actual capability check on ld instead of this workaround case "${host}" in *-darwin*) ;; *) AM_LDFLAGS="-Wl,--enable-new-dtags" ;; esac AC_SUBST(AM_LDFLAGS) THEPEG_EMPTY_SUBST AC_PATH_PROG(PERL, perl) AC_ARG_WITH(javagui, [ --with-javagui Compile and install the java-based GUI.]) if test "x$with_javagui" != "xno"; then THEPEG_HAS_JAVA([1.4], [], [with_javagui=no; AC_MSG_NOTICE([Java GUI disabled])]) fi AM_CONDITIONAL([JAVAGUI], [test "x$with_javagui" != "xno"]) AC_CONFIG_FILES([Helicity/Makefile Helicity/WaveFunction/Makefile Helicity/Vertex/Makefile Helicity/Vertex/Scalar/Makefile Helicity/Vertex/Vector/Makefile Helicity/Vertex/Tensor/Makefile Utilities/Makefile include/Makefile Interface/Makefile LesHouches/Makefile Vectors/Makefile PDT/Makefile PDF/Makefile Persistency/Makefile Config/Makefile Handlers/Makefile MatrixElement/Makefile Pointer/Makefile lib/Makefile lib/Makefile.common.install src/Makefile src/thepeg-config ACDC/Makefile Repository/Makefile EventRecord/Makefile StandardModel/Makefile Cuts/Makefile Analysis/Makefile Doc/Makefile Doc/MakeDocs.in Doc/refman.h Doc/refman.conf java/Makefile Makefile]) AC_CONFIG_FILES([Doc/fixinterfaces.pl],[chmod +x Doc/fixinterfaces.pl]) BOOST_REQUIRE([1.41],[AC_SUBST([BOOST_NOT_FOUND],[true])]) BOOST_TEST() THEPEG_BOOST_UNIT_TEST THEPEG_OVERVIEW AC_CONFIG_COMMANDS([summary],[cat config.thepeg]) AC_OUTPUT