Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // MatchboxHybridAmplitude.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_MatchboxHybridAmplitude_H
0010 #define Herwig_MatchboxHybridAmplitude_H
0011 //
0012 // This is the declaration of the MatchboxHybridAmplitude class.
0013 //
0014 
0015 #include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
0016 
0017 namespace Herwig {
0018 
0019 using namespace ThePEG;
0020 
0021 /**
0022  * \ingroup Matchbox
0023  * \author Simon Platzer
0024  *
0025  * \brief MatchboxHybridAmplitude unifies two amplitude objects to
0026  * provide tree and one-loop matrix elements.
0027  *
0028  * @see \ref MatchboxHybridAmplitudeInterfaces "The interfaces"
0029  * defined for MatchboxHybridAmplitude.
0030  */
0031 class MatchboxHybridAmplitude: public Herwig::MatchboxAmplitude {
0032 
0033 public:
0034 
0035   /**
0036    * The default constructor.
0037    */
0038   MatchboxHybridAmplitude();
0039 
0040 public:
0041 
0042   /**
0043    * Return the amplitude object to provide tree-level amplitudes.
0044    */
0045   Ptr<MatchboxAmplitude>::tptr treeLevelAmplitude() const { return theTreeLevelAmplitude; }
0046 
0047   /**
0048    * Set the amplitude object to provide tree-level amplitudes.
0049    */
0050   void treeLevelAmplitude(Ptr<MatchboxAmplitude>::tptr amp) { theTreeLevelAmplitude = amp; }
0051 
0052   /**
0053    * Return the amplitude object to provide one-loop amplitudes.
0054    */
0055   virtual Ptr<MatchboxAmplitude>::tptr oneLoopAmplitude() const { return theOneLoopAmplitude; }
0056 
0057   /**
0058    * Set the amplitude object to provide one-loop amplitudes.
0059    */
0060   void oneLoopAmplitude(Ptr<MatchboxAmplitude>::tptr amp) { theOneLoopAmplitude = amp; }
0061 
0062   /**
0063    * Return true, if the two amplitude objects can be used in a
0064    * consistent way.
0065    */
0066   bool isConsistent() const;
0067 
0068 public:
0069 
0070   /** @name Subprocess information */
0071   //@{
0072 
0073   /**
0074    * Return true, if this amplitude can handle the given process.
0075    */
0076   virtual bool canHandle(const PDVector& p,
0077              Ptr<MatchboxFactory>::tptr f,
0078              bool virt) const;
0079 
0080   /**
0081    * Return the number of random numbers required to evaluate this
0082    * amplitude at a fixed phase space point.
0083    */
0084   virtual int nDimAdditional() const {
0085     if ( !oneLoopAmplitude() )
0086       return treeLevelAmplitude()->nDimAdditional();
0087     return
0088       treeLevelAmplitude()->nDimAdditional() ?
0089       treeLevelAmplitude()->nDimAdditional() :
0090       oneLoopAmplitude()->nDimAdditional();
0091   }
0092 
0093   /**
0094    * Return a ME instance appropriate for this amplitude and the given
0095    * subprocesses
0096    */
0097   virtual Ptr<MatchboxMEBase>::ptr makeME(const PDVector& p) const {
0098     return treeLevelAmplitude()->makeME(p);
0099   }
0100 
0101   /**
0102    * Set the (tree-level) order in \f$g_S\f$ in which this matrix
0103    * element should be evaluated.
0104    */
0105   virtual void orderInGs(unsigned int n) {
0106     treeLevelAmplitude()->orderInGs(n);
0107     if ( oneLoopAmplitude() )
0108       oneLoopAmplitude()->orderInGs(n);
0109   }
0110 
0111   /**
0112    * Return the (tree-level) order in \f$g_S\f$ in which this matrix
0113    * element is given.
0114    */
0115   virtual unsigned int orderInGs() const {
0116     return treeLevelAmplitude()->orderInGs();
0117   }
0118 
0119   /**
0120    * Set the (tree-level) order in \f$g_{EM}\f$ in which this matrix
0121    * element should be evaluated.
0122    */
0123   virtual void orderInGem(unsigned int n) {
0124     treeLevelAmplitude()->orderInGem(n);
0125     if ( oneLoopAmplitude() )
0126       oneLoopAmplitude()->orderInGem(n);
0127   }
0128 
0129   /**
0130    * Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
0131    * element is given.
0132    */
0133   virtual unsigned int orderInGem() const {
0134     return treeLevelAmplitude()->orderInGem();
0135   }
0136 
0137   /**
0138    * Return true, if this amplitude already includes averaging over
0139    * incoming parton's quantum numbers.
0140    */
0141   virtual bool hasInitialAverage() const { 
0142     return treeLevelAmplitude()->hasInitialAverage();
0143   }
0144 
0145   /**
0146    * Return true, if this amplitude already includes symmetry factors
0147    * for identical outgoing particles.
0148    */
0149   virtual bool hasFinalStateSymmetry() const {
0150     return treeLevelAmplitude()->hasFinalStateSymmetry();
0151   }
0152 
0153   /**
0154    * Return true, if this amplitude is handled by a BLHA one-loop provider
0155    */
0156   virtual bool isOLPTree() const { return false; }
0157 
0158   /**
0159    * Return true, if this amplitude is handled by a BLHA one-loop provider
0160    */
0161   virtual bool isOLPLoop() const { 
0162     if ( !oneLoopAmplitude() )
0163       return false;
0164     return oneLoopAmplitude()->isOLPLoop();
0165   }
0166 
0167   /**
0168    * Return true, if colour and spin correlated matrix elements should
0169    * be ordered from the OLP
0170    */
0171   virtual bool needsOLPCorrelators() const { 
0172     return theUseOLPCorrelators;
0173   }
0174 
0175   /**
0176    * Start the one loop provider, if appropriate. This default
0177    * implementation writes an BLHA 2.0 order file and starts the OLP
0178    */
0179   virtual bool startOLP(const map<pair<Process,int>,int>& procs) {
0180     assert(oneLoopAmplitude());
0181     return oneLoopAmplitude()->startOLP(procs);
0182   }
0183 
0184   /**
0185    * Return true, if this amplitude needs to initialize an external
0186    * code.
0187    */
0188   virtual bool isExternal() const { 
0189     return treeLevelAmplitude()->isExternal();
0190   }
0191 
0192   /**
0193    * Initialize this amplitude
0194    */
0195   virtual bool initializeExternal() {
0196     return treeLevelAmplitude()->initializeExternal();
0197   }
0198 
0199   /**
0200    * Return a generic process id for the given process
0201    */
0202   virtual int externalId(const cPDVector& proc) { 
0203     return treeLevelAmplitude()->externalId(proc);
0204   }
0205 
0206   //@}
0207 
0208   /** @name Colour basis. */
0209   //@{
0210 
0211   /**
0212    * Return the colour basis.
0213    */
0214   virtual Ptr<ColourBasis>::tptr colourBasis() const { 
0215     return treeLevelAmplitude()->colourBasis();
0216   }
0217 
0218   /**
0219    * Return true, if the colour basis is capable of assigning colour
0220    * flows.
0221    */
0222   virtual bool haveColourFlows() const { 
0223     return treeLevelAmplitude()->haveColourFlows();
0224   }
0225 
0226   /**
0227    * Return a Selector with possible colour geometries for the selected
0228    * diagram weighted by their relative probabilities.
0229    */
0230   virtual Selector<const ColourLines *> colourGeometries(tcDiagPtr diag) const {
0231     return treeLevelAmplitude()->colourGeometries(diag);
0232   }
0233 
0234   //@}
0235 
0236   /** @name Phasespace point, crossing and helicities */
0237   //@{
0238 
0239   /**
0240    * Set the xcomb object.
0241    */
0242   virtual void setXComb(tStdXCombPtr xc) {
0243     treeLevelAmplitude()->setXComb(xc);
0244     if ( oneLoopAmplitude() )
0245       oneLoopAmplitude()->setXComb(xc);
0246     lastMatchboxXComb(xc);
0247   }
0248 
0249   /**
0250    * Perform a normal ordering of external legs and fill the
0251    * crossing information as. This default implementation sorts
0252    * lexicographically in (abs(colour)/spin/abs(charge)), putting pairs
0253    * of particles/anti-particles where possible.
0254    */
0255   virtual void fillCrossingMap(size_t shift = 0) {
0256     treeLevelAmplitude()->fillCrossingMap(shift);
0257   }
0258 
0259   //@}
0260 
0261   /** @name Tree-level amplitudes */
0262   //@{
0263 
0264   /**
0265    * Calculate the tree level amplitudes for the phasespace point
0266    * stored in lastXComb.
0267    */
0268   virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
0269 
0270   /**
0271    * Return the matrix element squared.
0272    */
0273   virtual double me2() const {
0274     return treeLevelAmplitude()->me2();
0275   }
0276 
0277   /**
0278    * Return the largeN matrix element squared.
0279    */
0280   virtual double largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const {
0281     return treeLevelAmplitude()->largeNME2(largeNBasis);
0282   }
0283 
0284   /**
0285    * Return the colour correlated matrix element.
0286    */
0287   virtual double colourCorrelatedME2(pair<int,int> ij) const {
0288     return 
0289       theUseOLPCorrelators ?
0290       oneLoopAmplitude()->colourCorrelatedME2(ij) :
0291       treeLevelAmplitude()->colourCorrelatedME2(ij);
0292   }
0293 
0294   /**
0295    * Return the large-N colour correlated matrix element.
0296    */
0297   virtual double largeNColourCorrelatedME2(pair<int,int> ij,
0298                        Ptr<ColourBasis>::tptr largeNBasis) const {
0299     return treeLevelAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis);
0300   }
0301 
0302   /**
0303    * Return a positive helicity polarization vector for a gluon of
0304    * momentum p (with reference vector n) to be used when evaluating
0305    * spin correlations.
0306    */
0307   virtual LorentzVector<Complex> plusPolarization(const Lorentz5Momentum& p,
0308                           const Lorentz5Momentum& n,
0309                           int id = -1) const {
0310     return 
0311       theUseOLPCorrelators ?
0312       oneLoopAmplitude()->plusPolarization(p,n,id) :
0313       treeLevelAmplitude()->plusPolarization(p,n,id);
0314   }
0315 
0316   /**
0317    * Return the colour and spin correlated matrix element.
0318    */
0319   virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator,
0320                      const SpinCorrelationTensor& c) const {
0321     return 
0322       theUseOLPCorrelators ?
0323       oneLoopAmplitude()->spinColourCorrelatedME2(emitterSpectator,c) :
0324       treeLevelAmplitude()->spinColourCorrelatedME2(emitterSpectator,c);
0325   }
0326 
0327   /**
0328    * Return the spin correlated matrix element.
0329    */
0330   virtual double spinCorrelatedME2(pair<int,int> emitterSpectator,
0331                    const SpinCorrelationTensor& c) const {
0332     return 
0333       theUseOLPCorrelators ?
0334       oneLoopAmplitude()->spinCorrelatedME2(emitterSpectator,c) :
0335       treeLevelAmplitude()->spinCorrelatedME2(emitterSpectator,c);
0336   }
0337 
0338   /**
0339    * Return true, if this amplitude is capable of consistently filling
0340    * the rho matrices for the spin correllations
0341    */
0342   virtual bool canFillRhoMatrix() const { 
0343     return treeLevelAmplitude()->canFillRhoMatrix();
0344   }
0345 
0346   /**
0347    * Return the helicity combination of the physical process in the
0348    * conventions used by the spin correlation algorithm.
0349    */
0350   virtual vector<unsigned int> physicalHelicities(const vector<int>& hel) const {
0351     return treeLevelAmplitude()->physicalHelicities(hel);
0352   }
0353 
0354   /**
0355    * Return true, if tree-level contributions will be evaluated at amplitude level.
0356    */
0357   virtual bool treeAmplitudes() const { 
0358     return treeLevelAmplitude()->treeAmplitudes();
0359   }
0360 
0361   /**
0362    * Evaluate the amplitude for the given colour tensor id and
0363    * helicity assignment
0364    */
0365   virtual Complex evaluate(size_t a, const vector<int>& hel, Complex& largeN) { 
0366     return treeLevelAmplitude()->evaluate(a,hel,largeN);
0367   }
0368 
0369   //@}
0370 
0371   /** @name One-loop amplitudes */
0372   //@{
0373 
0374   /**
0375    * Diasble one-loop functionality if not needed.
0376    */
0377   virtual void disableOneLoop() { oneLoopAmplitude(Ptr<MatchboxAmplitude>::ptr()); }
0378 
0379   /**
0380    * Return true, if this amplitude is capable of calculating one-loop
0381    * (QCD) corrections.
0382    */
0383   virtual bool haveOneLoop() const { return oneLoopAmplitude(); }
0384 
0385   /**
0386    * Return true, if this amplitude only provides
0387    * one-loop (QCD) corrections.
0388    */
0389   virtual bool onlyOneLoop() const { return false; }
0390 
0391   /**
0392    * Return true, if one-loop contributions will be evaluated at amplitude level.
0393    */
0394   virtual bool oneLoopAmplitudes() const { 
0395     assert(oneLoopAmplitude());
0396     return oneLoopAmplitude()->oneLoopAmplitudes();
0397   }
0398 
0399   /**
0400    * Return true, if the amplitude is DRbar renormalized, otherwise
0401    * MSbar is assumed.
0402    */
0403   virtual bool isDRbar() const { 
0404     assert(oneLoopAmplitude());
0405     return oneLoopAmplitude()->isDRbar();
0406   }
0407 
0408   /**
0409    * Return true, if one loop corrections have been calculated in
0410    * dimensional reduction. Otherwise conventional dimensional
0411    * regularization is assumed. Note that renormalization is always
0412    * assumed to be MSbar.
0413    */
0414   virtual bool isDR() const { 
0415     assert(oneLoopAmplitude());
0416     return oneLoopAmplitude()->isDR();
0417   }
0418 
0419   /**
0420    * Return true, if one loop corrections are given in the conventions
0421    * of the integrated dipoles.
0422    */
0423   virtual bool isCS() const { 
0424     assert(oneLoopAmplitude());
0425     return oneLoopAmplitude()->isCS();
0426   }
0427 
0428   /**
0429    * Return true, if one loop corrections are given in the conventions
0430    * of BDK.
0431    */
0432   virtual bool isBDK() const { 
0433     assert(oneLoopAmplitude());
0434     return oneLoopAmplitude()->isBDK();
0435   }
0436 
0437   /**
0438    * Return true, if one loop corrections are given in the conventions
0439    * of everything expanded.
0440    */
0441   virtual bool isExpanded() const { 
0442     assert(oneLoopAmplitude());
0443     return oneLoopAmplitude()->isExpanded();
0444   }
0445 
0446   /**
0447    * Return the value of the dimensional regularization
0448    * parameter. Note that renormalization scale dependence is fully
0449    * restored in DipoleIOperator.
0450    */
0451   virtual Energy2 mu2() const {
0452     assert(oneLoopAmplitude()); 
0453     return oneLoopAmplitude()->mu2();
0454   }
0455 
0456   /**
0457    * Adjust the virtual symmetry factor conventions to the tree level
0458    * one
0459    */
0460   double symmetryRatio() const;
0461 
0462   /**
0463    * Indicate that this amplitude is running alphas by itself.
0464    */
0465   virtual bool hasRunningAlphaS() const { 
0466     return treeLevelAmplitude()->hasRunningAlphaS();
0467   }
0468 
0469   /**
0470    * Indicate that this amplitude is running alphaew by itself.
0471    */
0472   virtual bool hasRunningAlphaEW() const { 
0473     return treeLevelAmplitude()->hasRunningAlphaEW();
0474   }
0475 
0476   /**
0477    * If defined, return the coefficient of the pole in epsilon^2
0478    */
0479   virtual double oneLoopDoublePole() const { 
0480     assert(oneLoopAmplitude());
0481     return symmetryRatio()*oneLoopAmplitude()->oneLoopDoublePole();
0482   }
0483 
0484   /**
0485    * If defined, return the coefficient of the pole in epsilon
0486    */
0487   virtual double oneLoopSinglePole() const { 
0488     assert(oneLoopAmplitude());
0489     return symmetryRatio()*oneLoopAmplitude()->oneLoopSinglePole();
0490   }
0491 
0492   /**
0493    * Calculate the one-loop amplitudes for the phasespace point
0494    * stored in lastXComb, if provided.
0495    */
0496   virtual void prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr);
0497 
0498   /**
0499    * Return the one-loop/tree interference.
0500    */
0501   virtual double oneLoopInterference() const {
0502     assert(oneLoopAmplitude());
0503     return symmetryRatio()*oneLoopAmplitude()->oneLoopInterference();
0504   }
0505 
0506   /**
0507    * Evaluate the amplitude for the given colour tensor id and
0508    * helicity assignment
0509    */
0510   virtual Complex evaluateOneLoop(size_t a, const vector<int>& hel) { 
0511     assert(oneLoopAmplitude());
0512     return oneLoopAmplitude()->evaluateOneLoop(a,hel);
0513   }
0514 
0515   //@}
0516 
0517   /** @name Caching and helpers to setup amplitude objects. */
0518   //@{
0519 
0520   /**
0521    * Flush all cashes.
0522    */
0523   virtual void flushCaches() {
0524     treeLevelAmplitude()->flushCaches();
0525     if ( oneLoopAmplitude() )
0526       oneLoopAmplitude()->flushCaches();
0527   }
0528 
0529   /**
0530    * Clone the dependencies, using a given prefix.
0531    */
0532   virtual void cloneDependencies(const std::string& prefix= "" , bool slim=false);
0533   //@}
0534 
0535 protected:
0536 
0537   /** @name Standard Interfaced functions. */
0538   //@{
0539 
0540   /**
0541    * Initialize this object after the setup phase before saving an
0542    * EventGenerator to disk.
0543    * @throws InitException if object could not be initialized properly.
0544    */
0545   virtual void doinit();
0546 
0547   /**
0548    * Initialize this object. Called in the run phase just before
0549    * a run begins.
0550    */
0551   virtual void doinitrun();
0552   //@}
0553 
0554 public:
0555 
0556   /** @name Functions used by the persistent I/O system. */
0557   //@{
0558   /**
0559    * Function used to write out object persistently.
0560    * @param os the persistent output stream written to.
0561    */
0562   void persistentOutput(PersistentOStream & os) const;
0563 
0564   /**
0565    * Function used to read in object persistently.
0566    * @param is the persistent input stream read from.
0567    * @param version the version number of the object when written.
0568    */
0569   void persistentInput(PersistentIStream & is, int version);
0570   //@}
0571 
0572   /**
0573    * The standard Init function used to initialize the interfaces.
0574    * Called exactly once for each class by the class description system
0575    * before the main function starts or
0576    * when this class is dynamically loaded.
0577    */
0578   static void Init();
0579 
0580 protected:
0581 
0582   /** @name Clone Methods. */
0583   //@{
0584   /**
0585    * Make a simple clone of this object.
0586    * @return a pointer to the new object.
0587    */
0588   virtual IBPtr clone() const;
0589 
0590   /** Make a clone of this object, possibly modifying the cloned object
0591    * to make it sane.
0592    * @return a pointer to the new object.
0593    */
0594   virtual IBPtr fullclone() const;
0595   //@}
0596 
0597 
0598 // If needed, insert declarations of virtual function defined in the
0599 // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
0600 
0601 
0602 private:
0603 
0604   /**
0605    * The amplitude object to provide tree-level amplitudes.
0606    */
0607   Ptr<MatchboxAmplitude>::ptr theTreeLevelAmplitude;
0608 
0609   /**
0610    * The amplitude object to provide one-loop amplitudes.
0611    */
0612   Ptr<MatchboxAmplitude>::ptr theOneLoopAmplitude;
0613 
0614   /**
0615    * True, if correlators should be used from the OLP amplitude
0616    */
0617   bool theUseOLPCorrelators;
0618 
0619   /**
0620    * The assignment operator is private and must never be called.
0621    * In fact, it should not even be implemented.
0622    */
0623   MatchboxHybridAmplitude & operator=(const MatchboxHybridAmplitude &) = delete;
0624 
0625 };
0626 
0627 }
0628 
0629 #endif /* Herwig_MatchboxHybridAmplitude_H */