Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // MPIHandler.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_MPIHandler_H
0010 #define HERWIG_MPIHandler_H
0011 //
0012 // This is the declaration of the MPIHandler class.
0013 //
0014 #include "ThePEG/Interface/Interfaced.h"
0015 #include "ThePEG/Handlers/StandardEventHandler.h"
0016 #include "ThePEG/Repository/EventGenerator.h"
0017 #include "Herwig/PDT/StandardMatchers.h"
0018 #include "Herwig/Utilities/GSLBisection.h"
0019 //#include "Herwig/Utilities/GSLMultiRoot.h"
0020 #include "Herwig/Utilities/GSLIntegrator.h"
0021 #include "Herwig/Shower/UEBase.h"
0022 
0023 #include <cassert>
0024 #include "ProcessHandler.h"
0025 #include "MPIHandler.fh"
0026 
0027 
0028 namespace Herwig {
0029 using namespace ThePEG;
0030 
0031   /** \ingroup UnderlyingEvent
0032    * \class MPIHandler
0033    * This class is responsible for generating additional 
0034    * semi hard partonic interactions.
0035    * 
0036    * \author Manuel B\"ahr
0037    *
0038    * @see \ref MPIHandlerInterfaces "The interfaces"
0039    * defined for MPIHandler.
0040    * @see ProcessHandler
0041    * @see ShowerHandler
0042    * @see HwRemDecayer
0043    */
0044 
0045 class MPIHandler: public UEBase {
0046 
0047   /**
0048    *  Maximum number of scatters
0049    */
0050   static const unsigned int maxScatters_ = 99;
0051 
0052   /**
0053    * Class for the integration is a friend to access private members
0054    */
0055   friend struct Eikonalization;
0056   friend struct TotalXSecBisection;
0057   friend struct slopeAndTotalXSec;
0058   friend struct slopeInt;
0059   friend struct slopeBisection;
0060 
0061 public:
0062 
0063   /** A vector of <code>SubProcessHandler</code>s. */
0064   typedef vector<SubHdlPtr> SubHandlerList;
0065 
0066   /** A vector of <code>Cut</code>s. */
0067   typedef vector<CutsPtr> CutsList;
0068 
0069   /** A vector of <code>ProcessHandler</code>s. */
0070   typedef vector<ProHdlPtr> ProcessHandlerList;
0071 
0072   /** A vector of cross sections. */
0073   typedef vector<CrossSection> XSVector;
0074 
0075   /** A pair of multiplicities: hard, soft. */
0076   typedef pair<unsigned int, unsigned int> MPair;
0077 
0078   /**
0079    * The default constructor.
0080    */
0081   MPIHandler(): softMult_(0), identicalToUE_(-1), 
0082         PtOfQCDProc_(-1.0*GeV), Ptmin_(-1.0*GeV), 
0083         hardXSec_(0*millibarn), softXSec_(0*millibarn), 
0084         totalXSecExp_(0*millibarn),
0085         softMu2_(ZERO), beta_(100.0/GeV2), 
0086         algorithm_(2), numSubProcs_(0), 
0087         colourDisrupt_(0.0), softInt_(true), twoComp_(true),
0088         DLmode_(2), avgNhard_(0.0), avgNsoft_(0.0),
0089                 energyExtrapolation_(3), EEparamA_(0.6*GeV),
0090                 EEparamB_(37.5*GeV), refScale_(7000.*GeV),
0091         pT0_(2.875*GeV), b_(0.3101), offset_(622.204*GeV) {}
0092 
0093 public:
0094 
0095   /** @name Methods for the MPI generation. */
0096   //@{
0097 
0098   /*
0099    * @return true if for this beam setup MPI can be generated
0100    */
0101   virtual bool beamOK() const;
0102 
0103   /**
0104    * Return true or false depending on whether soft interactions are enabled.
0105    */
0106   virtual bool softInt() const {return softInt_;}
0107 
0108   /**
0109    * Get the soft multiplicity from the pretabulated multiplicity
0110    * distribution. Generated in multiplicity in the first place.
0111    * @return the number of extra soft events in this collision
0112    */
0113   virtual unsigned int softMultiplicity() const {return softMult_;} 
0114 
0115   /**
0116    * Sample from the pretabulated multiplicity distribution.
0117    * @return the number of extra events in this collision
0118    */
0119   virtual unsigned int multiplicity(unsigned int sel=0); 
0120 
0121   /**
0122    * Select a StandardXComb according to it's weight
0123    * @return that StandardXComb Object
0124    * @param sel is the subprocess that should be returned,
0125    * if more than one is specified.
0126    */
0127   virtual tStdXCombPtr generate(unsigned int sel=0);
0128   //@}
0129 
0130 
0131   /** @name Functions used by the persistent I/O system. */
0132   //@{
0133   /**
0134    * Function used to write out object persistently.
0135    * @param os the persistent output stream written to.
0136    */
0137   void persistentOutput(PersistentOStream & os) const;
0138 
0139   /**
0140    * Function used to read in object persistently.
0141    * @param is the persistent input stream read from.
0142    * @param version the version number of the object when written.
0143    */
0144   void persistentInput(PersistentIStream & is, int version);
0145   //@}
0146 
0147   /**
0148    * The standard Init function used to initialize the interfaces.
0149    * Called exactly once for each class by the class description system
0150    * before the main function starts or
0151    * when this class is dynamically loaded.
0152    */
0153   static void Init();
0154 
0155   /**
0156    * Initialize this Multiple Interaction handler and all related objects needed to
0157    * generate additional events.
0158    */
0159   virtual void initialize();
0160 
0161   /**
0162    * Finalize this Multiple Interaction handler and all related objects needed to
0163    * generate additional events.
0164    */
0165   virtual void finalize();
0166 
0167   /**
0168    * Clean up the XCombs from our subprocesses after each event.
0169    * ThePEG cannot see them, so the usual cleaning misses these.
0170    */
0171   virtual void clean();
0172 
0173   /**
0174    * Write out accumulated statistics about integrated cross sections.
0175    */
0176   void statistics() const;
0177 
0178   /**
0179    * The level of statistics. Controlls the amount of statistics
0180    * written out after each run to the <code>EventGenerator</code>s
0181    * <code>.out</code> file. Simply the EventHandler method is called here.
0182    */
0183   int statLevel() const {return eventHandler()->statLevel();}
0184 
0185   /**
0186    * Return the hard cross section above ptmin
0187    */
0188   CrossSection hardXSec() const { return hardXSec_; }
0189 
0190   /**
0191    * Return the soft cross section below ptmin
0192    */
0193   CrossSection softXSec() const { return softXSec_; }
0194 
0195   /**
0196    * Return the inelastic cross section
0197    */
0198   CrossSection inelasticXSec() const { return inelXSec_; }
0199 
0200   /**
0201    * Return the non-diffractive cross section assumed by the model.
0202    * TODO: See comment at diffractiveXSec.
0203    */
0204   CrossSection nonDiffractiveXSec() const {
0205       return (1.-diffratio_)*inelXSec_;
0206   }
0207 
0208   /**
0209    * Return the diffractive cross section assumed by the model.
0210    * For now the diffractive cross section is seen as a fixed part of the
0211    * inelastic cross section. 
0212    * TODO: Energy dependence and/or Include diffraction in Eikonalisation.
0213    */
0214   CrossSection diffractiveXSec() const {
0215       return diffratio_*inelXSec_;
0216   }
0217 
0218 
0219   /** @name Simple access functions. */
0220   //@{
0221 
0222   /**
0223    * Return the ThePEG::EventHandler assigned to this handler.
0224    * This methods shadows ThePEG::StepHandler::eventHandler(), because
0225    * it is not virtual in ThePEG::StepHandler. This is ok, because this
0226    * method would give a null-pointer at some stages, whereas this method
0227    * gives access to the explicitely copied pointer (in initialize()) 
0228    * to the ThePEG::EventHandler.
0229    */
0230   tEHPtr eventHandler() const {return theHandler;}
0231 
0232   /**
0233    * Return the current handler
0234    */
0235   static const MPIHandler * currentHandler() {
0236     return currentHandler_;
0237   }
0238 
0239   /**
0240    * Return theAlgorithm.
0241    */
0242   virtual int Algorithm() const {return algorithm_;}
0243 
0244   /**
0245    * Return the ptmin parameter of the model
0246    */
0247   virtual Energy Ptmin() const {
0248     if(Ptmin_ > ZERO)
0249       return Ptmin_;
0250     else
0251       throw Exception() << "MPIHandler::Ptmin called without initialize before"
0252             << Exception::runerror;
0253   }
0254 
0255   /**
0256    * Return the slope of the soft pt spectrum as calculated.
0257    */
0258   virtual InvEnergy2 beta() const {
0259     if(beta_ != 100.0/GeV2)
0260       return beta_;
0261     else
0262       throw Exception() << "MPIHandler::beta called without initialization"
0263             << Exception::runerror;
0264   }
0265 
0266   /**
0267    * Return the pt Cutoff of the Interaction that is identical to the UE
0268    * one.
0269    */
0270   virtual Energy PtForVeto() const {return PtOfQCDProc_;}
0271   
0272   /**
0273    * Return the number of additional "hard" processes ( = multiple
0274    * parton scattering)
0275    */
0276   virtual unsigned int additionalHardProcs() const {return numSubProcs_-1;}
0277 
0278   /**
0279    * Return the fraction of colour disrupted connections to the
0280    * suprocesses.
0281    */
0282   virtual double colourDisrupt() const {return colourDisrupt_;}
0283 
0284 protected:
0285 
0286   /** @name Clone Methods. */
0287   //@{
0288   /**
0289    * Make a simple clone of this object.
0290    * @return a pointer to the new object.
0291    */
0292   virtual IBPtr clone() const;
0293 
0294   /** Make a clone of this object, possibly modifying the cloned object
0295    * to make it sane.
0296    * @return a pointer to the new object.
0297    */
0298   virtual IBPtr fullclone() const;
0299   //@}
0300 
0301 private:
0302 
0303   /**
0304    * Access the list of sub-process handlers.
0305    */
0306   const SubHandlerList & subProcesses() 
0307     const {return theSubProcesses;}
0308 
0309   /**
0310    * Access the list of sub-process handlers.
0311    */
0312   SubHandlerList & subProcesses() {return theSubProcesses;}
0313 
0314   /**
0315    * Access the list of cuts.
0316    */
0317   const CutsList & cuts() const {return theCuts;}
0318 
0319   /**
0320    * Access the list of cuts.
0321    */
0322   CutsList & cuts() {return theCuts;}
0323 
0324   /**
0325    * Access the list of sub-process handlers.
0326    */
0327   const ProcessHandlerList & processHandlers() 
0328     const {return theProcessHandlers;}
0329 
0330   /**
0331    * Access the list of sub-process handlers.
0332    */
0333   ProcessHandlerList & processHandlers() {return theProcessHandlers;}
0334 
0335 
0336   /**
0337    *  Method to calculate the individual probabilities for N scatters in the event.
0338    *  @param UEXSecs is(are) the inclusiv cross section(s) for the UE process(es).
0339    */
0340   void Probs(XSVector UEXSecs);
0341 
0342   /**
0343    * Debug method to check the individual probabilities.
0344    * @param filename is the file the output gets written to
0345    */
0346   void MultDistribution(string filename) const;
0347   
0348   /**
0349    * Return the value of the Overlap function A(b) for a given impact 
0350    * parameter \a b.
0351    *  @param b impact parameter
0352    *  @param mu2 = inv hadron radius squared. 0 will use the value of
0353    *  invRadius_
0354    *  @return inverse area.
0355    */
0356   InvArea OverlapFunction(Length b, Energy2 mu2=ZERO) const;
0357 
0358   /**
0359    * Method to calculate the poisson probability for expectation value
0360    * \f$<n> = A(b)\sigma\f$, and multiplicity N.
0361    */
0362   double poisson(Length b, CrossSection sigma, 
0363          unsigned int N, Energy2 mu2=ZERO) const;
0364 
0365   /**
0366    * Returns the total cross section for the current CMenergy.  The
0367    * decision which parametrization will be used is steered by a
0368    * external parameter of this class.
0369    */
0370   CrossSection totalXSecExp() const;
0371 
0372   /**
0373    * Difference of the calculated total cross section and the
0374    * experimental one from totalXSecExp.
0375    * @param softXSec = the soft cross section that is used
0376    * @param softMu2 = the soft radius, if 0 the hard radius will be used
0377    */
0378   CrossSection totalXSecDiff(CrossSection softXSec, 
0379                  Energy2 softMu2=ZERO) const;
0380 
0381   /**
0382    * Difference of the calculated elastic slope and the
0383    * experimental one from slopeExp.
0384    * @param softXSec = the soft cross section that is used
0385    * @param softMu2 = the soft radius, if 0 the hard radius will be used
0386    */
0387   InvEnergy2 slopeDiff(CrossSection softXSec, 
0388              Energy2 softMu2=ZERO) const;
0389 
0390   /**
0391    * Returns the value of the elastic slope for the current CMenergy.
0392    * The decision which parametrization will be used is steered by a
0393    * external parameter of this class.
0394    */
0395   InvEnergy2 slopeExp() const;
0396 
0397 
0398   /**
0399    * Calculate the minimal transverse momentum from the extrapolation
0400    */
0401   void overrideUECuts();
0402 
0403 
0404 private:
0405 
0406   /**
0407    * The assignment operator is private and must never be called.
0408    * In fact, it should not even be implemented.
0409    */
0410   MPIHandler & operator=(const MPIHandler &) = delete;
0411 
0412   /**
0413    * A pointer to the EventHandler that calls us. Has to be saved, because the
0414    * method eventHandler() inherited from ThePEG::StepHandler returns a null-pointer
0415    * sometimes. Leif changed that in r1053 so that a valid pointer is present, when
0416    * calling doinitrun().
0417    */
0418   tEHPtr theHandler;
0419 
0420   /**
0421    * The list of <code>SubProcessHandler</code>s.
0422    */
0423   SubHandlerList theSubProcesses;
0424 
0425   /**
0426    * The kinematical cuts used for this collision handler.
0427    */
0428   CutsList theCuts;
0429 
0430   /**
0431    * List of ProcessHandler used to sample different processes independently
0432    */
0433   ProcessHandlerList theProcessHandlers;
0434 
0435   /**
0436    * A ThePEG::Selector where the individual Probabilities P_N are stored
0437    * and the actual Multiplicities can be selected.
0438    */
0439   Selector<MPair> theMultiplicities;
0440 
0441   /**
0442    * Variable to store the soft multiplicity generated for a event. This
0443    * has to be stored as it is generated at the time of the hard
0444    * additional interactions but used later on.
0445    */
0446   unsigned int softMult_;
0447 
0448   /**
0449    * Variable to store the multiplicity of the second hard process
0450    */
0451   vector<int> additionalMultiplicities_;
0452 
0453   /**
0454    * Variable to store the information, which process is identical to
0455    * the UE one (QCD dijets).
0456    * 0 means "real" hard one
0457    * n>0 means the nth additional hard scatter
0458    * -1 means no one!
0459    */
0460   int identicalToUE_;
0461 
0462   /**
0463    * Variable to store the minimal pt of the process that is identical
0464    * to the UE one. This only has to be set, if it can't be determined
0465    * automatically (i.e. when reading QCD LesHouches files in).
0466    */
0467   Energy PtOfQCDProc_;
0468 
0469   /**
0470    * Variable to store the parameter ptmin
0471    */
0472   Energy Ptmin_;
0473 
0474   /**
0475    * Variable to store the hard cross section above ptmin
0476    */
0477   CrossSection hardXSec_;
0478 
0479   /**
0480    * Variable to store the final soft cross section below ptmin
0481    */
0482   CrossSection softXSec_;
0483 
0484   /**
0485    * Variable to store the inelastic cross section
0486    */
0487   CrossSection inelXSec_;
0488 
0489   /**
0490    * Variable to store the total pp cross section (assuming rho=0!) as
0491    * measured at LHC. If this variable is set, this value is used in the
0492    * subsequent run instead of any of the Donnachie-Landshoff
0493    * parametrizations.
0494    */
0495   CrossSection totalXSecExp_;
0496 
0497   /**
0498    * Variable to store the soft radius, that is calculated during
0499    * initialization for the two-component model.
0500    */
0501   Energy2 softMu2_;
0502 
0503   /**
0504    * slope to the non-perturbative pt spectrum: \f$d\sigma/dp_T^2 = A \exp
0505    * (- beta p_T^2)\f$. Its value is determined durint initialization.
0506    */
0507   InvEnergy2 beta_;
0508   /**
0509    * Switch to be set from outside to determine the algorithm used for 
0510    * UE activity.
0511    */
0512   int algorithm_;
0513 
0514   /**
0515    * Inverse hadron Radius squared \f$ (\mu^2) \f$. Used inside the overlap function.  
0516    */
0517   Energy2 invRadius_;
0518 
0519   /**
0520    * Member variable to store the actual number of separate SubProcesses
0521    */ 
0522   unsigned int numSubProcs_;
0523 
0524   /**
0525    * Variable to store the relative number of colour disrupted
0526    * connections to additional subprocesses. This variable is used in
0527    * Herwig::HwRemDecayer but store here, to have access to all
0528    * parameters through one Object.
0529    */
0530   double colourDisrupt_;
0531 
0532   /** 
0533    * Flag to store whether soft interactions, i.e. pt < ptmin should be
0534    * simulated.
0535    */
0536   bool softInt_;
0537 
0538   /** 
0539    * Flag to steer wheather the soft part has a different radius, that
0540    * will be dynamically fixed.
0541    */
0542   bool twoComp_;
0543   
0544   /**
0545    * Switch to determine which Donnachie & Landshoff parametrization
0546    * should be used.
0547    */
0548   unsigned int DLmode_;
0549 
0550   /**
0551    * Variable to store the average hard multiplicity.
0552    */
0553   double avgNhard_;
0554 
0555   /**
0556    * Variable to store the average soft multiplicity.
0557    */
0558   double avgNsoft_;
0559 
0560   /**
0561    * The current handler
0562    */
0563   static MPIHandler * currentHandler_;
0564 
0565   /**
0566    * Flag to store whether to calculate the minimal UE pt according to an
0567    * extrapolation formula or whether to use MPIHandler:Cuts[0]:OneCuts[0]:MinKT
0568    */
0569   unsigned int energyExtrapolation_;
0570 
0571   /**
0572    * Parameters for the energy extrapolation formula
0573    */
0574   Energy EEparamA_;
0575   Energy EEparamB_;
0576   Energy refScale_;
0577   Energy pT0_;
0578   double b_;
0579   Energy offset_;
0580 
0581   /**
0582    * Parameters to set the fraction of diffractive cross section in the inelastic cross section.
0583    */
0584   double diffratio_=0.2;
0585 
0586 protected:
0587 
0588   /** @cond EXCEPTIONCLASSES */
0589 
0590   /**
0591    * Exception class used by the MultipleInteractionHandler, when something
0592    * during initialization went wrong.
0593    * \todo understand!!!
0594    */
0595   class InitError: public Exception {};
0596 
0597   /** @endcond */
0598 
0599 };
0600 
0601 }
0602 
0603 namespace Herwig {
0604 
0605   /**
0606    * A struct for the 2D root finding that is necessary to determine the
0607    * soft cross section and the soft radius that is needed to describe
0608    * the total cross section correctly.
0609    * NOT IN USE CURRENTLY
0610    */
0611   struct slopeAndTotalXSec : public GSLHelper<CrossSection, CrossSection> {
0612 
0613   public:
0614 
0615     /**
0616      *  Constructor
0617      */
0618     slopeAndTotalXSec(tcMPIHPtr handler): handler_(handler) {}
0619 
0620     /** second argument type */
0621     typedef Energy2 ArgType2;
0622 
0623     /** second value type */
0624     typedef InvEnergy2 ValType2;
0625 
0626     /** first element of the vector like function to find root for 
0627      * @param softXSec soft cross-section
0628      * @param softMu2 \f$\mu^2\f$ 
0629      */
0630     CrossSection f1(ArgType softXSec, ArgType2 softMu2) const {
0631       return handler_->totalXSecDiff(softXSec, softMu2);
0632     }
0633 
0634     /** second element of the vector like function to find root for 
0635      * @param softXSec soft cross-section
0636      * @param softMu2 \f$\mu^2\f$ 
0637      */
0638     InvEnergy2 f2(ArgType softXSec, ArgType2 softMu2) const {
0639       return handler_->slopeDiff(softXSec, softMu2);
0640     }
0641 
0642     /** provide the actual units of use */
0643     virtual ValType vUnit() const {return 1.0*millibarn;}
0644     
0645     /** otherwise rounding errors may get significant */
0646     virtual ArgType aUnit() const {return 1.0*millibarn;}
0647 
0648     /** provide the actual units of use */
0649     ValType2 vUnit2() const {return 1.0/GeV2;}
0650     
0651     /** otherwise rounding errors may get significant */
0652     ArgType2 aUnit2() const {return GeV2;}
0653 
0654   private: 
0655 
0656     /**
0657      *  Pointer to the handler
0658      */
0659     tcMPIHPtr handler_;
0660 
0661   };
0662   
0663   /**
0664    * A struct for the root finding that is necessary to determine the
0665    * slope of the soft pt spectrum to match the soft cross section
0666    */
0667   struct betaBisection : public GSLHelper<Energy2, InvEnergy2>{
0668   public:
0669     /**
0670      * Constructor.
0671      * @param soft = soft cross section, i.e. the integral of the soft
0672      * pt spectrum f(u=p_T^2) = dsig exp(-beta*u/u_min)
0673      * @param dsig = dsigma_hard/dp_T^2 at the p_T cutoff
0674      * @param ptmin = p_T cutoff
0675      */
0676     betaBisection(CrossSection soft, DiffXSec dsig, Energy ptmin) 
0677       : softXSec_(soft), dsig_(dsig), ptmin_(ptmin) {}
0678    
0679     /**
0680      * Operator that is used inside the GSLBisection class
0681      */
0682     virtual Energy2 operator ()(InvEnergy2 beta) const
0683     {
0684       if( fabs(beta*GeV2) < 1.E-4 )
0685     beta = (beta > ZERO) ? 1.E-4/GeV2 : -1.E-4/GeV2;
0686 
0687       return (exp(beta*sqr(ptmin_)) - 1.0)/beta - softXSec_/dsig_;
0688     }
0689 
0690     /** provide the actual units of use */
0691     virtual ValType vUnit() const {return 1.0*GeV2;}
0692 
0693     /** provide the actual units of use */
0694     virtual ArgType aUnit() const {return 1.0/GeV2;}
0695 
0696   private: 
0697 
0698     /** soft cross section */
0699     CrossSection softXSec_;
0700 
0701     /** dsigma/dp_T^2 at ptmin */
0702     DiffXSec dsig_;
0703 
0704     /** pt cutoff */
0705     Energy ptmin_;
0706   };
0707 
0708   /**
0709    * A struct for the root finding that is necessary to determine the
0710    * soft cross section and soft mu2 that are needed to describe the
0711    * total cross section AND elastic slope correctly.
0712    */
0713   struct slopeBisection : public GSLHelper<InvEnergy2, Energy2> {
0714   public:
0715     /** Constructor */
0716     slopeBisection(tcMPIHPtr handler) : handler_(handler) {}
0717 
0718     /** 
0719      * Return the difference of the calculated elastic slope to the
0720      * experimental one for a given value of the soft mu2. During that,
0721      * the soft cross section get fixed.
0722      */
0723     InvEnergy2 operator ()(Energy2 arg) const;
0724     
0725     /** Return the soft cross section that has been calculated */
0726     CrossSection softXSec() const {return softXSec_;}
0727 
0728   private:
0729     /** const pointer to the MPIHandler to give access to member functions.*/
0730     tcMPIHPtr handler_;
0731     /** soft cross section that is determined on the fly.*/
0732     mutable CrossSection softXSec_;
0733   };
0734 
0735   /**
0736    * A struct for the root finding that is necessary to determine the
0737    * soft cross section that is needed to describe the total cross
0738    * section correctly.
0739    */
0740   struct TotalXSecBisection : public GSLHelper<CrossSection, CrossSection> {
0741   public:
0742 
0743     /**
0744      *  Constructor
0745      * @param handler The handler
0746      * @param softMu2 \f$\mu^2\f$
0747      */
0748     TotalXSecBisection(tcMPIHPtr handler, Energy2 softMu2=ZERO): 
0749       handler_(handler), softMu2_(softMu2) {}
0750 
0751     /**
0752      *  operator to return the cross section
0753      * @param argument input cross section
0754      */
0755     CrossSection operator ()(CrossSection argument) const {
0756       return handler_->totalXSecDiff(argument, softMu2_);
0757     }
0758 
0759     /** provide the actual units of use */
0760     virtual ValType vUnit() const {return 1.0*millibarn;}
0761     
0762     /** otherwise rounding errors may get significant */
0763     virtual ArgType aUnit() const {return 1.0*millibarn;}
0764 
0765   private: 
0766 
0767     /**
0768      *  The handler
0769      */
0770     tcMPIHPtr handler_;
0771 
0772     /**
0773      *  \f$\mu^2\f$
0774      */
0775     Energy2 softMu2_;
0776 
0777   };
0778 
0779   /**
0780    *  Typedef for derivative of the length
0781    */
0782   typedef decltype(mm/GeV2) LengthDiff;
0783 
0784   /**
0785    *  A struct for the integrand for the slope
0786    */
0787   struct slopeInt : public GSLHelper<LengthDiff, Length>{
0788 
0789   public:
0790     /** Constructor 
0791      * @param handler The handler
0792      * @param hard The hard cross section
0793      * @param soft The soft cross section
0794      * @param softMu2 \f$\mu^2\f$
0795      */
0796     slopeInt(tcMPIHPtr handler, CrossSection hard, 
0797           CrossSection soft=0*millibarn, Energy2 softMu2=ZERO)
0798       : handler_(handler), hardXSec_(hard), 
0799     softXSec_(soft), softMu2_(softMu2) {}
0800 
0801     /**
0802      *  Operator to return the answer
0803      * @param arg The argument
0804      */
0805     ValType operator ()(ArgType arg) const;
0806 
0807   private:
0808 
0809     /**
0810      * Pointer to the Handler that calls this integrand
0811      */
0812     tcMPIHPtr handler_;
0813 
0814     /**
0815      * The hard cross section to be eikonalized
0816      */
0817     CrossSection hardXSec_;
0818 
0819     /**
0820      * The soft cross section to be eikonalized. Default is zero
0821      */
0822     CrossSection softXSec_;
0823 
0824     /**
0825      * The inv radius^2 of the soft interactions.
0826      */
0827     Energy2 softMu2_;
0828 
0829   };
0830 
0831   /**
0832    * A struct for the eikonalization of the inclusive cross section. 
0833    */
0834   struct Eikonalization : public GSLHelper<Length, Length>{
0835 
0836     /**
0837      *  The constructor
0838      *  @param handler is the pointer to the MPIHandler to get access to 
0839      *  MPIHandler::OverlapFunction and member variables of the MPIHandler.
0840      *  @param option is a flag, whether the inelastic or the total 
0841      *  @param handler The handler
0842      *  @param hard The hard cross section
0843      *  @param soft The soft cross section
0844      *  @param softMu2 \f$\mu^2\f$
0845      *  cross section should be returned (-2 or -1). For option = N > 0 the integrand
0846      *  is N*(A(b)*sigma)^N/N! exp(-A(b)*sigma) this is the P_N*sigma where
0847      *  P_N is the Probability of having exactly N interaction (including the hard one)
0848      *  This is equation 14 from "Jimmy4: Multiparton Interactions in HERWIG for the LHC"
0849      */
0850     Eikonalization(tcMPIHPtr handler, int option, CrossSection hard, 
0851            CrossSection soft=0*millibarn, Energy2 softMu2=ZERO) 
0852       : theHandler(handler), theoption(option), hardXSec_(hard), 
0853     softXSec_(soft), softMu2_(softMu2) {}
0854 
0855     /**
0856      * Get the function value
0857      */
0858     Length operator ()(Length argument) const;
0859 
0860   private:
0861     /**
0862      * Pointer to the Handler that calls this integrand
0863      */
0864     tcMPIHPtr theHandler;
0865 
0866     /**
0867      * A flag to switch between the calculation of total and inelastic cross section
0868      * or calculations for the individual probabilities. See the constructor
0869      */
0870     int theoption;
0871 
0872     /**
0873      * The hard cross section to be eikonalized
0874      */
0875     CrossSection hardXSec_;
0876 
0877     /**
0878      * The soft cross section to be eikonalized. Default is zero
0879      */
0880     CrossSection softXSec_;
0881 
0882     /**
0883      * The inv radius^2 of the soft interactions.
0884      */
0885     Energy2 softMu2_;
0886 
0887   };
0888 }
0889 
0890 #endif /* HERWIG_MPIHandler_H */