Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:24:06

0001 // -*- C++ -*-
0002 //
0003 // PhaseSpaceMode.h is a part of Herwig - A multi-purpose Monte Carlo event generator
0004 // Copyright (C) 2002-2019 The Herwig Collaboration
0005 //
0006 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 #ifndef Herwig_PhaseSpaceMode_H
0010 #define Herwig_PhaseSpaceMode_H
0011 //
0012 // This is the declaration of the PhaseSpaceMode class.
0013 //
0014 
0015 #include "ThePEG/Config/ThePEG.h"
0016 #include "PhaseSpaceMode.fh"
0017 #include "PhaseSpaceChannel.h"
0018 #include "Herwig/PDT/GenericWidthGenerator.h"
0019 #include "Herwig/PDT/GenericMassGenerator.h"
0020 
0021 namespace Herwig {
0022 using namespace ThePEG;
0023 
0024 /** \ingroup Decay
0025  *
0026  * The <code>PhaseSpaceMode</code> class is designed to store a group
0027  * of phase-space channels for use by the DecayIntegrator class to 
0028  * generate the phase-space for a given decay mode.
0029  *
0030  * Additional phase-space channels can be added using the addChannel member.
0031  * 
0032  *  In practice the modes are usually constructed together with the a number of
0033  *  <code>PhaseSpaceChannel</code> objects. In classes inheriting from the
0034  *  DecayIntegrator class.
0035  *
0036  * @see DecayIntegrator
0037  * @see PhaseSpaceChannel
0038  *
0039  * @author  Peter Richardson
0040  * 
0041  */
0042 class PhaseSpaceMode: public Base {
0043 
0044   friend class PhaseSpaceChannel;
0045 
0046 public:
0047 
0048   /** @name Standard constructors and destructors. */
0049   //@{
0050   /**
0051    * The default constructor.
0052    */
0053   PhaseSpaceMode() : maxWeight_(0.), partial_(-1),
0054              testOnShell_(false), eMax_(ZERO),
0055              eps_(ZERO), nRand_(0)
0056   {};
0057   
0058   /**
0059    * The default constructor.
0060    */
0061   PhaseSpaceMode(tPDPtr in1, tPDVector out,
0062          double wMax, tPDPtr in2=tPDPtr(),
0063          Energy eMax=ZERO) : incoming_(make_pair(in1,in2)),
0064                      maxWeight_(wMax),
0065                      outgoing_(out), partial_(-1),
0066                      testOnShell_(false), eMax_(eMax),
0067                      eps_(ZERO), nRand_(0)
0068   {};
0069   //@}
0070 
0071 public:
0072   
0073   /**
0074    * Generate the decay.
0075    * @param intermediates Whether or not to generate the intermediate particle
0076    *                      in the decay channel.
0077    * @param cc Whether we are generating the mode specified or the charge 
0078    *           conjugate mode.
0079    * @param inpart The incoming particle.
0080    * @return The outgoing particles.
0081    */
0082   ParticleVector generateDecay(const Particle & inpart,
0083                    tcDecayIntegratorPtr decayer,
0084                    bool intermediates,bool cc);
0085   
0086   /**
0087    * Add a new channel. 
0088    * @param channel A pointer to the new PhaseChannel
0089    */
0090   void addChannel(PhaseSpaceChannel channel) {
0091     channel.init(this);
0092     channels_.push_back(channel);
0093   }
0094 
0095   /**
0096    * Reset the properties of one of the intermediate particles. Only a specific channel
0097    * is reset.
0098    * @param ichan The channel to reset.
0099    * @param part The ParticleData object of the particle to reset
0100    * @param mass The mass of the intermediate.
0101    * @param width The width of gthe intermediate.
0102    */
0103   void resetIntermediate(int ichan, tcPDPtr part, Energy mass, Energy width) {
0104     if(!part) return;
0105     channels_[ichan].resetIntermediate(part,mass,width);
0106   }
0107 
0108   /**
0109    * Reset the properties of one of the intermediate particles. All the channels 
0110    * are reset.
0111    * @param part The ParticleData object of the particle to reset
0112    * @param mass The mass of the intermediate.
0113    * @param width The width of gthe intermediate.
0114    */
0115   void resetIntermediate(tcPDPtr part, Energy mass, Energy width) {
0116     for(PhaseSpaceChannel & channel : channels_)
0117       channel.resetIntermediate(part,mass,width);
0118   }
0119 
0120   /**
0121    *   The phase-space channels
0122    */
0123   const vector<PhaseSpaceChannel> & channels() const {return channels_;}
0124 
0125   /**
0126    *   Set the weights
0127    */
0128   void setWeights(const vector<double> & wgts) {
0129     assert(wgts.size()==channels_.size());
0130     for(unsigned int ix=0;ix<channels_.size();++ix)
0131       channels_[ix].weight(wgts[ix]);
0132   }
0133 
0134   /**
0135    *  Access to the selected channel
0136    */
0137   unsigned int selectedChannel() const {return iChannel_;}
0138 
0139   /**
0140    *  Number of rnadom numbers needed
0141    */
0142   unsigned int nRand() const {return nRand_;}
0143 
0144   /**
0145    *  Set whether of not decays are generated on-shell
0146    */
0147   void checkOnShell(bool in) {testOnShell_=in;}
0148   
0149 public:
0150 
0151   /** @name Functions used by the persistent I/O system. */
0152   //@{
0153   /**
0154    * Function used to write out object persistently.
0155    * @param os the persistent output stream written to.
0156    */
0157   void persistentOutput(PersistentOStream & os) const;
0158 
0159   /**
0160    * Function used to read in object persistently.
0161    * @param is the persistent input stream read from.
0162    * @param version the version number of the object when written.
0163    */
0164   void persistentInput(PersistentIStream & is, int version);
0165   //@}
0166 
0167   /**
0168    * The standard Init function used to initialize the interfaces.
0169    * Called exactly once for each class by the class description system
0170    * before the main function starts or
0171    * when this class is dynamically loaded.
0172    */
0173   static void Init();
0174 
0175 public :
0176 
0177   /**
0178    *   Initialize the phase space
0179    */
0180   void init();
0181 
0182   /**
0183    *   Initialisation before the run stage
0184    */
0185   void initrun(); 
0186 
0187   /**
0188    * Get the maximum weight for the decay.
0189    * @return The maximum weight.
0190    */
0191   double maxWeight() const {return maxWeight_;}
0192   
0193   /**
0194    * Set the maximum weight for the decay.
0195    * @return The maximum weight.
0196    */
0197   void maxWeight(double wgt) const {maxWeight_=wgt;}
0198   
0199   /**
0200    * Initialise the phase space.
0201    * @param init Perform the initialization.
0202    */
0203   Energy initializePhaseSpace(bool init, tcDecayIntegratorPtr decayer,
0204                   bool onShell=false);
0205 
0206   /**
0207    *   The incoming particles
0208    */
0209   pair<PDPtr,PDPtr> incoming() const {return incoming_;}
0210   
0211   /**
0212    * Access to the outging particles.
0213    * @return A pointer to the ParticleData object.
0214    */
0215   tPDVector outgoing() const {return outgoing_;}
0216   
0217   /**
0218    * Access to the outging particles.
0219    * @return A pointer to the ParticleData object.
0220    */
0221   tPDVector outgoingCC() const {return outgoingCC_;}
0222 
0223   /**
0224    * Number of outgoing particles.
0225    * @return The number of outgoing particles.
0226    */
0227   unsigned int numberOfParticles() const {return outgoing_.size();}
0228 
0229   /**
0230    * Set the partial width to use for normalization. This is the partial width
0231    * in the WidthGenerator object.
0232    * @param in The partial width to use.
0233    */
0234   void setPartialWidth(int in) {partial_=in;}
0235   
0236   /**
0237    *  Access to the epsilon parameter
0238    */
0239   Energy epsilonPS() const {return eps_;}
0240   
0241   /**
0242    *   Fill the stack
0243    */
0244   void fillStack(const double * r) {
0245     assert(rStack_.empty());
0246     for(unsigned int ix=nRand_;ix>0;--ix)
0247       rStack_.push(r[nRand_-1]);
0248   }
0249 
0250   /**
0251    *   Fill the stack
0252    */
0253   void fillStack() {
0254     assert(rStack_.empty());
0255     for(unsigned int ix=0;ix<nRand_;++ix) rStack_.push(UseRandom::rnd());
0256   }
0257 
0258   /**
0259    * Return the weight for a given phase-space point.
0260    * @param in The momentum of the incoming particle
0261    * @param momenta The momenta of the outgoing particles
0262    * @param onShell Whether or not to force the intermediates to be on-shell 
0263    * @return The weight.
0264    */
0265   Energy weight(int & ichan, const Lorentz5Momentum & in,
0266         vector<Lorentz5Momentum> & momenta,
0267         bool onShell=false) const {
0268     ichan=0;
0269     // flat phase-space
0270     if(channels_.empty())
0271       return flatPhaseSpace(in,momenta,onShell);
0272     // multi-channel
0273     else
0274       return channelPhaseSpace(ichan,in,momenta,onShell);
0275   }
0276 
0277 public :
0278 
0279   /**
0280    * A friend operator to allow the mode to be outputted for debugging purposes.
0281    */
0282   friend ostream & operator<<(ostream & os, const PhaseSpaceMode & mode) {
0283     os << "The mode has " << mode.channels_.size() << " channels\n";
0284     if(mode.incoming_.second==PDPtr())
0285       os << "This is a mode for the decay of " << mode.incoming_.first->PDGName() << " to ";
0286     else
0287       os << "This is a mode for " << mode.incoming_.first->PDGName() << ", "
0288      << mode.incoming_.second->PDGName() << " to ";
0289     for(tPDPtr out : mode.outgoing_) os << out->PDGName() << " ";
0290     os << "\n";
0291     for(const PhaseSpaceChannel & channel : mode.channels_) os << channel;
0292     return os;
0293   }
0294 
0295 private: 
0296     
0297   /**
0298    * Return the weight and momenta for a flat phase-space decay.
0299    * @param in The momentum of the incoming particle
0300    * @param momenta The momenta of the outgoing particles
0301    * @param onShell Whether or not to force the intermediates to be on-shell 
0302    * @return The weight.
0303    */
0304   Energy flatPhaseSpace(const Lorentz5Momentum & in,
0305             vector<Lorentz5Momentum> & momenta,
0306             bool onShell=false) const;
0307   
0308   /**
0309    * Generate a phase-space point using multichannel phase space.
0310    * @param ichan The channel to use
0311    * @param in The momentum of the incoming particle
0312    * @param momenta The momenta of the outgoing particles
0313    * @param onShell Whether or not to force the intermediates to be on-shell 
0314    * @return The weight.
0315    */
0316   Energy channelPhaseSpace(int & ichan, const Lorentz5Momentum & in,
0317                vector<Lorentz5Momentum> & momenta,
0318                bool onShell=false) const;
0319 
0320   /**
0321    * Generate the masses of the external particles.
0322    * @param inmass The mass of the decaying particle.
0323    * @param wgt The weight for the masses.
0324    * @return The masses.
0325    */
0326   vector<Energy> externalMasses(Energy inmass,double & wgt, bool onShell) const;
0327 
0328   /**
0329    * Construct the vertex for spin corrections
0330    * @param in The incoming particle.
0331    * @param out The outgoing particles.
0332    */
0333   void constructVertex(const Particle & in, const ParticleVector & out,
0334                tcDecayIntegratorPtr decayer) const;
0335   
0336 private:
0337 
0338   /**
0339    * The assignment operator is private and must never be called.
0340    * In fact, it should not even be implemented.
0341    */
0342   PhaseSpaceMode & operator=(const PhaseSpaceMode &) = delete;
0343 
0344 private:
0345 
0346   /**
0347    *  The incoming particles
0348    */
0349   pair<PDPtr,PDPtr> incoming_;
0350 
0351   /**
0352    *  The phase-space channels
0353    */
0354   vector<PhaseSpaceChannel> channels_;
0355 
0356   /**
0357    *  The maximum weight
0358    */
0359   mutable double maxWeight_;
0360 
0361   /**
0362    *  The external particles
0363    */
0364   tPDVector outgoing_;
0365   tPDVector outgoingCC_;
0366 
0367   /**
0368    * Which of the partial widths of the incoming particle to use
0369    */
0370   int partial_;
0371 
0372   /**
0373    * The width generator for the incoming particle.
0374    */
0375   cGenericWidthGeneratorPtr widthGen_;
0376 
0377   /**
0378    *  The mass generators for the outgoing particles.
0379    */
0380   vector<cGenericMassGeneratorPtr> massGen_;
0381   vector<double> BRsum_;
0382   /**
0383    *  Whether to check on-shell or off-shell kinematics
0384    * in doinit, if on-shell off-shell is tested in initrun
0385    */
0386   bool testOnShell_;
0387 
0388   /**
0389    *   The maximum energy for the mode
0390    */
0391   Energy eMax_;
0392 
0393   /**
0394    *  The selected channel
0395    */
0396   mutable unsigned int iChannel_;
0397 
0398   /**
0399    *   Cut-off
0400    */
0401   Energy eps_;
0402 
0403   /**
0404    *   Number of random numbers required
0405    */
0406   unsigned int nRand_;
0407 
0408   /**
0409    *   Stack for the random numbers
0410    */
0411   mutable stack<double> rStack_;
0412 };
0413 
0414 }
0415 
0416 #endif /* Herwig_PhaseSpaceMode_H */