Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // DipoleSplittingKinematics.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_DipoleSplittingKinematics_H
0010 #define HERWIG_DipoleSplittingKinematics_H
0011 //
0012 // This is the declaration of the DipoleSplittingKinematics class.
0013 //
0014 
0015 #include "ThePEG/Handlers/HandlerBase.h"
0016 #include "ThePEG/Vectors/Lorentz5Vector.h"
0017 
0018 #include "ThePEG/EventRecord/Particle.h"
0019 #include "ThePEG/Utilities/UtilityBase.h"
0020 
0021 #include "Herwig/Shower/Dipole/Utility/DipoleMCCheck.h"
0022 
0023 namespace Herwig {
0024 
0025   using namespace ThePEG;
0026 
0027   class DipoleIndex;
0028   class DipoleSplittingInfo;
0029   class DipoleSplittingKernel;
0030 
0031   /**
0032    * \ingroup DipoleShower
0033    * \author Simon Platzer
0034    *
0035    * \brief DipoleSplittingKinematics is the base class for dipole splittings
0036    * as performed in the dipole shower.
0037    *
0038    * @see \ref DipoleSplittingKinematicsInterfaces "The interfaces"
0039    * defined for DipoleSplittingKinematics.
0040    */
0041   class DipoleSplittingKinematics: public HandlerBase {
0042 
0043   public:
0044 
0045     /**
0046      * The default constructor.
0047      */
0048     DipoleSplittingKinematics();
0049 
0050   public:
0051 
0052     /**
0053      * Return the boundaries in between the evolution
0054      * variable random number is to be sampled; the lower
0055      * cuoff is assumed to correspond to the infrared cutoff.
0056      */
0057     virtual pair<double,double> kappaSupport(const DipoleSplittingInfo&) const {
0058       return {0.0,1.0};
0059     }
0060 
0061     /**
0062      * Return the boundaries in between the momentum
0063      * fraction random number is to be sampled.
0064      */
0065     virtual pair<double,double> xiSupport(const DipoleSplittingInfo&) const {
0066       return {0.0,1.0};
0067     }
0068 
0069     /**
0070      * Return the dipole scale associated to the
0071      * given pair of emitter and spectator. This
0072      * should be the invariant mass or absolute value
0073      * final/final or initial/initial and the absolute
0074      * value of the momentum transfer for intial/final or
0075      * final/initial dipoles.
0076      */
0077     virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
0078                    const Lorentz5Momentum& pSpectator) const {
0079     // MEMinBias produces non-zero zeros.
0080       if(abs(pEmitter*pSpectator)<0.0000001*GeV2)return ZERO;
0081       assert(pEmitter*pSpectator >= ZERO);
0082       return sqrt(2.*pEmitter*pSpectator);
0083     }
0084 
0085     /**
0086      * Return the mass of the system absorbing 
0087      * the recoil in the dipole splitting. 
0088      * This is overloaded in the decay dipoles.
0089      */
0090     virtual Energy recoilMassKin(const Lorentz5Momentum&,
0091                   const Lorentz5Momentum& pSpectator) const {
0092       return pSpectator.m();
0093     }
0094 
0095     /**
0096      * Return the maximum pt for the given dipole scale.
0097      */
0098     virtual Energy ptMax(Energy dScale, 
0099              double emX, double specX,
0100              const DipoleIndex& dIndex,
0101              const DipoleSplittingKernel& split) const =0;
0102 
0103     /**
0104      * Return the maximum pt for the given dipole scale.
0105      */
0106     virtual Energy ptMax(Energy dScale, 
0107              double emX, double specX,
0108              const DipoleSplittingInfo& dInfo,
0109              const DipoleSplittingKernel& split) const;
0110     
0111     /**
0112      * Return the maximum pt for the given dipole scale.
0113      */
0114     virtual Energy ptMax(Energy dScale, 
0115              double emX, double specX,
0116              const DipoleIndex& dIndex,
0117              const DipoleSplittingKernel& split,
0118              tPPtr emitter, tPPtr spectator) const; 
0119 
0120     /**
0121      * Return the maximum virtuality for the given dipole scale.
0122      */
0123     virtual Energy QMax(Energy dScale, 
0124             double emX, double specX,
0125             const DipoleIndex& dIndex,
0126             const DipoleSplittingKernel& split) const =0;
0127 
0128     /**
0129      * Return the maximum virtuality for the given dipole scale.
0130      */
0131     virtual Energy QMax(Energy dScale, 
0132             double emX, double specX,
0133             const DipoleSplittingInfo& dInfo,
0134             const DipoleSplittingKernel& split) const;
0135 
0136     /**
0137      * Return the maximum virtuality for the given dipole scale.
0138      */
0139     virtual Energy QMax(Energy dScale, 
0140             double emX, double specX,
0141             const DipoleIndex& dIndex,
0142             const DipoleSplittingKernel& split,
0143             tPPtr emitter, tPPtr spectator) const;
0144   
0145     /**
0146      * Return the pt given a virtuality.
0147      */
0148     virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const = 0;
0149 
0150     /**
0151      * Return the virtuality given a pt.
0152      */
0153     virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const = 0;
0154 
0155     /**
0156      * Return the infrared cutoff.
0157      */
0158     virtual Energy IRCutoff() const { return theIRCutoff; }
0159 
0160     /**
0161      * Return the minimum momentum fraction for
0162      * incoming partons
0163      */
0164     double xMin() const { return theXMin; }
0165 
0166     /**
0167      * Generate a pt
0168      */
0169     Energy generatePt(double r, Energy dScale,
0170               double emX, double specX,
0171               const DipoleIndex& dIndex,
0172               const DipoleSplittingKernel& split,
0173               double& weight) const;
0174 
0175     /**
0176      * Return the random number associated to
0177      * the given pt.
0178      */
0179     virtual double ptToRandom(Energy pt, Energy dScale,
0180                   double emX, double specX,
0181                   const DipoleIndex& dIndex,
0182                   const DipoleSplittingKernel& split) const;
0183 
0184     /**
0185      * Return the boundaries on the momentum fraction
0186      */
0187     virtual pair<double,double> zBoundaries(Energy pt,
0188                         const DipoleSplittingInfo& dInfo,
0189                         const DipoleSplittingKernel& split) const = 0;
0190 
0191     /**
0192      * Enumerate the variants of sampling z
0193      */
0194     enum ZSamplingOptions {
0195 
0196       FlatZ = 0,
0197       OneOverZ,
0198       OneOverOneMinusZ,
0199       OneOverZOneMinusZ
0200 
0201     };
0202 
0203     /**
0204      * Generate a z value flat
0205      */
0206     double generateZ(double r, Energy pt, int sampling,
0207              const DipoleSplittingInfo& dInfo,
0208              const DipoleSplittingKernel& split,
0209              double& weight) const;
0210 
0211     /**
0212      * Generate splitting variables given three random numbers
0213      * and the momentum fractions of the emitter and spectator.
0214      * Return true on success.
0215      */
0216     virtual bool generateSplitting(double kappa, double xi, double phi,
0217                    DipoleSplittingInfo& info,
0218                    const DipoleSplittingKernel&) = 0;
0219 
0220     /**
0221      * Get the splitting phasespace weight associated to
0222      * the last call to generateSplitting. This is taken to
0223      * be the single particle phasespace times 16 \pi^2 divided
0224      * by the relevant propagator invariant.
0225      */
0226     double jacobian() const { return theJacobian; }
0227 
0228     /**
0229      * Return true, if this splitting kinematics
0230      * class is capable of delivering an overestimate
0231      * to the jacobian.
0232      */
0233     virtual bool haveOverestimate() const { return false; }
0234 
0235     /**
0236      * Return the overestimated jacobian for the
0237      * last generated parameters.
0238      */
0239     virtual double jacobianOverestimate() const { return -1.; }
0240 
0241     /**
0242      * Return the last generated pt
0243      */
0244     Energy lastPt() const { return theLastPt; }
0245 
0246     /**
0247      * Return the last generated momentum fraction.
0248      */
0249     double lastZ() const { return theLastZ; }
0250 
0251     /**
0252      * Return the last calculated zPrime for massive FF and decay dipoles.
0253      */
0254     
0255     // Do not need in current implementation,
0256     // using lastSplittingParameters instead.
0257     //double lastZPrime() const { return theLastZPrime; }
0258 
0259     /**
0260      * Return the last generated azimuthal angle.
0261      */
0262     double lastPhi() const { return theLastPhi; }
0263 
0264     /**
0265      * Return the momentum fraction, by which the emitter's
0266      * momentum fraction should be divided after the splitting.
0267      */
0268     double lastEmitterZ() const { return theLastEmitterZ; }
0269 
0270     /**
0271      * Return the momentum fraction, by which the spectator's
0272      * momentum fraction should be divided after the splitting.
0273      */
0274     double lastSpectatorZ() const { return theLastSpectatorZ; }
0275 
0276     /**
0277      * Return any additional parameters needed to
0278      * evaluate the splitting kernel or to generate the 
0279      * full splitting.
0280      */
0281     const vector<double>& lastSplittingParameters() const { return theLastSplittingParameters; }
0282 
0283     /**
0284      * Complete a DipoleSplittingInfo object with
0285      * the parameters generated by the last call to
0286      * generateSplitting()
0287      */
0288     void prepareSplitting(DipoleSplittingInfo& dInfo);
0289 
0290   public:
0291 
0292     /**
0293      * Generate the full kinematics given emitter and
0294      * spectator momentum and a previously completeted
0295      * DipoleSplittingInfo object.
0296      */
0297     virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
0298                     const Lorentz5Momentum& pSpectator,
0299                     const DipoleSplittingInfo& dInfo) = 0;
0300 
0301 
0302 
0303     /**
0304      * Return the emitter's momentum after the splitting.
0305      */
0306     const Lorentz5Momentum& lastEmitterMomentum() const { return theEmitterMomentum; }
0307 
0308     /**
0309      * Return the spectator's momentum after the splitting.
0310      */
0311     const Lorentz5Momentum& lastSpectatorMomentum() const { return theSpectatorMomentum; }
0312 
0313     /**
0314      * Return the emission's momentum.
0315      */
0316     const Lorentz5Momentum& lastEmissionMomentum() const { return theEmissionMomentum; }
0317 
0318     /*
0319      * Return true, if there is a transformation which should
0320      * be applied to all other final state particles except the ones
0321      * involved in the splitting after having performed the splitting.
0322      */
0323     virtual bool doesTransform () const { return false; }
0324 
0325     /**
0326      * Calculate and store a required Lorentz transformation
0327      **/
0328     virtual void setTransformation () {};
0329 
0330     /*
0331      * Use the Dipole scale instead of hardpt for z-boundaries.
0332      */
0333     int openZBoundaries() const { return theOpenZBoundaries; }
0334 
0335     /*
0336      * perform the transformation if required.
0337      */
0338     virtual void transform (PPtr&) {};
0339 
0340     /*
0341      * SW 30/01/2019: Test feature only, not for release.
0342      * Return true to only apply the transformation to non-coloured particles.
0343      * Note this requires careful handling in DipoleEventRecord
0344      */
0345     //virtual bool transformHardOnly() const { return false; }
0346     
0347     /**
0348      * SW 30/01/2019: Test feature only, not for release.
0349      * In II case use colourless particles only to absorb recoil
0350      */   
0351     //virtual void transformHard ( PPtr& ) {};
0352 
0353     /**
0354      * SW 30/01/2019: Used in DipoleEventRecord to prepare for 
0355      * transformHard, test feature only, not for release.
0356      * Add to splitRecoilMomentum for transformation
0357      */
0358     // void addToRecoilMom( const Lorentz5Momentum& mom ) {    
0359     //   Lorentz5Momentum newRecoilMom = splitRecoilMomentum() + mom;
0360     //   splitRecoilMomentum(newRecoilMom);
0361     // }
0362     
0363     /*
0364      * Return true if this splitting is of a dipole which contains
0365      * a decayed parton and requires the remnant to absorb the recoil.
0366      */
0367     virtual bool isDecay() const { return false; }
0368 
0369     /**
0370      * Perform the recoil in the case of a decayed parton
0371      */
0372     //virtual Lorentz5Momentum decayRecoil ( const Lorentz5Momentum& p, const int) { return p; }
0373 
0374     /**
0375      * Perform the recoil in the case of a decayed parton
0376      */
0377     virtual void decayRecoil ( PList& ) {};
0378 
0379     /**
0380      * Return the pVector, required for spin correlations.
0381      */
0382     virtual Lorentz5Momentum pVector(const Lorentz5Momentum& pEmitter,
0383                                      const Lorentz5Momentum&,
0384                                      const DipoleSplittingInfo&) const {
0385       return pEmitter;
0386     }
0387 
0388     /**
0389      * Return the nVector, required for spin correlations.
0390      */
0391     virtual Lorentz5Momentum nVector(const Lorentz5Momentum&,
0392                                      const Lorentz5Momentum& pSpectator,
0393                                      const DipoleSplittingInfo&) const {
0394       return pSpectator;
0395     }
0396 
0397  // {;}
0398 
0399   protected:
0400 
0401     /**
0402      * Calculate a transverse momentum for the given momenta,
0403      * invariant pt and azimuth.
0404      */
0405     Lorentz5Momentum getKt(const Lorentz5Momentum& p1,
0406                const Lorentz5Momentum& p2,
0407                Energy pt,
0408                double phi,
0409                bool spacelike = false) const;
0410 
0411     /**
0412      * Set the splitting phasespace weight associated to
0413      * the last call to generateSplitting. This is taken to
0414      * be the single particle phasespace times 16 \pi^2 divided
0415      * by the relevant propagator invariant.
0416      */
0417     void jacobian(double w) { theJacobian = w; }
0418 
0419     /**
0420      * Set the last generated pt
0421      */
0422     void lastPt(Energy p) { theLastPt = p; }
0423 
0424     /**
0425      * Set the last generated momentum fraction.
0426      */
0427     void lastZ(double z) { theLastZ = z; }
0428 
0429     /**
0430      * Set the last calculated zPrime for massive FF and decay dipoles.
0431      */
0432     // Do not need in current implementation,
0433     // using lastSplittingParameters instead.
0434     //void lastZPrime(double zPrime) { theLastZPrime = zPrime; }
0435 
0436     /**
0437      * Set the last generated azimuthal angle.
0438      */
0439     void lastPhi(double p) { theLastPhi = p; }
0440 
0441     /**
0442      * Set the momentum fraction, by which the emitter's
0443      * momentum fraction should be divided after the splitting.
0444      */
0445     void lastEmitterZ(double z) { theLastEmitterZ = z; }
0446 
0447     /**
0448      * Set the momentum fraction, by which the spectator's
0449      * momentum fraction should be divided after the splitting.
0450      */
0451     void lastSpectatorZ(double z) { theLastSpectatorZ = z; }
0452 
0453     /**
0454      * Access any additional parameters needed to
0455      * evaluate the splitting kernel or to generate the 
0456      * full splitting.
0457      */
0458     vector<double>& splittingParameters() { return theLastSplittingParameters; }
0459 
0460     /**
0461      * Set the emitter's momentum after the splitting.
0462      */
0463     void emitterMomentum(const Lorentz5Momentum& p) { theEmitterMomentum = p; }
0464 
0465     /**
0466      * Set the spectator's momentum after the splitting.
0467      */
0468     void spectatorMomentum(const Lorentz5Momentum& p) { theSpectatorMomentum = p; }
0469 
0470     /**
0471      * Set the emission's momentum.
0472      */
0473     void emissionMomentum(const Lorentz5Momentum& p) { theEmissionMomentum = p; }
0474 
0475     /**
0476      * Set the momentum of the recoil system after the splitting.
0477      */
0478     void splitRecoilMomentum( const Lorentz5Momentum& mom ) { theSplitRecoilMomentum = mom; }
0479     
0480     /**
0481      * Return the momentum of the recoil system after splitting.
0482      */
0483     const Lorentz5Momentum& splitRecoilMomentum() const { return theSplitRecoilMomentum; }
0484 
0485   public:
0486 
0487     /**
0488      * The standard Init function used to initialize the interfaces.
0489      * Called exactly once for each class by the class description system
0490      * before the main function starts or
0491      * when this class is dynamically loaded.
0492      */
0493     static void Init();
0494 
0495   public:
0496 
0497     /** @name Functions used by the persistent I/O system. */
0498     //@{
0499     /**
0500      * Function used to write out object persistently.
0501      * @param os the persistent output stream written to.
0502      */
0503     void persistentOutput(PersistentOStream & os) const;
0504 
0505     /**
0506      * Function used to read in object persistently.
0507      * @param is the persistent input stream read from.
0508      * @param version the version number of the object when written.
0509      */
0510     void persistentInput(PersistentIStream & is, int version);
0511     //@}
0512 
0513 
0514     // If needed, insert declarations of virtual function defined in the
0515     // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
0516 
0517   private:
0518 
0519     /**
0520      * The infrared cutoff associated to this
0521      * splitting kinematics.
0522      */
0523     Energy theIRCutoff;
0524 
0525     /**
0526      * The minimum momentum fraction for
0527      * incoming partons
0528      */
0529     double theXMin;
0530 
0531     /**
0532      * The last calculated splitting phase space weight.
0533      */
0534     double theJacobian;
0535 
0536     /**
0537      * The last generated pt
0538      */
0539     Energy theLastPt;
0540 
0541     /**
0542      * The last generated momentum fraction.
0543      */
0544     double theLastZ;
0545 
0546     /**
0547      * The last calculated zPrime required for massive FF
0548      * and decay kinematics dipoles.
0549      * zPrime := qi.nk / (qi+qj).nk (qj = emission momentum)
0550      */
0551     // Do not need in current implementation,
0552     // using lastSplittingParameters instead.
0553     //double theLastZPrime;
0554 
0555     /**
0556      * The last generated azimuthal angle.
0557      */
0558     double theLastPhi;
0559 
0560     /**
0561      * The momentum fraction, by which the emitter's
0562      * momentum fraction should be divided after the splitting.
0563      */
0564     double theLastEmitterZ;
0565 
0566     /**
0567      * The momentum fraction, by which the spectator's
0568      * momentum fraction should be divided after the splitting.
0569      */
0570     double theLastSpectatorZ;
0571 
0572     /**
0573      * Any additional parameters needed to
0574      * evaluate the splitting kernel or to generate the 
0575      * full splitting.
0576      */
0577     vector<double> theLastSplittingParameters;
0578 
0579     /**
0580      * The emitter's momentum after the splitting.
0581      */
0582     Lorentz5Momentum theEmitterMomentum;
0583 
0584     /**
0585      * The emission's momentum after the splitting.
0586      */
0587     Lorentz5Momentum theEmissionMomentum;
0588 
0589     /**
0590      * The spectator's momentum after the splitting.
0591      */
0592     Lorentz5Momentum theSpectatorMomentum;
0593 
0594     /**
0595      * The momentum of the recoil system after the splitting, 
0596      * used in decay dipole kinematics.
0597      */
0598     Lorentz5Momentum theSplitRecoilMomentum;
0599 
0600 
0601 
0602     int theOpenZBoundaries;
0603 
0604   protected:
0605 
0606     /**
0607      * Pointer to a check histogram object
0608      */
0609     Ptr<DipoleMCCheck>::ptr theMCCheck;
0610 
0611   private:
0612 
0613     /**
0614      * The static object used to initialize the description of this class.
0615      * Indicates that this is an abstract class.
0616      */
0617     static AbstractClassDescription<DipoleSplittingKinematics> initDipoleSplittingKinematics;
0618 
0619     /**
0620      * The assignment operator is private and must never be called.
0621      * In fact, it should not even be implemented.
0622      */
0623     DipoleSplittingKinematics & operator=(const DipoleSplittingKinematics &) = delete;
0624 
0625   };
0626 
0627 }
0628 
0629 #include "ThePEG/Utilities/ClassTraits.h"
0630 
0631 namespace ThePEG {
0632 
0633   /** @cond TRAITSPECIALIZATIONS */
0634 
0635   /** This template specialization informs ThePEG about the
0636    *  base classes of DipoleSplittingKinematics. */
0637   template <>
0638   struct BaseClassTrait<Herwig::DipoleSplittingKinematics,1> {
0639     /** Typedef of the first base class of DipoleSplittingKinematics. */
0640     typedef HandlerBase NthBase;
0641   };
0642 
0643   /** This template specialization informs ThePEG about the name of
0644    *  the DipoleSplittingKinematics class and the shared object where it is defined. */
0645   template <>
0646   struct ClassTraits<Herwig::DipoleSplittingKinematics>
0647     : public ClassTraitsBase<Herwig::DipoleSplittingKinematics> {
0648     /** Return a platform-independent class name */
0649     static string className() { return "Herwig::DipoleSplittingKinematics"; }
0650     /**
0651      * The name of a file containing the dynamic library where the class
0652      * DipoleSplittingKinematics is implemented. It may also include several, space-separated,
0653      * libraries if the class DipoleSplittingKinematics depends on other classes (base classes
0654      * excepted). In this case the listed libraries will be dynamically
0655      * linked in the order they are specified.
0656      */
0657     static string library() { return "HwDipoleShower.so"; }
0658   };
0659 
0660   /** @endcond */
0661 
0662 }
0663 
0664 #endif /* HERWIG_DipoleSplittingKinematics_H */