diff --git a/Hadronization/ClusterHadronizationHandler.cc b/Hadronization/ClusterHadronizationHandler.cc --- a/Hadronization/ClusterHadronizationHandler.cc +++ b/Hadronization/ClusterHadronizationHandler.cc @@ -1,320 +1,463 @@ // -*- C++ -*- // // ClusterHadronizationHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig 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 ClusterHadronizationHandler class. // #include "ClusterHadronizationHandler.h" #include <ThePEG/Interface/ClassDocumentation.h> #include <ThePEG/Persistency/PersistentOStream.h> #include <ThePEG/Persistency/PersistentIStream.h> #include <ThePEG/Interface/Switch.h> #include <ThePEG/Interface/Parameter.h> #include <ThePEG/Interface/Reference.h> #include <ThePEG/Handlers/EventHandler.h> #include <ThePEG/Handlers/Hint.h> #include <ThePEG/PDT/ParticleData.h> #include <ThePEG/EventRecord/Particle.h> #include <ThePEG/EventRecord/Step.h> #include <ThePEG/PDT/PDT.h> #include <ThePEG/PDT/EnumParticles.h> #include <ThePEG/Utilities/Throw.h> #include "Herwig/Utilities/EnumParticles.h" #include "CluHadConfig.h" #include "Cluster.h" #include <ThePEG/Utilities/DescribeClass.h> using namespace Herwig; ClusterHadronizationHandler * ClusterHadronizationHandler::currentHandler_ = 0; DescribeClass<ClusterHadronizationHandler,HadronizationHandler> describeClusterHadronizationHandler("Herwig::ClusterHadronizationHandler","Herwig.so"); IBPtr ClusterHadronizationHandler::clone() const { return new_ptr(*this); } IBPtr ClusterHadronizationHandler::fullclone() const { return new_ptr(*this); } void ClusterHadronizationHandler::persistentOutput(PersistentOStream & os) const { os << _partonSplitter << _clusterFinder << _colourReconnector << _clusterFissioner << _lightClusterDecayer << _clusterDecayer + << reshuffle_ << reshuffleMode_ << gluonMassGenerator_ << ounit(_minVirtuality2,GeV2) << ounit(_maxDisplacement,mm) << _underlyingEventHandler << _reduceToTwoComponents; } void ClusterHadronizationHandler::persistentInput(PersistentIStream & is, int) { is >> _partonSplitter >> _clusterFinder >> _colourReconnector >> _clusterFissioner >> _lightClusterDecayer >> _clusterDecayer + >> reshuffle_ >> reshuffleMode_ >> gluonMassGenerator_ >> iunit(_minVirtuality2,GeV2) >> iunit(_maxDisplacement,mm) >> _underlyingEventHandler >> _reduceToTwoComponents; } void ClusterHadronizationHandler::Init() { static ClassDocumentation<ClusterHadronizationHandler> documentation ("This is the main handler class for the Cluster Hadronization", "The hadronization was performed using the cluster model of \\cite{Webber:1983if}.", "%\\cite{Webber:1983if}\n" "\\bibitem{Webber:1983if}\n" " B.~R.~Webber,\n" " ``A QCD Model For Jet Fragmentation Including Soft Gluon Interference,''\n" " Nucl.\\ Phys.\\ B {\\bf 238}, 492 (1984).\n" " %%CITATION = NUPHA,B238,492;%%\n" // main manual ); static Reference<ClusterHadronizationHandler,PartonSplitter> interfacePartonSplitter("PartonSplitter", "A reference to the PartonSplitter object", &Herwig::ClusterHadronizationHandler::_partonSplitter, false, false, true, false); static Reference<ClusterHadronizationHandler,ClusterFinder> interfaceClusterFinder("ClusterFinder", "A reference to the ClusterFinder object", &Herwig::ClusterHadronizationHandler::_clusterFinder, false, false, true, false); static Reference<ClusterHadronizationHandler,ColourReconnector> interfaceColourReconnector("ColourReconnector", "A reference to the ColourReconnector object", &Herwig::ClusterHadronizationHandler::_colourReconnector, false, false, true, false); static Reference<ClusterHadronizationHandler,ClusterFissioner> interfaceClusterFissioner("ClusterFissioner", "A reference to the ClusterFissioner object", &Herwig::ClusterHadronizationHandler::_clusterFissioner, false, false, true, false); static Reference<ClusterHadronizationHandler,LightClusterDecayer> interfaceLightClusterDecayer("LightClusterDecayer", "A reference to the LightClusterDecayer object", &Herwig::ClusterHadronizationHandler::_lightClusterDecayer, false, false, true, false); static Reference<ClusterHadronizationHandler,ClusterDecayer> interfaceClusterDecayer("ClusterDecayer", "A reference to the ClusterDecayer object", &Herwig::ClusterHadronizationHandler::_clusterDecayer, false, false, true, false); + static Reference<ClusterHadronizationHandler,GluonMassGenerator> interfaceGluonMassGenerator + ("GluonMassGenerator", + "Set a reference to a gluon mass generator.", + &ClusterHadronizationHandler::gluonMassGenerator_, false, false, true, true, false); + + static Switch<ClusterHadronizationHandler,bool> interfaceReshuffle + ("Reshuffle", + "Perform reshuffling if constituent masses have not yet been included by the shower", + &ClusterHadronizationHandler::reshuffle_, false, false, false); + static SwitchOption interfaceReshuffleYes + (interfaceReshuffle, + "Global", + "Do reshuffle.", + true); + static SwitchOption interfaceReshuffleNo + (interfaceReshuffle, + "No", + "Do not reshuffle.", + false); + + static Switch<ClusterHadronizationHandler,int> interfaceReshuffleMode + ("ReshuffleMode", + "Which mode is used for the reshuffling to constituent masses", + &ClusterHadronizationHandler::reshuffleMode_, 0, false, false); + static SwitchOption interfaceReshuffleModeGlobal + (interfaceReshuffleMode, + "Global", + "Global reshuffling on all final state partons", + 0); + static SwitchOption interfaceReshuffleModeColourConnected + (interfaceReshuffleMode, + "ColourConnected", + "Separate reshuffling for colour connected partons", + 1); + static Parameter<ClusterHadronizationHandler,Energy2> interfaceMinVirtuality2 ("MinVirtuality2", "Minimum virtuality^2 of partons to use in calculating distances (unit [GeV2]).", &ClusterHadronizationHandler::_minVirtuality2, GeV2, 0.1*GeV2, ZERO, 10.0*GeV2,false,false,false); static Parameter<ClusterHadronizationHandler,Length> interfaceMaxDisplacement ("MaxDisplacement", "Maximum displacement that is allowed for a particle (unit [millimeter]).", &ClusterHadronizationHandler::_maxDisplacement, mm, 1.0e-10*mm, 0.0*mm, 1.0e-9*mm,false,false,false); static Reference<ClusterHadronizationHandler,StepHandler> interfaceUnderlyingEventHandler ("UnderlyingEventHandler", "Pointer to the handler for the Underlying Event. " "Set to NULL to disable.", &ClusterHadronizationHandler::_underlyingEventHandler, false, false, true, true, false); static Switch<ClusterHadronizationHandler,bool> interfaceReduceToTwoComponents ("ReduceToTwoComponents", "Whether or not to reduce three component baryon-number violating clusters to two components before cluster splitting or leave" " this till after the cluster splitting", &ClusterHadronizationHandler::_reduceToTwoComponents, true, false, false); static SwitchOption interfaceReduceToTwoComponentsYes (interfaceReduceToTwoComponents, "BeforeSplitting", "Reduce to two components", true); static SwitchOption interfaceReduceToTwoComponentsNo (interfaceReduceToTwoComponents, "AfterSplitting", "Treat as three components", false); } namespace { void extractChildren(tPPtr p, set<PPtr> & all) { if (p->children().empty()) return; for (PVector::const_iterator child = p->children().begin(); child != p->children().end(); ++child) { all.insert(*child); extractChildren(*child, all); } } } void ClusterHadronizationHandler:: handle(EventHandler & ch, const tPVector & tagged, const Hint &) { useMe(); currentHandler_ = this; - PVector currentlist(tagged.begin(),tagged.end()); + + PVector theList(tagged.begin(),tagged.end()); + + if ( reshuffle_ ) { + + vector<PVector> reshufflelists; + + if (reshuffleMode_==0){ // global reshuffling + reshufflelists.push_back(theList); + } + else if (reshuffleMode_==1){// colour connected reshuffling + splitIntoColourSinglets(theList, reshufflelists); + } + + for (auto currentlist : reshufflelists){ + // get available energy and energy needed for constituent mass shells + LorentzMomentum totalQ; + Energy needQ = ZERO; + size_t nGluons = 0; // number of gluons for which a mass need be generated + for ( auto p : currentlist ) { + totalQ += p->momentum(); + if ( p->id() == ParticleID::g && gluonMassGenerator() ) { + ++nGluons; + continue; + } + needQ += p->dataPtr()->constituentMass(); + } + Energy Q = totalQ.m(); + if ( needQ > Q ) + throw Exception() << "cannot reshuffle to constituent mass shells" << Exception::eventerror; + + // generate gluon masses if needed + list<Energy> gluonMasses; + if ( nGluons && gluonMassGenerator() ) + gluonMasses = gluonMassGenerator()->generateMany(nGluons,Q-needQ); + + // set masses for inidividual particles + vector<Energy> masses; + for ( auto p : currentlist ) { + if ( p->id() == ParticleID::g && gluonMassGenerator() ) { + list<Energy>::const_iterator it = gluonMasses.begin(); + advance(it,UseRandom::irnd(gluonMasses.size())); + masses.push_back(*it); + gluonMasses.erase(it); + } + else { + masses.push_back(p->dataPtr()->constituentMass()); + } + } + + // reshuffle to new masses + reshuffle(currentlist,masses); + + } + + } + // set the scale for coloured particles to just above the gluon mass squared // if less than this so they are classed as perturbative Energy2 Q02 = 1.01*sqr(getParticleData(ParticleID::g)->constituentMass()); - for(unsigned int ix=0;ix<currentlist.size();++ix) { - if(currentlist[ix]->scale()<Q02) currentlist[ix]->scale(Q02); + for(unsigned int ix=0;ix<theList.size();++ix) { + if(theList[ix]->scale()<Q02) theList[ix]->scale(Q02); } // split the gluons - _partonSplitter->split(currentlist); + _partonSplitter->split(theList); // form the clusters ClusterVector clusters = - _clusterFinder->formClusters(currentlist); + _clusterFinder->formClusters(theList); // reduce BV clusters to two components now if needed if(_reduceToTwoComponents) _clusterFinder->reduceToTwoComponents(clusters); // perform colour reconnection if needed and then // decay the clusters into one hadron bool lightOK = false; short tried = 0; const ClusterVector savedclusters = clusters; tPVector finalHadrons; // only needed for partonic decayer while (!lightOK && tried++ < 10) { // no colour reconnection with baryon-number-violating (BV) clusters ClusterVector CRclusters, BVclusters; CRclusters.reserve( clusters.size() ); BVclusters.reserve( clusters.size() ); for (size_t ic = 0; ic < clusters.size(); ++ic) { ClusterPtr cl = clusters.at(ic); bool hasClusterParent = false; for (unsigned int ix=0; ix < cl->parents().size(); ++ix) { if (cl->parents()[ix]->id() == ParticleID::Cluster) { hasClusterParent = true; break; } } if (cl->numComponents() > 2 || hasClusterParent) BVclusters.push_back(cl); else CRclusters.push_back(cl); } // colour reconnection _colourReconnector->rearrange(CRclusters); // tag new clusters as children of the partons to hadronize _setChildren(CRclusters); // forms diquarks _clusterFinder->reduceToTwoComponents(CRclusters); // recombine vectors of (possibly) reconnected and BV clusters clusters.clear(); clusters.insert( clusters.end(), CRclusters.begin(), CRclusters.end() ); clusters.insert( clusters.end(), BVclusters.begin(), BVclusters.end() ); // fission of heavy clusters // NB: during cluster fission, light hadrons might be produced straight away finalHadrons = _clusterFissioner->fission(clusters,isSoftUnderlyingEventON()); // if clusters not previously reduced to two components do it now if(!_reduceToTwoComponents) _clusterFinder->reduceToTwoComponents(clusters); lightOK = _lightClusterDecayer->decay(clusters,finalHadrons); // if the decay of the light clusters was not successful, undo the cluster // fission and decay steps and revert to the original state of the event // record if (!lightOK) { clusters = savedclusters; for_each(clusters.begin(), clusters.end(), std::mem_fn(&Particle::undecay)); } } if (!lightOK) { throw Exception( "CluHad::handle(): tried LightClusterDecayer 10 times!", Exception::eventerror); } // decay the remaining clusters _clusterDecayer->decay(clusters,finalHadrons); // ***************************************** // ***************************************** // ***************************************** bool finalStateCluster=false; StepPtr pstep = newStep(); set<PPtr> allDecendants; for (tPVector::const_iterator it = tagged.begin(); it != tagged.end(); ++it) { extractChildren(*it, allDecendants); } for(set<PPtr>::const_iterator it = allDecendants.begin(); it != allDecendants.end(); ++it) { // this is a workaround because the set sometimes // re-orders parents after their children if ((*it)->children().empty()){ // If there is a cluster in the final state throw an event error if((*it)->id()==81) { finalStateCluster=true; } pstep->addDecayProduct(*it); } else { pstep->addDecayProduct(*it); pstep->addIntermediate(*it); } } // For very small center of mass energies it might happen that baryonic clusters cannot decay into hadrons if (finalStateCluster){ throw Exception( "CluHad::Handle(): Cluster in the final state", Exception::eventerror); } // ***************************************** // ***************************************** // ***************************************** // soft underlying event if needed if (isSoftUnderlyingEventON()) { assert(_underlyingEventHandler); ch.performStep(_underlyingEventHandler,Hint::Default()); } } // Sets parent child relationship of all clusters with two components // Relationships for clusters with more than two components are set elsewhere in the Colour Reconnector void ClusterHadronizationHandler::_setChildren(const ClusterVector & clusters) const { // erase existing information about the partons' children tPVector partons; for ( const auto & cl : clusters ) { if ( cl->numComponents() > 2 ) continue; partons.push_back( cl->colParticle() ); partons.push_back( cl->antiColParticle() ); } // erase all previous information about parent child relationship for_each(partons.begin(), partons.end(), std::mem_fn(&Particle::undecay)); // give new parents to the clusters: their constituents for ( const auto & cl : clusters ) { if ( cl->numComponents() > 2 ) continue; cl->colParticle()->addChild(cl); cl->antiColParticle()->addChild(cl); } } + +void ClusterHadronizationHandler::splitIntoColourSinglets(PVector copylist, + vector<PVector>& reshufflelists){ + + PVector currentlist; + bool gluonloop; + PPtr firstparticle, temp; + reshufflelists.clear(); + + while (copylist.size()>0){ + gluonloop=false; + currentlist.clear(); + + firstparticle=copylist.back(); + copylist.pop_back(); + + if (!firstparticle->coloured()){ + continue; //non-coloured particles are not included + } + + currentlist.push_back(firstparticle); + + //go up the anitColourLine and check if we are in a gluon loop + temp=firstparticle; + while( temp->hasAntiColour()){ + temp = temp->antiColourLine()->endParticle(); + if(temp==firstparticle){ + gluonloop=true; + break; + } + else{ + currentlist.push_back(temp); + copylist.erase(remove(copylist.begin(),copylist.end(), temp), copylist.end()); + } + } + + //if not a gluon loop, go up the ColourLine + if(!gluonloop){ + temp=firstparticle; + while( temp->hasColour()){ + temp=temp->colourLine()->startParticle(); + currentlist.push_back(temp); + copylist.erase(remove(copylist.begin(),copylist.end(), temp), copylist.end()); + } + } + + reshufflelists.push_back(currentlist); + } + +} diff --git a/Hadronization/ClusterHadronizationHandler.h b/Hadronization/ClusterHadronizationHandler.h --- a/Hadronization/ClusterHadronizationHandler.h +++ b/Hadronization/ClusterHadronizationHandler.h @@ -1,214 +1,247 @@ // -*- C++ -*- // // ClusterHadronizationHandler.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2019 The Herwig Collaboration // // Herwig is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_ClusterHadronizationHandler_H #define HERWIG_ClusterHadronizationHandler_H #include <ThePEG/Handlers/HadronizationHandler.h> #include "PartonSplitter.h" #include "ClusterFinder.h" #include "ColourReconnector.h" #include "ClusterFissioner.h" #include "LightClusterDecayer.h" #include "ClusterDecayer.h" #include "ClusterHadronizationHandler.fh" +#include "Herwig/Utilities/Reshuffler.h" +#include "GluonMassGenerator.h" namespace Herwig { using namespace ThePEG; /** \ingroup Hadronization * \class ClusterHadronizationHandler * \brief Class that controls the cluster hadronization algorithm. * \author Philip Stephens // cerr << *ch.currentEvent() << '\n'; cerr << finalHadrons.size() << '\n'; cerr << "Finished hadronizing \n"; * \author Alberto Ribon * * This class is the main driver of the cluster hadronization: it is * responsible for the proper handling of all other specific collaborating * classes PartonSplitter, ClusterFinder, ColourReconnector, ClusterFissioner, * LightClusterDecayer, ClusterDecayer; * and for the storing of the produced particles in the Event record. * * @see PartonSplitter * @see ClusterFinder * @see ColourReconnector * @see ClusterFissioner * @see LightClusterDecayer * @see ClusterDecayer * @see Cluster * @see \ref ClusterHadronizationHandlerInterfaces "The interfaces" * defined for ClusterHadronizationHandler. */ -class ClusterHadronizationHandler: public HadronizationHandler { +class ClusterHadronizationHandler: + public HadronizationHandler, public Reshuffler { public: /** * The main method which manages the all cluster hadronization. * * This routine directs "traffic". It determines which function is called * and on which particles/clusters. This function also handles the * situation of vetos on the hadronization. */ virtual void handle(EventHandler & ch, const tPVector & tagged, const Hint & hint); /** * It returns minimum virtuality^2 of partons to use in calculating * distances. It is used both in the Showering and Hadronization. */ Energy2 minVirtuality2() const { return _minVirtuality2; } /** * It returns the maximum displacement that is allowed for a particle * (used to determine the position of a cluster with two components). */ Length maxDisplacement() const { return _maxDisplacement; } /** * It returns true/false according if the soft underlying model * is switched on/off. */ bool isSoftUnderlyingEventON() const { return _underlyingEventHandler; } /** * pointer to "this", the current HadronizationHandler. */ static const ClusterHadronizationHandler * currentHandler() { if(!currentHandler_){ cerr<< " \nCreating new ClusterHadronizationHandler without input from infiles."; cerr<< " \nWhen using for example the string model "; cerr<< " hadronic decays are still treated by the Cluster model\n"; currentHandler_=new ClusterHadronizationHandler();; } return currentHandler_; } + /** + * A pointer to a gluon mass generator for the reshuffling + */ + Ptr<GluonMassGenerator>::tptr gluonMassGenerator() const { + return gluonMassGenerator_; + } + 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: /** * Private and non-existent assignment operator. */ ClusterHadronizationHandler & operator=(const ClusterHadronizationHandler &) = delete; /** * This is a pointer to a Herwig::PartonSplitter object. */ PartonSplitterPtr _partonSplitter; /** * This is a pointer to a Herwig::ClusterFinder object. */ ClusterFinderPtr _clusterFinder; /** * This is a pointer to a Herwig::ColourReconnector object. */ ColourReconnectorPtr _colourReconnector; /** * This is a pointer to a Herwig::ClusterFissioner object. */ ClusterFissionerPtr _clusterFissioner; /** * This is a pointer to a Herwig::LightClusterDecayer object. */ LightClusterDecayerPtr _lightClusterDecayer; /** * This is a pointer to a Herwig::ClusterDecayer object. */ ClusterDecayerPtr _clusterDecayer; /** + * Perform reshuffling to constituent masses. + */ + bool reshuffle_ = false; + + /** + * Which type of reshuffling (global (default) or colour connected) is used + */ + int reshuffleMode_ = 0; + + /** + * A pointer to a gluon mass generator for the reshuffling + */ + Ptr<GluonMassGenerator>::ptr gluonMassGenerator_; + + /** * The minimum virtuality^2 of partons to use in calculating * distances. */ Energy2 _minVirtuality2 = 0.1_GeV2; /** * The maximum displacement that is allowed for a particle * (used to determine the position of a cluster with two components). */ Length _maxDisplacement = 1.0e-10_mm; /** * The pointer to the Underlying Event handler. */ StepHdlPtr _underlyingEventHandler; /** * How to handle baryon-number clusters */ bool _reduceToTwoComponents = true; /** * Tag the constituents of the clusters as their parents */ void _setChildren(const ClusterVector & clusters) const; + + + /** + * Split the list of partons into colour connected sub-lists before reshuffling + */ + void splitIntoColourSinglets(PVector thelist, + vector<PVector>& reshufflelists); + /** * pointer to "this", the current HadronizationHandler. */ static ClusterHadronizationHandler * currentHandler_; }; } #endif /* HERWIG_ClusterHadronizationHandler_H */ diff --git a/Hadronization/GluonMassGenerator.cc b/Hadronization/GluonMassGenerator.cc new file mode 100644 --- /dev/null +++ b/Hadronization/GluonMassGenerator.cc @@ -0,0 +1,63 @@ +// -*- C++ -*- +// +// GluonMassGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator +// Copyright (C) 2002-2019 The Herwig Collaboration +// +// Herwig 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 GluonMassGenerator class. +// + +#include "GluonMassGenerator.h" +#include "ThePEG/Interface/ClassDocumentation.h" +#include "ThePEG/EventRecord/Particle.h" +#include "ThePEG/Repository/UseRandom.h" +#include "ThePEG/Repository/EventGenerator.h" +#include "ThePEG/Utilities/DescribeClass.h" +#include "ThePEG/StandardModel/StandardModelBase.h" +#include "ClusterHadronizationHandler.h" + +#include "ThePEG/Persistency/PersistentOStream.h" +#include "ThePEG/Persistency/PersistentIStream.h" + +using namespace Herwig; + +GluonMassGenerator::GluonMassGenerator() {} + +GluonMassGenerator::~GluonMassGenerator() {} + +IBPtr GluonMassGenerator::clone() const { + return new_ptr(*this); +} + +IBPtr GluonMassGenerator::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 GluonMassGenerator::persistentOutput(PersistentOStream &) const {} + +void GluonMassGenerator::persistentInput(PersistentIStream &, int) {} + + +// *** 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<GluonMassGenerator,HandlerBase> + describeHerwigGluonMassGenerator("Herwig::GluonMassGenerator", ""); + +void GluonMassGenerator::Init() { + + static ClassDocumentation<GluonMassGenerator> documentation + ("Dynamic gluon mass generation"); + +} + diff --git a/Hadronization/GluonMassGenerator.h b/Hadronization/GluonMassGenerator.h new file mode 100644 --- /dev/null +++ b/Hadronization/GluonMassGenerator.h @@ -0,0 +1,171 @@ +// -*- C++ -*- +// +// GluonMassGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator +// Copyright (C) 2002-2019 The Herwig Collaboration +// +// Herwig is licenced under version 3 of the GPL, see COPYING for details. +// Please respect the MCnet academic guidelines, see GUIDELINES for details. +// +#ifndef Herwig_GluonMassGenerator_H +#define Herwig_GluonMassGenerator_H +// +// This is the declaration of the GluonMassGenerator class. +// + +#include "ThePEG/Handlers/HandlerBase.h" +#include "ThePEG/EventRecord/Particle.h" + +namespace Herwig { + +using namespace ThePEG; + +/** + * \ingroup Hadronization + * \brief Dynamic gluon mass generator; the default returns a constant mass. + * + * @see \ref GluonMassGeneratorInterfaces "The interfaces" + * defined for GluonMassGenerator. + */ +class GluonMassGenerator: public HandlerBase { + +public: + + /** @name Standard constructors and destructors. */ + //@{ + /** + * The default constructor. + */ + GluonMassGenerator(); + + /** + * The destructor. + */ + virtual ~GluonMassGenerator(); + //@} + +public: + + /** + * Generate a single gluon mass with possible reference to a hard + * scale Q and up to a maximum value + */ + virtual Energy generate(Energy, Energy) const { + return generate(); + } + + /** + * Generate a single gluon mass with possible reference to a hard + * scale Q + */ + virtual Energy generate(Energy) const { + return generate(); + } + + /** + * Generate a single gluon mass without further constraints + */ + virtual Energy generate() const { + return getParticleData(ThePEG::ParticleID::g)->constituentMass(); + } + + /** + * Generate a list of n gluon masses, with a maximum available energy + */ + list<Energy> generateMany(size_t n, Energy QMax) const { + list<Energy> res; + Energy m0, mu, md, ms, mg, mgmax, summg; + + mu=getParticleData(ThePEG::ParticleID::u)->constituentMass(); + md=getParticleData(ThePEG::ParticleID::d)->constituentMass(); + ms=getParticleData(ThePEG::ParticleID::s)->constituentMass(); + + m0=md; + if(mu<m0){m0=mu;} + if(ms<m0){m0=ms;} + + if( QMax<2.0*m0*n ){ + throw Exception() << "cannot reshuffle to constituent mass shells" << Exception::eventerror; + } + + bool repeat=true; + + while( repeat ){ + repeat=false; + summg = 0.0*GeV; + res.clear(); + for( size_t k = 0; k < n; ++k ){ + mg = generate(); + res.push_back(mg); + summg += mg; + if( summg > QMax - 2.0*m0*(n-k-1) ){ + repeat=true; + break; + } + } + } + + return res; + + } + +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 assignment operator is private and must never be called. + * In fact, it should not even be implemented. + */ + GluonMassGenerator & operator=(const GluonMassGenerator &); + +}; + +} + +#endif /* Herwig_GluonMassGenerator_H */ diff --git a/Hadronization/Makefile.am b/Hadronization/Makefile.am --- a/Hadronization/Makefile.am +++ b/Hadronization/Makefile.am @@ -1,17 +1,18 @@ noinst_LTLIBRARIES = libHwHadronization.la libHwHadronization_la_SOURCES = \ CheckId.cc CheckId.h \ CluHadConfig.h \ Cluster.h Cluster.cc Cluster.fh \ ClusterDecayer.cc ClusterDecayer.h ClusterDecayer.fh \ ClusterFinder.cc ClusterFinder.h ClusterFinder.fh \ ClusterFissioner.cc ClusterFissioner.h ClusterFissioner.fh \ ClusterHadronizationHandler.cc ClusterHadronizationHandler.h \ ClusterHadronizationHandler.fh \ ColourReconnector.cc ColourReconnector.h ColourReconnector.fh\ +GluonMassGenerator.h GluonMassGenerator.cc \ HadronSelector.cc HadronSelector.h HadronSelector.fh\ Hw64Selector.cc Hw64Selector.h Hw64Selector.fh\ HwppSelector.cc HwppSelector.h HwppSelector.fh\ LightClusterDecayer.cc LightClusterDecayer.h LightClusterDecayer.fh \ PartonSplitter.cc PartonSplitter.h PartonSplitter.fh \ SpinHadronizer.h SpinHadronizer.cc