--- /dev/null
+#-*- Mode: Makefile -*-
+
+SRCS:= \
+pythia8130/src/Analysis.cxx \
+pythia8130/src/Basics.cxx \
+pythia8130/src/BeamParticle.cxx \
+pythia8130/src/BeamRemnants.cxx \
+pythia8130/src/BeamShape.cxx \
+pythia8130/src/BoseEinstein.cxx \
+pythia8130/src/Event.cxx \
+pythia8130/src/FragmentationFlavZpT.cxx \
+pythia8130/src/FragmentationSystems.cxx \
+pythia8130/src/HadronLevel.cxx \
+pythia8130/src/Info.cxx \
+pythia8130/src/LesHouches.cxx \
+pythia8130/src/MiniStringFragmentation.cxx \
+pythia8130/src/MultipleInteractions.cxx \
+pythia8130/src/ParticleData.cxx \
+pythia8130/src/ParticleDecays.cxx \
+pythia8130/src/PartonDistributions.cxx \
+pythia8130/src/PartonLevel.cxx \
+pythia8130/src/PhaseSpace.cxx \
+pythia8130/src/ProcessContainer.cxx \
+pythia8130/src/ProcessLevel.cxx \
+pythia8130/src/Pythia.cxx \
+pythia8130/src/ResonanceDecays.cxx \
+pythia8130/src/ResonanceWidths.cxx \
+pythia8130/src/Settings.cxx \
+pythia8130/src/SigmaCompositeness.cxx \
+pythia8130/src/SigmaEW.cxx \
+pythia8130/src/SigmaExtraDim.cxx \
+pythia8130/src/SigmaHiggs.cxx \
+pythia8130/src/SigmaLeftRightSym.cxx \
+pythia8130/src/SigmaLeptoquark.cxx \
+pythia8130/src/SigmaNewGaugeBosons.cxx \
+pythia8130/src/SigmaOnia.cxx \
+pythia8130/src/SigmaProcess.cxx \
+pythia8130/src/SigmaQCD.cxx \
+pythia8130/src/SigmaSUSY.cxx \
+pythia8130/src/SigmaTotal.cxx \
+pythia8130/src/SpaceShower.cxx \
+pythia8130/src/StandardModel.cxx \
+pythia8130/src/StringFragmentation.cxx \
+pythia8130/src/SusyLesHouches.cxx \
+pythia8130/src/TimeShower.cxx \
+pythia8130/src/UserHooks.cxx
+
+EINCLUDE:= PYTHIA8/pythia8130/include
+ifeq (macosxicc,$(ALICE_TARGET))
+PACKFFLAGS := $(filter-out -O%,$(FFLAGS))
+endif
--- /dev/null
+// Analysis.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the Sphericity, Thrust, ClusterJet and CellJet classes.
+// Sphericity: sphericity analysis of the event.
+// Thrust: thrust analysis of the event.
+// ClusterJet: clustering jet finder.
+// CellJet: calorimetric cone jet finder.
+
+#ifndef Pythia8_Analysis_H
+#define Pythia8_Analysis_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "PythiaStdlib.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sphericity class.
+// This class performs (optionally modified) sphericity analysis on an event.
+
+class Sphericity {
+
+public:
+
+ // Constructor.
+ Sphericity(double powerIn = 2., int selectIn = 2) : power(powerIn),
+ select(selectIn), nFew(0), nBack(0) {powerInt = 0;
+ if (abs(power - 1.) < 0.01) powerInt = 1;
+ if (abs(power - 2.) < 0.01) powerInt = 2;
+ powerMod = 0.5 * power - 1.;}
+
+ // Analyze event.
+ bool analyze(const Event& event, ostream& os = cout);
+
+ // Return info on results of analysis.
+ double sphericity() const {return 1.5 * (eVal2 + eVal3);}
+ double aplanarity() const {return 1.5 * eVal3;}
+ double eigenValue(int i) const {return (i < 2) ? eVal1 :
+ ( (i < 3) ? eVal2 : eVal3 ) ;}
+ Vec4 eventAxis(int i) const {return (i < 2) ? eVec1 :
+ ( (i < 3) ? eVec2 : eVec3 ) ;}
+
+ // Provide a listing of the info.
+ void list(ostream& os = cout);
+
+ // Tell how many events could not be analyzed.
+ int nError() const {return nFew + nBack;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NSTUDYMIN, TIMESTOPRINT;
+ static const double P2MIN, EIGENVALUEMIN;
+
+ // Properties of analysis.
+ double power;
+ int select, powerInt;
+ double powerMod;
+
+ // Outcome of analysis.
+ double eVal1, eVal2, eVal3;
+ Vec4 eVec1, eVec2, eVec3;
+
+ // Error statistics;
+ int nFew, nBack;
+
+};
+
+//**************************************************************************
+
+// Thrust class.
+// This class performs thrust analysis on an event.
+
+class Thrust {
+
+public:
+
+ // Constructor.
+ Thrust(int selectIn = 2) : select(selectIn), nFew(0) {}
+
+ // Analyze event.
+ bool analyze(const Event& event, ostream& os = cout);
+
+ // Return info on results of analysis.
+ double thrust() const {return eVal1;}
+ double tMajor() const {return eVal2;}
+ double tMinor() const {return eVal3;}
+ double oblateness() const {return eVal2 - eVal3;}
+ Vec4 eventAxis(int i) const {return (i < 2) ? eVec1 :
+ ( (i < 3) ? eVec2 : eVec3 ) ;}
+
+ // Provide a listing of the info.
+ void list(ostream& os = cout);
+
+ // Tell how many events could not be analyzed.
+ int nError() const {return nFew;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NSTUDYMIN, TIMESTOPRINT;
+ static const double MAJORMIN;
+
+ // Properties of analysis.
+ int select;
+
+ // Outcome of analysis.
+ double eVal1, eVal2, eVal3;
+ Vec4 eVec1, eVec2, eVec3;
+
+ // Error statistics;
+ int nFew;
+
+};
+
+//**************************************************************************
+
+// SingleClusterJet class.
+// Simple helper class to ClusterJet for a jet and its contents.
+
+class SingleClusterJet {
+
+public:
+
+ // Constructors.
+ SingleClusterJet(Vec4 pJetIn = 0., int motherIn = 0) :
+ pJet(pJetIn), mother(motherIn), daughter(0), multiplicity(1),
+ isAssigned(false) {pAbs = max( PABSMIN, pJet.pAbs());}
+ SingleClusterJet& operator=(const SingleClusterJet& j) { if (this != &j)
+ { pJet = j.pJet; mother = j.mother; daughter = j.daughter;
+ multiplicity = j.multiplicity; pAbs = j.pAbs;
+ isAssigned = j.isAssigned;} return *this; }
+
+ // Properties of jet.
+ // Note: mother, daughter and isAssigned only used for original
+ // particles, multiplicity and pTemp only for reconstructed jets.
+ Vec4 pJet;
+ int mother, daughter, multiplicity;
+ bool isAssigned;
+ double pAbs;
+ Vec4 pTemp;
+
+ // Distance measures (Lund, JADE, Durham) with friend.
+ friend double dist2Fun(int measure, const SingleClusterJet& j1,
+ const SingleClusterJet& j2);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double PABSMIN;
+
+} ;
+
+//**************************************************************************
+
+// ClusterJet class.
+// This class performs a jet clustering according to different
+// distance measures: Lund, JADE or Durham.
+
+class ClusterJet {
+
+public:
+
+ // Constructor.
+ ClusterJet(string measureIn = "Lund", int selectIn = 2, int massSetIn = 2,
+ bool preclusterIn = false, bool reassignIn = false) : measure(1),
+ select(selectIn), massSet(massSetIn), doPrecluster(preclusterIn),
+ doReassign(reassignIn), nFew(0) {
+ char firstChar = toupper(measureIn[0]);
+ if (firstChar == 'J') measure = 2;
+ if (firstChar == 'D') measure = 3;
+ piMass = ParticleDataTable::m0(211);
+ }
+
+ // Analyze event.
+ bool analyze(const Event& event, double yScaleIn, double pTscaleIn,
+ int nJetMinIn = 1, int nJetMaxIn = 0, ostream& os = cout);
+
+ // Return info on jets produced.
+ int size() const {return jets.size();}
+ Vec4 p(int j) const {return jets[j].pJet;}
+
+ // Return belonging of particle to one of the jets (-1 if none).
+ int jetAssignment(int i) const {
+ for (int iP = 0; iP < int(particles.size()); ++iP)
+ if (particles[iP].mother == i) return particles[iP].daughter;
+ return -1;}
+
+ // Provide a listing of the info.
+ void list(ostream& os = cout);
+
+ // Tell how many events could not be analyzed.
+ int nError() const {return nFew;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int TIMESTOPRINT;
+ static const double PABSMIN, PRECLUSTERFRAC, PRECLUSTERSTEP;
+
+ // Properties of analysis.
+ int measure, select, massSet;
+ bool doPrecluster, doReassign;
+ double yScale, pTscale;
+ int nJetMin, nJetMax;
+
+ // Temporary results.
+ double piMass, dist2Join, dist2BigMin, distPre, dist2Pre;
+ vector<SingleClusterJet> particles;
+ int nParticles;
+
+ // Error statistics;
+ int nFew;
+
+ // Member functions for some operations (for clarity).
+ void precluster();
+ void reassign();
+
+ // Outcome of analysis: ET-ordered list of jets.
+ vector<SingleClusterJet> jets;
+
+};
+
+//**************************************************************************
+
+// SingleCell class.
+// Simple helper class to CellJet for a cell and its contents.
+
+class SingleCell {
+
+public:
+
+ // Constructor.
+ SingleCell(int iCellIn = 0, double etaCellIn = 0., double phiCellIn = 0.,
+ double eTcellIn = 0., int multiplicityIn = 0) : iCell(iCellIn),
+ etaCell(etaCellIn), phiCell(phiCellIn), eTcell(eTcellIn),
+ multiplicity(multiplicityIn), canBeSeed(true), isUsed(false),
+ isAssigned(false) {}
+
+ // Properties of cell.
+ int iCell;
+ double etaCell, phiCell, eTcell;
+ int multiplicity;
+ bool canBeSeed, isUsed, isAssigned;
+
+} ;
+
+//**************************************************************************
+
+// SingleCellJet class.
+// Simple helper class to CellJet for a jet and its contents.
+
+class SingleCellJet {
+
+public:
+
+ // Constructor.
+ SingleCellJet(double eTjetIn = 0., double etaCenterIn = 0.,
+ double phiCenterIn = 0., double etaWeightedIn = 0.,
+ double phiWeightedIn = 0., int multiplicityIn = 0,
+ Vec4 pMassiveIn = 0.) : eTjet(eTjetIn), etaCenter(etaCenterIn),
+ phiCenter(phiCenterIn), etaWeighted(etaWeightedIn),
+ phiWeighted(phiWeightedIn), multiplicity(multiplicityIn),
+ pMassive(pMassiveIn) {}
+
+ // Properties of jet.
+ double eTjet, etaCenter, phiCenter, etaWeighted, phiWeighted;
+ int multiplicity;
+ Vec4 pMassive;
+
+} ;
+
+//**************************************************************************
+
+// CellJet class.
+// This class performs a cone jet search in (eta, phi, E_T) space.
+
+class CellJet {
+
+public:
+
+ // Constructor.
+ CellJet(double etaMaxIn = 5., int nEtaIn = 50, int nPhiIn = 32,
+ int selectIn = 2, int smearIn = 0, double resolutionIn = 0.5,
+ double upperCutIn = 2., double thresholdIn = 0.) : etaMax(etaMaxIn),
+ nEta(nEtaIn), nPhi(nPhiIn), select(selectIn), smear(smearIn),
+ resolution(resolutionIn), upperCut(upperCutIn),
+ threshold(thresholdIn), nFew(0) { }
+
+ // Analyze event.
+ bool analyze(const Event& event, double eTjetMinIn = 20.,
+ double coneRadiusIn = 0.7, double eTseedIn = 1.5, ostream& os = cout);
+
+ // Return info on results of analysis.
+ int size() const {return jets.size();}
+ double eT(int i) const {return jets[i].eTjet;}
+ double etaCenter(int i) const {return jets[i].etaCenter;}
+ double phiCenter(int i) const {return jets[i].phiCenter;}
+ double etaWeighted(int i) const {return jets[i].etaWeighted;}
+ double phiWeighted(int i) const {return jets[i].phiWeighted;}
+ double multiplicity(int i) const {return jets[i].multiplicity;}
+ Vec4 pMassless(int i) const {return jets[i].eTjet * Vec4(
+ cos(jets[i].phiWeighted), sin(jets[i].phiWeighted),
+ sinh(jets[i].etaWeighted), cosh(jets[i].etaWeighted) );}
+ Vec4 pMassive(int i) const {return jets[i].pMassive;}
+ double m(int i) const {return jets[i].pMassive.mCalc();}
+
+ // Provide a listing of the info.
+ void list(ostream& os = cout);
+
+ // Tell how many events could not be analyzed: so far never.
+ int nError() const {return nFew;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int TIMESTOPRINT;
+
+ // Properties of analysis.
+ double etaMax;
+ int nEta, nPhi, select, smear;
+ double resolution, upperCut, threshold;
+ double eTjetMin, coneRadius, eTseed;
+
+ // Error statistics;
+ int nFew;
+
+ // Outcome of analysis: ET-ordered list of jets.
+ vector<SingleCellJet> jets;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // end Pythia8_Analysis_H
+
--- /dev/null
+// Basics.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for basic, often-used helper classes.
+// RndmEngine: base class for external random number generators.
+// Rndm: random number generator (static member functions).
+// Vec4: simple four-vectors.
+// RotBstMatrix: matrices encoding rotations and boosts of Vec4 objects.
+// Hist: simple one-dimensional histograms.
+
+#ifndef Pythia8_Basics_H
+#define Pythia8_Basics_H
+
+#include "PythiaStdlib.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// RndmEngine is the base class for external random number generators.
+// There is only one pure virtual method, that should do the generation.
+
+class RndmEngine {
+
+public:
+
+ // A pure virtual method, wherein the derived class method
+ // generates a random number uniformly distributed between 1 and 1.
+ virtual double flat() = 0;
+
+protected:
+
+ // Destructor.
+ virtual ~RndmEngine() {}
+
+};
+
+//**************************************************************************
+
+// Rndm class.
+// This class handles random number generation according to the
+// Marsaglia-Zaman-Tsang algorithm.
+
+class Rndm {
+
+public:
+
+ // Constructors.
+ Rndm() {}
+ Rndm(int seedIn) { init(seedIn);}
+
+ // Possibility to pass in pointer for external random number generation.
+ static bool rndmEnginePtr( RndmEngine* rndmPtrIn);
+
+ // Initialize, normally at construction or in first call.
+ static void init(int seedIn = 0) ;
+
+ // Generate next random number uniformly between 0 and 1.
+ static double flat() ;
+
+ // Generate random numbers according to exp(-x).
+ static double exp() { return -log(flat()) ;}
+
+ // Generate random numbers according to x * exp(-x).
+ static double xexp() { return -log(flat() * flat()) ;}
+
+ // Generate random numbers according to exp(-x^2/2).
+ static double gauss() ;
+
+ // Pick one option among vector of (positive) probabilities.
+ static int pick(const vector<double>& prob) ;
+
+private:
+
+ // State of the random number generator.
+ static bool initRndm, saveGauss;
+ static int i97, j97, defaultSeed;
+ static double u[97], c, cd, cm, save;
+
+ // Pointer for external random number generation.
+ static bool useExternalRndm;
+ static RndmEngine* rndmPtr;
+
+};
+
+//**************************************************************************
+
+// Forward reference to RotBstMatrix class.
+class RotBstMatrix;
+
+//**************************************************************************
+
+// Vec4 class.
+// This class implements four-vectors, in energy-momentum space.
+// (But can equally well be used to hold space-time four-vectors.)
+
+class Vec4 {
+
+public:
+
+ // Constructors.
+ Vec4(double xIn = 0., double yIn = 0., double zIn = 0., double tIn = 0.)
+ : xx(xIn), yy(yIn), zz(zIn), tt(tIn) { }
+ Vec4(const Vec4& v) : xx(v.xx), yy(v.yy), zz(v.zz), tt(v.tt) { }
+ Vec4& operator=(const Vec4& v) { if (this != &v) { xx = v.xx; yy = v.yy;
+ zz = v.zz; tt = v.tt; } return *this; }
+ Vec4& operator=(double value) { xx = value; yy = value; zz = value;
+ tt = value; return *this; }
+
+ // Member functions for input.
+ void reset() {xx = 0.; yy = 0.; zz = 0.; tt = 0.;}
+ void p(double xIn, double yIn, double zIn, double tIn)
+ {xx = xIn; yy = yIn; zz = zIn; tt = tIn;}
+ void p(Vec4 pIn) {xx = pIn.xx; yy = pIn.yy; zz = pIn.zz; tt = pIn.tt;}
+ void px(double xIn) {xx = xIn;}
+ void py(double yIn) {yy = yIn;}
+ void pz(double zIn) {zz = zIn;}
+ void e(double tIn) {tt = tIn;}
+
+ // Member functions for output.
+ double px() const {return xx;}
+ double py() const {return yy;}
+ double pz() const {return zz;}
+ double e() const {return tt;}
+ double mCalc() const {double temp = tt*tt - xx*xx - yy*yy - zz*zz;
+ return (temp >= 0) ? sqrt(temp) : -sqrt(-temp);}
+ double m2Calc() const {return tt*tt - xx*xx - yy*yy - zz*zz;}
+ double pT() const {return sqrt(xx*xx + yy*yy);}
+ double pT2() const {return xx*xx + yy*yy;}
+ double pAbs() const {return sqrt(xx*xx + yy*yy + zz*zz);}
+ double pAbs2() const {return xx*xx + yy*yy + zz*zz;}
+ double theta() const {return atan2(sqrt(xx*xx + yy*yy), zz);}
+ double phi() const {return atan2(yy,xx);}
+ double thetaXZ() const {return atan2(xx,zz);}
+ double pPlus() const {return tt + zz;}
+ double pMinus() const {return tt - zz;}
+
+ // Member functions that perform operations.
+ void rescale3(double fac) {xx *= fac; yy *= fac; zz *= fac;}
+ void rescale4(double fac) {xx *= fac; yy *= fac; zz *= fac; tt *= fac;}
+ void flip3() {xx = -xx; yy = -yy; zz = -zz;}
+ void flip4() {xx = -xx; yy = -yy; zz = -zz; tt = -tt;}
+ void rot(double thetaIn, double phiIn);
+ void rotaxis(double phiIn, double nx, double ny, double nz);
+ void rotaxis(double phiIn, const Vec4& n);
+ void bst(double betaX, double betaY, double betaZ);
+ void bst(double betaX, double betaY, double betaZ, double gamma);
+ void bst(const Vec4& pIn);
+ void bst(const Vec4& pIn, double mIn);
+ void bstback(const Vec4& pIn);
+ void bstback(const Vec4& pIn, double mIn);
+ void rotbst(const RotBstMatrix& M);
+
+ // Operator overloading with member functions
+ Vec4& operator-() {xx = -xx; yy = -yy; zz = -zz; tt = -tt; return *this;}
+ Vec4& operator+=(const Vec4& v) {xx += v.xx; yy += v.yy; zz += v.zz;
+ tt += v.tt; return *this;}
+ Vec4& operator-=(const Vec4& v) {xx -= v.xx; yy -= v.yy; zz -= v.zz;
+ tt -= v.tt; return *this;}
+ Vec4& operator*=(double f) {xx *= f; yy *= f; zz *= f;
+ tt *= f; return *this;}
+ Vec4& operator/=(double f) {xx /= f; yy /= f; zz /= f;
+ tt /= f; return *this;}
+
+ // Operator overloading with friends
+ friend Vec4 operator+(const Vec4& v1, const Vec4& v2);
+ friend Vec4 operator-(const Vec4& v1, const Vec4& v2);
+ friend Vec4 operator*(double f, const Vec4& v1);
+ friend Vec4 operator*(const Vec4& v1, double f);
+ friend Vec4 operator/(const Vec4& v1, double f);
+ friend double operator*(const Vec4& v1, const Vec4& v2);
+
+ // Invariant mass of a pair and its square.
+ friend double m(const Vec4& v1, const Vec4& v2);
+ friend double m2(const Vec4& v1, const Vec4& v2);
+
+ // Scalar and cross product of 3-vector parts.
+ friend double dot3(const Vec4& v1, const Vec4& v2);
+ friend Vec4 cross3(const Vec4& v1, const Vec4& v2);
+
+ // theta is polar angle between v1 and v2.
+ friend double theta(const Vec4& v1, const Vec4& v2);
+ friend double costheta(const Vec4& v1, const Vec4& v2);
+
+ // phi is azimuthal angle between v1 and v2 around z axis.
+ friend double phi(const Vec4& v1, const Vec4& v2);
+ friend double cosphi(const Vec4& v1, const Vec4& v2);
+
+ // phi is azimuthal angle between v1 and v2 around n axis.
+ friend double phi(const Vec4& v1, const Vec4& v2, const Vec4& n);
+ friend double cosphi(const Vec4& v1, const Vec4& v2, const Vec4& n);
+
+ // Print a four-vector
+ friend ostream& operator<<(ostream&, const Vec4& v) ;
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double TINY;
+
+ // The four-vector data members.
+ double xx, yy, zz, tt;
+
+};
+
+// Implementation of operator overloading with friends.
+
+inline Vec4 operator+(const Vec4& v1, const Vec4& v2)
+ {Vec4 v = v1 ; return v += v2;}
+
+inline Vec4 operator-(const Vec4& v1, const Vec4& v2)
+ {Vec4 v = v1 ; return v -= v2;}
+
+inline Vec4 operator*(double f, const Vec4& v1)
+ {Vec4 v = v1; return v *= f;}
+
+inline Vec4 operator*(const Vec4& v1, double f)
+ {Vec4 v = v1; return v *= f;}
+
+inline Vec4 operator/(const Vec4& v1, double f)
+ {Vec4 v = v1; return v /= f;}
+
+inline double operator*(const Vec4& v1, const Vec4& v2)
+ {return v1.tt*v2.tt - v1.xx*v2.xx - v1.yy*v2.yy - v1.zz*v2.zz;}
+
+//**************************************************************************
+
+// RotBstMatrix class.
+// This class implements 4 * 4 matrices that encode an arbitrary combination
+// of rotations and boosts, that can be applied to Vec4 four-vectors.
+
+class RotBstMatrix {
+
+public:
+
+ // Constructors.
+ RotBstMatrix() {for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j)
+ { M[i][j] = (i==j) ? 1. : 0.; } } }
+ RotBstMatrix(const RotBstMatrix& Min) {
+ for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) {
+ M[i][j] = Min.M[i][j]; } } }
+ RotBstMatrix& operator=(const RotBstMatrix& Min) {if (this != &Min) {
+ for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) {
+ M[i][j] = Min.M[i][j]; } } } return *this; }
+
+ // Member functions.
+ void rot(double = 0., double = 0.);
+ void rot(const Vec4& p);
+ void bst(double = 0., double = 0., double = 0.);
+ void bst(const Vec4&);
+ void bstback(const Vec4&);
+ void bst(const Vec4&, const Vec4&);
+ void toCMframe(const Vec4&, const Vec4&);
+ void fromCMframe(const Vec4&, const Vec4&);
+ void rotbst(const RotBstMatrix&);
+ void invert();
+ void reset();
+
+ // Crude estimate deviation from unit matrix.
+ double deviation() const;
+
+ // Print a transformation matrix.
+ friend ostream& operator<<(ostream&, const RotBstMatrix&) ;
+
+ // Private members to be accessible from Vec4.
+ friend class Vec4;
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double TINY;
+
+ // The rotation-and-boost matrix data members.
+ double M[4][4];
+
+};
+
+//**************************************************************************
+
+// Hist class.
+// This class handles a single histogram at a time.
+
+class Hist{
+
+public:
+
+ // Constructors, including copy constructors.
+ Hist() {;}
+ Hist(string titleIn, int nBinIn = 100, double xMinIn = 0.,
+ double xMaxIn = 1.) {
+ book(titleIn, nBinIn, xMinIn, xMaxIn);}
+ Hist(const Hist& h)
+ : title(h.title), nBin(h.nBin), nFill(h.nFill), xMin(h.xMin),
+ xMax(h.xMax), dx(h.dx), under(h.under), inside(h.inside),
+ over(h.over), res(h.res) { }
+ Hist(string titleIn, const Hist& h)
+ : title(titleIn), nBin(h.nBin), nFill(h.nFill), xMin(h.xMin),
+ xMax(h.xMax), dx(h.dx), under(h.under), inside(h.inside),
+ over(h.over), res(h.res) { }
+ Hist& operator=(const Hist& h) { if(this != &h) {
+ nBin = h.nBin; nFill = h.nFill; xMin = h.xMin; xMax = h.xMax;
+ dx = h.dx; under = h.under; inside = h.inside; over = h.over;
+ res = h.res; } return *this; }
+
+ // Book a histogram.
+ void book(string titleIn = " ", int nBinIn = 100, double xMinIn = 0.,
+ double xMaxIn = 1.) ;
+
+ // Set title of a histogram.
+ void name(string titleIn = " ") {title = titleIn; }
+
+ // Reset bin contents.
+ void null() ;
+
+ // Fill bin with weight.
+ void fill(double x, double w = 1.) ;
+
+ // Return content of specific bin: -1 gives underflow and nBin overflow.
+ double getBinContent(int iBin) ;
+
+ // Return number of entries
+ double getEntries() {return nFill; }
+
+ // Print histogram contents as a table (e.g. for Gnuplot).
+ void table(ostream& os = cout) const ;
+
+ // Check whether another histogram has same size and limits.
+ bool sameSize(const Hist& h) const ;
+
+ // Take logarithm (base 10 or e) of bin contents.
+ void takeLog(bool tenLog = true) ;
+
+ // Operator overloading with member functions
+ Hist& operator+=(const Hist& h) ;
+ Hist& operator-=(const Hist& h) ;
+ Hist& operator*=(const Hist& h) ;
+ Hist& operator/=(const Hist& h) ;
+ Hist& operator+=(double f) ;
+ Hist& operator-=(double f) ;
+ Hist& operator*=(double f) ;
+ Hist& operator/=(double f) ;
+
+ // Operator overloading with friends
+ friend Hist operator+(double f, const Hist& h1);
+ friend Hist operator+(const Hist& h1, double f);
+ friend Hist operator+(const Hist& h1, const Hist& h2);
+ friend Hist operator-(double f, const Hist& h1);
+ friend Hist operator-(const Hist& h1, double f);
+ friend Hist operator-(const Hist& h1, const Hist& h2);
+ friend Hist operator*(double f, const Hist& h1);
+ friend Hist operator*(const Hist& h1, double f);
+ friend Hist operator*(const Hist& h1, const Hist& h2);
+ friend Hist operator/(double f, const Hist& h1);
+ friend Hist operator/(const Hist& h1, double f);
+ friend Hist operator/(const Hist& h1, const Hist& h2);
+
+ // Print a histogram with overloaded << operator.
+ friend ostream& operator<<(ostream& os, const Hist& h) ;
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NBINMAX, NLINES;
+ static const double TOLERANCE, TINY, SMALLFRAC, DYAC[];
+ static const char NUMBER[];
+
+ // Properties and contents of a histogram.
+ string title;
+ int nBin, nFill;
+ double xMin, xMax, dx, under, inside, over;
+ vector<double> res;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // end Pythia8_Basics_H
--- /dev/null
+// BeamParticle.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for information on incoming beams.
+// ResolvedParton: an initiator or remnant in beam.
+// BeamParticle: contains partons, parton densities, etc.
+
+#ifndef Pythia8_BeamParticle_H
+#define Pythia8_BeamParticle_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "FragmentationFlavZpT.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PartonDistributions.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// This class holds info on a parton resolved inside the incoming beam,
+// i.e. either an initiator (part of a hard or a multiple interaction)
+// or a remnant (part of the beam remnant treatment).
+
+// The companion code is -1 from onset and for g, is -2 for an unmatched
+// sea quark, is >= 0 for a matched sea quark, with the number giving the
+// companion position, and is -3 for a valence quark.
+
+class ResolvedParton {
+
+public:
+
+ // Constructor.
+ ResolvedParton( int iPosIn = 0, int idIn = 0, double xIn = 0.,
+ int companionIn = -1) : iPosRes(iPosIn), idRes(idIn), xRes(xIn),
+ companionRes(companionIn), xqCompRes(0.), mRes(0.), colRes(0),
+ acolRes(0) { }
+
+ // Set info on initiator or remnant parton.
+ void iPos( int iPosIn) {iPosRes = iPosIn;}
+ void id( int idIn) {idRes = idIn;}
+ void x( double xIn) {xRes = xIn;}
+ void update( int iPosIn, int idIn, double xIn) {iPosRes = iPosIn;
+ idRes = idIn; xRes = xIn;}
+ void companion( int companionIn) {companionRes = companionIn;}
+ void xqCompanion( double xqCompIn) {xqCompRes = xqCompIn;}
+ void p(Vec4 pIn) {pRes = pIn;}
+ void px(double pxIn) {pRes.px(pxIn);}
+ void py(double pyIn) {pRes.py(pyIn);}
+ void pz(double pzIn) {pRes.pz(pzIn);}
+ void e(double eIn) {pRes.e(eIn);}
+ void m(double mIn) {mRes = mIn;}
+ void col(int colIn) {colRes = colIn;}
+ void acol(int acolIn) {acolRes = acolIn;}
+ void cols(int colIn = 0,int acolIn = 0)
+ {colRes = colIn; acolRes = acolIn;}
+
+ // Get info on initiator or remnant parton.
+ int iPos() const {return iPosRes;}
+ int id() const {return idRes;}
+ double x() const {return xRes;}
+ int companion() const {return companionRes;}
+ bool isValence() const {return (companionRes == -3);}
+ bool isUnmatched() const {return (companionRes == -2);}
+ bool isCompanion() const {return (companionRes >= 0);}
+ double xqCompanion() const {return xqCompRes;}
+ Vec4 p() const {return pRes;}
+ double px() const {return pRes.px();}
+ double py() const {return pRes.py();}
+ double pz() const {return pRes.pz();}
+ double e() const {return pRes.e();}
+ double m() const {return mRes;}
+ double pT() const {return pRes.pT();}
+ double mT2() const {return mRes*mRes + pRes.pT2();}
+ int col() const {return colRes;}
+ int acol() const {return acolRes;}
+
+private:
+
+ // Properties of a resolved parton.
+ int iPosRes, idRes;
+ double xRes;
+ // Companion code and distribution value, if any.
+ int companionRes;
+ double xqCompRes;
+ // Four-momentum and mass; for remnant kinematics construction.
+ Vec4 pRes;
+ double mRes;
+ // Colour codes.
+ int colRes, acolRes;
+
+};
+
+//**************************************************************************
+
+// This class holds info on a beam particle in the evolution of
+// initial-state radiation and multiple interactions.
+
+class BeamParticle {
+
+public:
+
+ // Constructor.
+ BeamParticle() {Q2ValFracSav = -1.;}
+
+ // Initialize data on a beam particle and save pointers.
+ void init( int idIn, double pzIn, double eIn, double mIn,
+ Info* infoPtrIn, PDF* pdfInPtr, PDF* pdfHardInPtr,
+ bool isUnresolvedIn, StringFlav* flavSelPtrIn);
+
+ // Set new pZ and E, but keep the rest the same.
+ void newPzE( double pzIn, double eIn) {pBeam = Vec4( 0., 0., pzIn, eIn);}
+
+ // Member functions for output.
+ int id() const {return idBeam;}
+ Vec4 p() const {return pBeam;}
+ double px() const {return pBeam.px();}
+ double py() const {return pBeam.py();}
+ double pz() const {return pBeam.pz();}
+ double e() const {return pBeam.e();}
+ double m() const {return mBeam;}
+ bool isLepton() const {return isLeptonBeam;}
+ bool isUnresolved() const {return isUnresolvedBeam;}
+ // As hadrons here we only count those we know how to handle remnants for.
+ bool isHadron() const {return isHadronBeam;}
+ bool isMeson() const {return isMesonBeam;}
+ bool isBaryon() const {return isBaryonBeam;}
+
+ // Maximum x remaining after previous MI and ISR, plus safety margin.
+ double xMax(int iSkip = -1);
+
+ // Special hard-process parton distributions (can agree with standard ones).
+ double xfHard(int idIn, double x, double Q2)
+ {return pdfHardBeamPtr->xf(idIn, x, Q2);}
+
+ // Standard parton distributions.
+ double xf(int idIn, double x, double Q2)
+ {return pdfBeamPtr->xf(idIn, x, Q2);}
+
+ // Ditto, split into valence and sea parts (where gluon counts as sea).
+ double xfVal(int idIn, double x, double Q2)
+ {return pdfBeamPtr->xfVal(idIn, x, Q2);}
+ double xfSea(int idIn, double x, double Q2)
+ {return pdfBeamPtr->xfSea(idIn, x, Q2);}
+
+ // Rescaled parton distributions, as needed for MI and ISR.
+ // For ISR also allow split valence/sea, and only return relevant part.
+ double xfMI(int idIn, double x, double Q2)
+ {return xfModified(-1, idIn, x, Q2);}
+ double xfISR(int indexMI, int idIn, double x, double Q2)
+ {return xfModified( indexMI, idIn, x, Q2);}
+
+ // Decide whether chosen quark is valence, sea or companion.
+ int pickValSeaComp();
+
+ // Initialize kind of incoming beam particle.
+ void initBeamKind();
+
+ // Overload index operator to access a resolved parton from the list.
+ ResolvedParton& operator[](int i) {return resolved[i];}
+
+ // Total number of partons extracted from beam, and initiators only.
+ int size() const {return resolved.size();}
+ int sizeInit() const {return nInit;}
+
+ // Clear list of resolved partons.
+ void clear() {resolved.resize(0);}
+
+ // Add a resolved parton to list.
+ int append( int iPos, int idIn, double x, int companion = -1)
+ {resolved.push_back( ResolvedParton( iPos, idIn, x, companion) );
+ return resolved.size() - 1;}
+
+ // Print extracted parton list; for debug mainly.
+ void list(ostream& os = cout);
+
+ // How many different flavours, and how many quarks of given flavour.
+ int nValenceKinds() const {return nValKinds;}
+ int nValence(int idIn) const {for (int i = 0; i < nValKinds; ++i)
+ if (idIn == idVal[i]) return nVal[i]; return 0;}
+
+ // Test whether a lepton is to be considered as unresolved.
+ bool isUnresolvedLepton();
+
+ // Add extra remnant flavours to make valence and sea come out right.
+ bool remnantFlavours(Event& event);
+
+ // Correlate all initiators and remnants to make a colour singlet.
+ bool remnantColours(Event& event, vector<int>& colFrom,
+ vector<int>& colTo);
+
+ // Pick unrescaled x of remnant parton (valence or sea).
+ double xRemnant(int i);
+
+ // Tell whether a junction has been resolved, and its junction colours.
+ bool hasJunction() const {return hasJunctionBeam;}
+ int junctionCol(int i) const {return junCol[i];}
+ void junctionCol(int i, int col) {junCol[i] = col;}
+
+ // For a diffractive system, decide whether to kick out gluon or quark.
+ bool pickGluon(double mDiff);
+
+ // Pick a valence quark at random, and provide the remaining flavour.
+ int pickValence();
+ int pickRemnant() const {return idVal2;}
+
+ // Share lightcone momentum between two remnants in a diffractive system.
+ // At the same time generate a relative pT for the two.
+ double zShare( double mDiff, double m1, double m2);
+ double pxShare() const {return pxRel;}
+ double pyShare() const {return pyRel;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double XMINUNRESOLVED;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pinters to PDF sets.
+ PDF* pdfBeamPtr;
+ PDF* pdfHardBeamPtr;
+
+ // Pointer to class for flavour generation.
+ StringFlav* flavSelPtr;
+
+ // Initialization data, normally only set once.
+ bool allowJunction;
+ int maxValQuark, companionPower;
+ double valencePowerMeson, valencePowerUinP, valencePowerDinP,
+ valenceDiqEnhance, pickQuarkNorm, pickQuarkPower,
+ diffPrimKTwidth, diffLargeMassSuppress;
+
+ // Basic properties of a beam particle.
+ int idBeam, idBeamAbs;
+ Vec4 pBeam;
+ double mBeam;
+ // Beam kind. Valence flavour content for hadrons.
+ bool isLeptonBeam, isUnresolvedBeam, isHadronBeam, isMesonBeam,
+ isBaryonBeam;
+ int nValKinds, idVal[3], nVal[3];
+
+ // Current parton density, by valence, sea and companion.
+ int idSave, iSkipSave, nValLeft[3];
+ double xqgTot, xqVal, xqgSea, xqCompSum;
+
+ // The list of resolved partons.
+ vector<ResolvedParton> resolved;
+
+ // Status after all initiators have been accounted for. Junction content.
+ int nInit;
+ bool hasJunctionBeam;
+ int junCol[3];
+
+ // Routine to calculate pdf's given previous interactions.
+ double xfModified( int iSkip, int idIn, double x, double Q2);
+
+ // Fraction of hadron momentum sitting in a valence quark distribution.
+ double xValFrac(int j, double Q2);
+ double Q2ValFracSav, uValInt, dValInt;
+
+ // Fraction of hadron momentum sitting in a companion quark distribution.
+ double xCompFrac(double xs);
+
+ // Value of companion quark PDF, also given the sea quark x.
+ double xCompDist(double xc, double xs);
+
+ // Valence quark subdivision for diffractive systems.
+ int idVal1, idVal2, idVal3;
+ double zRel, pxRel, pyRel;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_BeamParticle_H
--- /dev/null
+// BeamRemnants.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for beam-remnants handling.
+// BeamRemnants: matches the remnants between the two beams.
+
+#ifndef Pythia8_BeamRemnants_H
+#define Pythia8_BeamRemnants_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Event.h"
+#include "FragmentationFlavZpT.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PartonDistributions.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// This class matches the kinematics of the hard-scattering subsystems
+// (with primordial kT added) to that of the two beam remnants.
+
+class BeamRemnants {
+
+public:
+
+ // Constructor.
+ BeamRemnants() { }
+
+ // Initialization.
+ bool init( Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn);
+
+ // Select the flavours/kinematics/colours of the two beam remnants.
+ bool add( Event& event);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRYCOLMATCH, NTRYKINMATCH;
+
+ // Initialization data, read from Settings.
+ bool doPrimordialKT, doReconnect;
+ double primordialKTsoft, primordialKThard, primordialKTremnant,
+ halfScaleForKT, halfMassForKT, reconnectRange,
+ pT0Ref, ecmRef, ecmPow;
+
+ // Information set for events.
+ int nSys, oldSize;
+ double eCM, sCM, pT0, pT20Rec;
+
+ // Colour collapses (when one colour is mapped onto another).
+ vector<int> colFrom, colTo;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to the two incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Do the kinematics of the collision subsystems and two beam remnants.
+ bool setKinematics( Event& event);
+
+ // Allow colour reconnections.
+ bool reconnectColours( Event& event);
+
+ // Check that colours are consistent.
+ bool checkColours( Event& event);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_BeamRemnants_H
--- /dev/null
+// BeamShape.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header for classes to set beam momentum and interaction vertex spread.
+
+#ifndef Pythia8_BeamShape_H
+#define Pythia8_BeamShape_H
+
+#include "Basics.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Base class to set beam momentum and interaction spot spread.
+
+class BeamShape {
+
+public:
+
+ // Constructor.
+ BeamShape() {}
+
+ // Destructor.
+ virtual ~BeamShape() {}
+
+ // Initialize beam parameters.
+ virtual void init();
+
+ // Set the two beam momentum deviations and the beam vertex.
+ virtual void pick();
+
+ // Methods to read out the choice made with the above method.
+ Vec4 deltaPA() const {return Vec4( deltaPxA, deltaPyA, deltaPzA, 0);}
+ Vec4 deltaPB() const {return Vec4( deltaPxB, deltaPyB, deltaPzB, 0);}
+ Vec4 vertex() const {return Vec4( vertexX, vertexY, vertexZ, vertexT);}
+
+protected:
+
+ // Values to be set.
+ double deltaPxA, deltaPyA, deltaPzA, deltaPxB, deltaPyB, deltaPzB,
+ vertexX, vertexY, vertexZ, vertexT;
+
+ // Parameters of Gaussian parametrizations.
+ bool allowMomentumSpread, allowVertexSpread;
+ double sigmaPxA, sigmaPyA, sigmaPzA, maxDevA, sigmaPxB, sigmaPyB,
+ sigmaPzB, maxDevB, sigmaVertexX, sigmaVertexY, sigmaVertexZ,
+ maxDevVertex, sigmaTime, maxDevTime, offsetX, offsetY,
+ offsetZ, offsetT;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_BeamShape_H
--- /dev/null
+// Bose-Einstein.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the classes to handle Bose-Einstein effects.
+// BoseEinsteinHadron: simple working container for particle momenta.
+// BoseEinstein: main class to perform the task.
+
+#ifndef Pythia8_BoseEinstein_H
+#define Pythia8_BoseEinstein_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The BoseEinsteinHadron class is a simple container for studied hadrons.
+
+class BoseEinsteinHadron {
+
+public:
+
+ // Constructors.
+ BoseEinsteinHadron() : id(0), iPos(0), p(0.), pShift(0.), pComp(0.),
+ m2(0.) {}
+ BoseEinsteinHadron(int idIn, int iPosIn, Vec4 pIn, double mIn) :
+ id(idIn), iPos(iPosIn), p(pIn), pShift(0.), pComp(0.) {m2 = mIn*mIn;}
+
+ // Information on hadron - all public.
+ int id, iPos;
+ Vec4 p, pShift, pComp;
+ double m2;
+
+};
+
+//**************************************************************************
+
+// The BoseEinstein class shifts the momenta of identical particles relative
+// to each other, to simulate Bose-Einstein effects to some approximation.
+
+class BoseEinstein {
+
+public:
+
+ // Constructor.
+ BoseEinstein() {}
+
+ // Find settings. Precalculate table used to find momentum shifts.
+ bool init(Info* infoPtrIn);
+
+ // Perform Bose-Einstein corrections on an event.
+ bool shiftEvent( Event& event);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int IDHADRON[9], ITABLE[9], NCOMPSTEP;
+ static const double STEPSIZE, Q2MIN, COMPRELERR, COMPFACMAX;
+
+ // Initialization data, read from Settings.
+ bool doPion, doKaon, doEta;
+ double lambda, QRef;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Table of momentum shifts for different hadron species.
+ int nStep[4], nStep3[4], nStored[10];
+ double QRef2, QRef3, R2Ref, R2Ref2, R2Ref3, mHadron[9],
+ mPair[4], m2Pair[4], deltaQ[4], deltaQ3[4], maxQ[4], maxQ3[4];
+ double shift[4][200], shift3[4][200];
+
+ // Vector of hadrons to study.
+ vector<BoseEinsteinHadron> hadronBE;
+
+ // Calculate shift and (unnormalized) compensation for pair.
+ void shiftPair(int i1, int i2, int iHad);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_BoseEinstein_H
+
--- /dev/null
+// Event.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the Particle and Event classes.
+// Particle: information on an instance of a particle.
+// Junction: information on a junction between three colours.
+// Event: list of particles in the current event.
+
+#ifndef Pythia8_Event_H
+#define Pythia8_Event_H
+
+#include "Basics.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Forward references to ParticleData and ResonanceWidths classes.
+class ParticleDataEntry;
+class ResonanceWidths;
+
+//**************************************************************************
+
+// Particle class.
+// This class holds info on a particle in general.
+
+class Particle {
+
+public:
+
+ // Constructors.
+ Particle() : idSave(0), statusSave(0), mother1Save(0), mother2Save(0),
+ daughter1Save(0), daughter2Save(0), colSave(0), acolSave(0),
+ pSave(Vec4(0.,0.,0.,0.)), mSave(0.), scaleSave(0.),
+ hasVertexSave(false), vProdSave(Vec4(0.,0.,0.,0.)), tauSave(0.),
+ particlePtr(0) { }
+ Particle(int idIn, int statusIn = 0, int mother1In = 0,
+ int mother2In = 0, int daughter1In = 0, int daughter2In = 0,
+ int colIn = 0, int acolIn = 0, double pxIn = 0., double pyIn = 0.,
+ double pzIn = 0., double eIn = 0., double mIn = 0., double scaleIn = 0.)
+ : idSave(idIn), statusSave(statusIn), mother1Save(mother1In),
+ mother2Save(mother2In), daughter1Save(daughter1In),
+ daughter2Save(daughter2In), colSave(colIn), acolSave(acolIn),
+ pSave(Vec4(pxIn, pyIn, pzIn, eIn)), mSave(mIn), scaleSave(scaleIn),
+ hasVertexSave(false), vProdSave(Vec4(0.,0.,0.,0.)), tauSave(0.)
+ {setParticlePtr();}
+ Particle(int idIn, int statusIn, int mother1In, int mother2In,
+ int daughter1In, int daughter2In, int colIn, int acolIn,
+ Vec4 pIn, double mIn = 0., double scaleIn = 0.)
+ : idSave(idIn), statusSave(statusIn), mother1Save(mother1In),
+ mother2Save(mother2In), daughter1Save(daughter1In),
+ daughter2Save(daughter2In), colSave(colIn), acolSave(acolIn),
+ pSave(pIn), mSave(mIn), scaleSave(scaleIn), hasVertexSave(false),
+ vProdSave(Vec4(0.,0.,0.,0.)), tauSave(0.) {setParticlePtr();}
+ Particle(const Particle& pt) : idSave(pt.idSave),
+ statusSave(pt.statusSave), mother1Save(pt.mother1Save),
+ mother2Save(pt.mother2Save), daughter1Save(pt.daughter1Save),
+ daughter2Save(pt.daughter2Save), colSave(pt.colSave),
+ acolSave(pt.acolSave), pSave(pt.pSave), mSave(pt.mSave),
+ scaleSave(pt.scaleSave), hasVertexSave(pt.hasVertexSave),
+ vProdSave(pt.vProdSave), tauSave(pt.tauSave),
+ particlePtr(pt.particlePtr) { }
+ Particle& operator=(const Particle& pt) {if (this != &pt) {
+ idSave = pt.idSave; statusSave = pt.statusSave;
+ mother1Save = pt.mother1Save; mother2Save = pt.mother2Save;
+ daughter1Save = pt.daughter1Save; daughter2Save = pt.daughter2Save;
+ colSave = pt.colSave; acolSave = pt.acolSave; pSave = pt.pSave;
+ mSave = pt.mSave; scaleSave = pt.scaleSave;
+ hasVertexSave = pt.hasVertexSave; vProdSave = pt.vProdSave;
+ tauSave = pt.tauSave; particlePtr = pt.particlePtr; } return *this; }
+
+ // Member functions for input.
+ void id(int idIn) {idSave = idIn; setParticlePtr();}
+ void status(int statusIn) {statusSave = statusIn;}
+ void statusPos() {statusSave = abs(statusSave);}
+ void statusNeg() {statusSave = -abs(statusSave);}
+ void statusCode(int statusIn) {statusSave =
+ (statusSave > 0) ? abs(statusIn) : -abs(statusIn);}
+ void mother1(int mother1In) {mother1Save = mother1In;}
+ void mother2(int mother2In) {mother2Save = mother2In;}
+ void mothers(int mother1In = 0, int mother2In = 0)
+ {mother1Save = mother1In; mother2Save = mother2In;}
+ void daughter1(int daughter1In) {daughter1Save = daughter1In;}
+ void daughter2(int daughter2In) {daughter2Save = daughter2In;}
+ void daughters(int daughter1In = 0, int daughter2In = 0)
+ {daughter1Save = daughter1In; daughter2Save = daughter2In;}
+ void col(int colIn) {colSave = colIn;}
+ void acol(int acolIn) {acolSave = acolIn;}
+ void cols(int colIn = 0,int acolIn = 0) {colSave = colIn;
+ acolSave = acolIn;}
+ void p(Vec4 pIn) {pSave = pIn;}
+ void p(double pxIn, double pyIn, double pzIn, double eIn)
+ {pSave.p(pxIn, pyIn, pzIn, eIn);}
+ void px(double pxIn) {pSave.px(pxIn);}
+ void py(double pyIn) {pSave.py(pyIn);}
+ void pz(double pzIn) {pSave.pz(pzIn);}
+ void e(double eIn) {pSave.e(eIn);}
+ void m(double mIn) {mSave = mIn;}
+ void scale(double scaleIn) {scaleSave = scaleIn;}
+ void vProd(Vec4 vProdIn) {vProdSave = vProdIn; hasVertexSave = true;}
+ void vProd(double xProdIn, double yProdIn, double zProdIn, double tProdIn)
+ {vProdSave.p(xProdIn, yProdIn, zProdIn, tProdIn); hasVertexSave = true;}
+ void xProd(double xProdIn) {vProdSave.px(xProdIn); hasVertexSave = true;}
+ void yProd(double yProdIn) {vProdSave.py(yProdIn); hasVertexSave = true;}
+ void zProd(double zProdIn) {vProdSave.pz(zProdIn); hasVertexSave = true;}
+ void tProd(double tProdIn) {vProdSave.e(tProdIn); hasVertexSave = true;}
+ void tau(double tauIn) {tauSave = tauIn;}
+
+ // Member functions for output.
+ int id() const {return idSave;}
+ int status() const {return statusSave;}
+ int mother1() const {return mother1Save;}
+ int mother2() const {return mother2Save;}
+ int daughter1() const {return daughter1Save;}
+ int daughter2() const {return daughter2Save;}
+ int col() const {return colSave;}
+ int acol() const {return acolSave;}
+ Vec4 p() const {return pSave;}
+ double px() const {return pSave.px();}
+ double py() const {return pSave.py();}
+ double pz() const {return pSave.pz();}
+ double e() const {return pSave.e();}
+ double m() const {return mSave;}
+ double scale() const {return scaleSave;}
+ bool hasVertex() const {return hasVertexSave;}
+ Vec4 vProd() const {return vProdSave;}
+ double xProd() const {return vProdSave.px();}
+ double yProd() const {return vProdSave.py();}
+ double zProd() const {return vProdSave.pz();}
+ double tProd() const {return vProdSave.e();}
+ double tau() const {return tauSave;}
+
+ // Member functions for output; derived int and bool quantities.
+ int idAbs() const {return abs(idSave);}
+ int statusAbs() const {return abs(statusSave);}
+ bool isFinal() const {return (statusSave > 0);}
+
+ // Member functions for output; derived double quantities.
+ double m2() const {return mSave*mSave;}
+ double mCalc() const {return pSave.mCalc();}
+ double m2Calc() const {return pSave.m2Calc();}
+ double eCalc() const {return sqrt(mSave*mSave + pSave.pAbs2());}
+ double pT() const {return pSave.pT();}
+ double pT2() const {return pSave.pT2();}
+ double mT() const {return sqrt(mSave*mSave + pSave.pT2());}
+ double mT2() const {return mSave*mSave + pSave.pT2();}
+ double pAbs() const {return pSave.pAbs();}
+ double pAbs2() const {return pSave.pAbs2();}
+ double theta() const {return pSave.theta();}
+ double phi() const {return pSave.phi();}
+ double thetaXZ() const {return pSave.thetaXZ();}
+ double pPlus() const {return pSave.pPlus();}
+ double pMinus() const {return pSave.pMinus();}
+ double y() const;
+ double eta() const;
+ Vec4 vDec() const {return (tauSave > 0. && mSave > 0.)
+ ? vProdSave + tauSave * pSave / mSave : vProdSave;}
+ double xDec() const {return (tauSave > 0. && mSave > 0.)
+ ? vProdSave.px() + tauSave * pSave.px() / mSave : vProdSave.px();}
+ double yDec() const {return (tauSave > 0. && mSave > 0.)
+ ? vProdSave.py() + tauSave * pSave.py() / mSave : vProdSave.py();}
+ double zDec() const {return (tauSave > 0. && mSave > 0.)
+ ? vProdSave.pz() + tauSave * pSave.pz() / mSave : vProdSave.pz();}
+ double tDec() const {return (tauSave > 0. && mSave > 0.)
+ ? vProdSave.e() + tauSave * pSave.e() / mSave : vProdSave.e();}
+
+ // Further output, based on a pointer to a ParticleDataEntry object.
+ string name() const {return particlePtr->name(idSave);}
+ string nameWithStatus(int maxLen = 20) const;
+ int spinType() const {return particlePtr->spinType();}
+ int chargeType() const {return particlePtr->chargeType(idSave);}
+ double charge() const {return particlePtr->charge(idSave);}
+ bool isCharged() const {return (particlePtr->chargeType(idSave) != 0);}
+ bool isNeutral() const {return (particlePtr->chargeType(idSave) == 0);}
+ int colType() const {return particlePtr->colType(idSave);}
+ double m0() const {return particlePtr->m0();}
+ double mWidth() const {return particlePtr->mWidth();}
+ double mMin() const {return particlePtr->mMin();}
+ double mMax() const {return particlePtr->mMax();}
+ double mass() const {return particlePtr->mass();}
+ double constituentMass() const {return particlePtr->constituentMass();}
+ double tau0() const {return particlePtr->tau0();}
+ bool mayDecay() const {return particlePtr->mayDecay();}
+ bool canDecay() const {return particlePtr->canDecay();}
+ bool doExternalDecay() const {return particlePtr->doExternalDecay();}
+ bool isResonance() const {return particlePtr->isResonance();}
+ bool isVisible() const {return particlePtr->isVisible();}
+ bool isLepton() const {return particlePtr->isLepton();}
+ bool isQuark() const {return particlePtr->isQuark();}
+ bool isGluon() const {return particlePtr->isGluon();}
+ bool isHadron() const {return particlePtr->isHadron();}
+ ParticleDataEntry& particleData() const {return *particlePtr;}
+
+ // Member functions that perform operations.
+ void rescale3(double fac) {pSave.rescale3(fac);}
+ void rescale4(double fac) {pSave.rescale4(fac);}
+ void rescale5(double fac) {pSave.rescale4(fac); mSave *= fac;}
+ void rot(double thetaIn, double phiIn) {pSave.rot(thetaIn, phiIn);
+ if (hasVertexSave) vProdSave.rot(thetaIn, phiIn);}
+ void bst(double betaX, double betaY, double betaZ) {
+ pSave.bst(betaX, betaY, betaZ);
+ if (hasVertexSave) vProdSave.bst(betaX, betaY, betaZ);}
+ void bst(double betaX, double betaY, double betaZ, double gamma) {
+ pSave.bst(betaX, betaY, betaZ, gamma);
+ if (hasVertexSave) vProdSave.bst(betaX, betaY, betaZ, gamma);}
+ void bst(const Vec4& pBst) {pSave.bst(pBst);
+ if (hasVertexSave) vProdSave.bst(pBst);}
+ void bst(const Vec4& pBst, double mBst) {pSave.bst(pBst, mBst);
+ if (hasVertexSave) vProdSave.bst(pBst, mBst);}
+ void bstback(const Vec4& pBst) {pSave.bstback(pBst);
+ if (hasVertexSave) vProdSave.bstback(pBst);}
+ void bstback(const Vec4& pBst, double mBst) {pSave.bstback(pBst, mBst);
+ if (hasVertexSave) vProdSave.bstback(pBst, mBst);}
+ void rotbst(const RotBstMatrix& M) {pSave.rotbst(M);
+ if (hasVertexSave) vProdSave.rotbst(M);}
+ void offsetHistory( int minMother, int addMother, int minDaughter,
+ int addDaughter);
+ void offsetCol( int addCol);
+
+ // Member function to set the ParticleDataEntry pointer, using idSave.
+ void setParticlePtr();
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double TINY;
+
+ // Properties of the current particle.
+ int idSave, statusSave, mother1Save, mother2Save, daughter1Save,
+ daughter2Save, colSave, acolSave;
+ Vec4 pSave;
+ double mSave, scaleSave;
+ bool hasVertexSave;
+ Vec4 vProdSave;
+ double tauSave;
+
+ // Pointer to properties of the particle species.
+ // Should no be saved in a persistent copy of the event record.
+ // The //! below is ROOT notation that this member should not be saved.
+ // Event::restorePtrs() can be called to restore the missing information.
+ ParticleDataEntry* particlePtr; //!
+
+};
+
+// Invariant mass of a pair and its square.
+// (Not part of class proper, but tightly linked.)
+double m(const Particle&, const Particle&);
+double m2(const Particle&, const Particle&);
+
+//**************************************************************************
+
+// The juction class stores what kind of junction it is, the colour indices
+// of the legs at the junction and as far out as legs have been traced,
+// and the status codes assigned for fragmentation of each leg.
+
+class Junction {
+
+public:
+
+ // Constructors.
+ Junction() : remainsSave(true), kindSave(0) {
+ for (int j = 0; j < 3; ++j) {
+ colSave[j] = 0; endColSave[j] = 0; statusSave[j] = 0; } }
+ Junction( int kindIn, int col0In, int col1In, int col2In)
+ : remainsSave(true), kindSave(kindIn) {colSave[0] = col0In;
+ colSave[1] = col1In; colSave[2] = col2In;
+ for (int j = 0; j < 3; ++j) {
+ endColSave[j] = colSave[j]; statusSave[j] = 0; } }
+ Junction(const Junction& ju) : remainsSave(ju.remainsSave),
+ kindSave(ju.kindSave) { for (int j = 0; j < 3; ++j) {
+ colSave[j] = ju.colSave[j]; endColSave[j] = ju.endColSave[j];
+ statusSave[j] = ju.statusSave[j]; } }
+ Junction& operator=(const Junction& ju) {if (this != &ju) {
+ remainsSave = ju.remainsSave; kindSave = ju.kindSave;
+ for (int j = 0; j < 3; ++j) { colSave[j] = ju.colSave[j];
+ endColSave[j] = ju.endColSave[j]; statusSave[j] = ju.statusSave[j]; } }
+ return *this; }
+
+ // Set values.
+ void remains(bool remainsIn) {remainsSave = remainsIn;}
+ void col(int j, int colIn) {colSave[j] = colIn; endColSave[j] = colIn;}
+ void cols(int j, int colIn, int endColIn) {colSave[j] = colIn;
+ endColSave[j] = endColIn;}
+ void endCol(int j, int endColIn) {endColSave[j] = endColIn;}
+ void status(int j, int statusIn) {statusSave[j] = statusIn;}
+
+ // Read out value.
+ bool remains() const {return remainsSave;}
+ int kind() const {return kindSave;}
+ int col(int j) const {return colSave[j];}
+ int endCol(int j) const {return endColSave[j];}
+ int status(int j) const {return statusSave[j];}
+
+private:
+
+ // Kind, positions of the three ends and their status codes.
+ bool remainsSave;
+ int kindSave, colSave[3], endColSave[3], statusSave[3];
+
+};
+
+//**************************************************************************
+
+// The Event class holds all info on the generated event.
+
+class Event {
+
+public:
+
+ // Constructors.
+ Event(int capacity = 100) {entry.reserve(capacity); startColTag = 100;
+ headerList = "----------------------------------------";}
+ Event& operator=(const Event& oldEvent);
+
+ // Initialize colour and header specification for event listing.
+ void init( string headerIn = "");
+
+ // Clear event record.
+ void clear() {entry.resize(0); maxColTag = startColTag;
+ clearJunctions(); clearSystems();}
+
+ // Clear event record, and set first particle empty.
+ void reset() {clear(); append(90, -11, 0, 0, 0., 0., 0., 0., 0.);}
+
+ // Overload index operator to access element of event record.
+ Particle& operator[](int i) {return entry[i];}
+ const Particle& operator[](int i) const {return entry[i];}
+
+ // Event record size.
+ int size() const {return entry.size();}
+
+ // Put a new particle at the end of the event record; return index.
+ int append(Particle entryIn) {
+ entry.push_back(entryIn);
+ if (entryIn.col() > maxColTag) maxColTag = entryIn.col();
+ if (entryIn.acol() > maxColTag) maxColTag = entryIn.acol();
+ return entry.size() - 1;
+ }
+ int append(int id, int status, int mother1, int mother2, int daughter1,
+ int daughter2, int col, int acol, double px, double py, double pz,
+ double e, double m = 0., double scaleIn = 0.) {entry.push_back(
+ Particle(id, status, mother1, mother2, daughter1, daughter2, col, acol,
+ px, py, pz, e, m, scaleIn) );
+ if (col > maxColTag) maxColTag = col;
+ if (acol > maxColTag) maxColTag = acol;
+ return entry.size() - 1;
+ }
+ int append(int id, int status, int mother1, int mother2, int daughter1,
+ int daughter2, int col, int acol, Vec4 p, double m = 0.,
+ double scaleIn = 0.) {entry.push_back( Particle(id, status, mother1,
+ mother2, daughter1, daughter2, col, acol, p, m, scaleIn) );
+ if (col > maxColTag) maxColTag = col;
+ if (acol > maxColTag) maxColTag = acol;
+ return entry.size() - 1;
+ }
+
+ // Brief versions of append: no mothers and no daughters.
+ int append(int id, int status, int col, int acol, double px, double py,
+ double pz, double e, double m = 0.) {entry.push_back( Particle(id,
+ status, 0, 0, 0, 0, col, acol, px, py, pz, e, m, 0.) );
+ if (col > maxColTag) maxColTag = col;
+ if (acol > maxColTag) maxColTag = acol;
+ return entry.size() - 1;
+ }
+ int append(int id, int status, int col, int acol, Vec4 p, double m = 0.)
+ {entry.push_back( Particle(id, status, 0, 0, 0, 0, col, acol, p, m, 0.) );
+ if (col > maxColTag) maxColTag = col;
+ if (acol > maxColTag) maxColTag = acol;
+ return entry.size() - 1;
+ }
+
+ // Add a copy of an existing particle at the end of the event record.
+ int copy(int iCopy, int newStatus = 0);
+
+ // Implement reference "back" to access last element.
+ Particle& back() {return entry.back();}
+
+ // List the particles in an event.
+ void list(ostream& os = cout) {list(false, false, os);}
+ void list(bool showScaleAndVertex, bool showMothersAndDaughters = false,
+ ostream& os = cout);
+
+ // Remove last n entries.
+ void popBack(int nRemove = 1) { if (nRemove ==1) entry.pop_back();
+ else {int newSize = max( 0, size() - nRemove);
+ entry.resize(newSize);} }
+
+ // Restore all ParticleDataEntry* pointers in the Particle vector.
+ // Useful when a persistent copy of the event record is read back in.
+ void restorePtrs() {
+ for (int i = 0; i < size(); ++i) entry[i].setParticlePtr(); }
+
+ // Save or restore the size of the event record (throwing at the end).
+ void saveSize() {savedSize = entry.size();}
+ void restoreSize() {entry.resize(savedSize);}
+
+ // Initialize and access colour tag information.
+ void initColTag(int colTag = 0) {maxColTag = max( colTag,startColTag);}
+ int lastColTag() const {return maxColTag;}
+ int nextColTag() {return ++maxColTag;}
+
+ // Access scale for which event as a whole is defined.
+ void scale( double scaleIn) {scaleSave = scaleIn;}
+ double scale() const {return scaleSave;}
+
+ // Need a second scale if two hard interactions in event.
+ void scaleSecond( double scaleSecondIn) {scaleSecondSave = scaleSecondIn;}
+ double scaleSecond() const {return scaleSecondSave;}
+
+ // Find complete list of daughters and mothers.
+ vector<int> motherList(int i) const;
+ vector<int> daughterList(int i) const;
+
+ // Trace the first and last copy of one and the same particle.
+ int iTopCopy(int i) const;
+ int iBotCopy(int i) const;
+
+ // Trace the first and last copy of a particle, using flavour match.
+ int iTopCopyId(int i) const;
+ int iBotCopyId(int i) const;
+
+ // Find list of sisters, also tracking up and down identical copies.
+ vector<int> sisterList(int i) const;
+ vector<int> sisterListTopBot(int i, bool widenSearch = true) const;
+
+ // Check whether two particles have a direct mother-daughter relation.
+ bool isAncestor(int i, int iAncestor) const;
+
+ // Member functions for rotations and boosts of an event.
+ void rot(double theta, double phi)
+ {for (int i = 0; i < size(); ++i) entry[i].rot(theta, phi);}
+ void bst(double betaX, double betaY, double betaZ)
+ {for (int i = 0; i < size(); ++i) entry[i].bst(betaX, betaY, betaZ);}
+ void bst(double betaX, double betaY, double betaZ, double gamma)
+ {for (int i = 0; i < size(); ++i) entry[i].bst(betaX, betaY, betaZ,
+ gamma);}
+ void bst(const Vec4& vec)
+ {for (int i = 0; i < size(); ++i) entry[i].bst(vec);}
+ void rotbst(const RotBstMatrix& M)
+ {for (int i = 0; i < size(); ++i) entry[i].rotbst(M);}
+
+ // Clear the list of junctions.
+ void clearJunctions() {junction.resize(0);}
+
+ // Add a junction to the list, study it or extra input.
+ void appendJunction( int kind, int col0, int col1, int col2)
+ { junction.push_back( Junction( kind, col0, col1, col2) );}
+ void appendJunction(Junction junctionIn) {junction.push_back(junctionIn);}
+ int sizeJunction() const {return junction.size();}
+ bool remainsJunction(int i) const {return junction[i].remains();}
+ void remainsJunction(int i, bool remainsIn) {junction[i].remains(remainsIn);}
+ int kindJunction(int i) const {return junction[i].kind();}
+ int colJunction( int i, int j) const {return junction[i].col(j);}
+ void colJunction( int i, int j, int colIn) {junction[i].col(j, colIn);}
+ int endColJunction( int i, int j) const {return junction[i].endCol(j);}
+ void endColJunction( int i, int j, int endColIn)
+ {junction[i].endCol(j, endColIn);}
+ int statusJunction( int i, int j) const {return junction[i].status(j);}
+ void statusJunction( int i, int j, int statusIn)
+ {junction[i].status(j, statusIn);}
+ Junction& getJunction(int i) {return junction[i];}
+ const Junction& getJunction(int i) const {return junction[i];}
+ void eraseJunction(int i);
+
+ // Save or restore the size of the junction list (throwing at the end).
+ void saveJunctionSize() {savedJunctionSize = junction.size();}
+ void restoreJunctionSize() {junction.resize(savedJunctionSize);}
+
+ // List any junctions in the event; for debug mainly.
+ void listJunctions(ostream& os = cout) const;
+
+ // Operations with grouped systems of partons for internal use only.
+ // (Used by combined MI, ISR, FSR and BR machinery in PartonLevel.)
+
+ // Reset all systems and system number to empty.
+ void clearSystems() {beginSys.resize(0); sizeSys.resize(0);
+ memberSys.resize(0);}
+
+ // Get number of systems or number of members in a system.
+ int sizeSystems() const {return beginSys.size();}
+ int sizeSystem(int iSys) const {return sizeSys[iSys];}
+
+ // New system or new parton in system.
+ int newSystem() {beginSys.push_back(memberSys.size());
+ sizeSys.push_back(0); return (beginSys.size() - 1);}
+ void addToSystem(int iSys, int iPos);
+
+ // Get or set value of given member in given system. Replace value by new.
+ int getInSystem(int iSys, int iMem) const {
+ return memberSys[beginSys[iSys] + iMem];}
+ void setInSystem(int iSys, int iMem, int iPos) {
+ memberSys[beginSys[iSys] + iMem] = iPos;}
+ void replaceInSystem(int iSys, int iPosOld, int iPosNew);
+
+ // List members in systems; for debug mainly.
+ void listSystems(ostream& os = cout) const;
+
+ // Operator overloading allows to append one event to an existing one.
+ // Warning: particles should be OK, but some other information unreliable.
+ Event& operator+=(const Event& addEvent);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int IPERLINE;
+
+ // Initialization data, normally only set once.
+ int startColTag;
+
+ // The event: a vector containing all particles (entries).
+ vector<Particle> entry;
+
+ // The list of junctions.
+ vector<Junction> junction;
+
+ // The maximum colour tag of the event so far.
+ int maxColTag;
+
+ // Saved entry and junction list sizes, for simple restoration.
+ int savedSize, savedJunctionSize;
+
+ // The scale of the event; linear quantity in GeV.
+ double scaleSave, scaleSecondSave;
+
+ // Header specification in event listing (at most 40 characters wide).
+ string headerList;
+
+ // Offsets, sizes and values of systems.
+ vector<int> beginSys, sizeSys, memberSys;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // end Pythia8_Event_H
--- /dev/null
+// FragmentationFlavZpT.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains helper classes for fragmentation.
+// StringFlav is used to select quark and hadron flavours.
+// StringPT is used to select transverse momenta.
+// StringZ is used to sample the fragmentation function f(z).
+
+#ifndef Pythia8_FragmentationFlavZpT_H
+#define Pythia8_FragmentationFlavZpT_H
+
+#include "Basics.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+
+//**************************************************************************
+
+// The FlavContainer class is a simple container for flavour,
+// including the extra properties needed for popcorn baryon handling.
+// id = current flavour.
+// rank = current rank; 0 for endpoint flavour and then increase by 1.
+// nPop = number of popcorn mesons yet to be produced (1 or 0).
+// idPop = (absolute sign of) popcorn quark, shared between B and Bbar.
+// idVtx = (absolute sign of) vertex (= non-shared) quark in diquark.
+
+class FlavContainer {
+
+public:
+
+ // Constructor.
+ FlavContainer(int idIn = 0, int rankIn = 0, int nPopIn = 0,
+ int idPopIn = 0, int idVtxIn = 0) : id(idIn), rank(rankIn),
+ nPop(nPopIn), idPop(idPopIn), idVtx(idVtxIn) {}
+
+ // Overloaded equal operator.
+ FlavContainer& operator=(const FlavContainer& flav) { if (this != &flav) {
+ id = flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
+ idVtx = flav.idVtx; } return *this; }
+
+ // Invert flavour.
+ FlavContainer& anti() {id = -id; return *this;}
+
+ // Read in a container into another, without/with id sign flip.
+ FlavContainer& copy(const FlavContainer& flav) { if (this != &flav) {
+ id = flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
+ idVtx = flav.idVtx; } return *this; }
+ FlavContainer& anti(const FlavContainer& flav) { if (this != &flav) {
+ id = -flav.id; rank = flav.rank; nPop = flav.nPop; idPop = flav.idPop;
+ idVtx = flav.idVtx; } return *this; }
+
+ // Stored properties.
+ int id, rank, nPop, idPop, idVtx;
+
+};
+
+//**************************************************************************
+
+// The StringFlav class is used to select quark and hadron flavours.
+
+class StringFlav {
+
+public:
+
+ // Constructor.
+ StringFlav() {}
+
+ // Initialize data members.
+ void init();
+
+ // Pick a light d, u or s quark according to fixed ratios.
+ int pickLightQ() { double rndmFlav = probQandS * Rndm::flat();
+ if (rndmFlav < 1.) return 1; if (rndmFlav < 2.) return 2; return 3; }
+
+ // Pick a new flavour (including diquarks) given an incoming one.
+ FlavContainer pick(FlavContainer& flavOld);
+
+ // Combine two flavours (including diquarks) to produce a hadron.
+ int combine(FlavContainer& flav1, FlavContainer& flav2);
+
+ // Assign popcorn quark inside an original (= rank 0) diquark.
+ void assignPopQ(FlavContainer& flav);
+
+ // Combine two quarks to produce a diquark.
+ int makeDiquark(int id1, int id2, int idHad = 0);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int mesonMultipletCode[6];
+ static const double baryonCGOct[6], baryonCGDec[6];
+
+ // Initialization data, to be read from Settings.
+ bool suppressLeadingB;
+ double probQQtoQ, probStoUD, probSQtoQQ, probQQ1toQQ0, probQandQQ,
+ probQandS, probQandSinQQ, probQQ1corr, probQQ1corrInv, probQQ1norm,
+ mesonRate[4][6], mesonRateSum[4], mesonMix1[2][6], mesonMix2[2][6],
+ etaSup, etaPrimeSup, decupletSup, baryonCGSum[6], baryonCGMax[6],
+ popcornRate, popcornSpair, popcornSmeson, scbBM[3], popFrac,
+ popS[3], dWT[3][7], lightLeadingBSup, heavyLeadingBSup;
+};
+
+//**************************************************************************
+
+// The StringZ class is used to sample the fragmentation function f(z).
+
+class StringZ {
+
+public:
+
+ // Constructor.
+ StringZ() {}
+
+ // Initialize data members.
+ void init();
+
+ // Fragmentation function: top-level to determine parameters.
+ double zFrag( int idOld, int idNew = 0, double mT2 = 1.);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double CFROMUNITY, AFROMZERO, AFROMC, EXPMAX;
+
+ // Initialization data, to be read from Settings.
+ bool usePetersonC, usePetersonB, usePetersonH;
+ double mc2, mb2, aLund, bLund, aExtraDiquark, rFactC, rFactB, rFactH,
+ epsilonC, epsilonB, epsilonH;
+
+ // Fragmentation function: select z according to provided parameters.
+ double zLund( double a, double b, double c = 1.);
+ double zPeterson( double epsilon);
+
+};
+
+//**************************************************************************
+
+// The StringPT class is used to select select transverse momenta.
+
+class StringPT {
+
+public:
+
+ // Constructor.
+ StringPT() {}
+
+ // Initialize data members.
+ void init();
+
+ // Return px and py separately, but really same routine.
+ double px() {return pxy();}
+ double py() {return pxy();}
+
+private:
+
+ // Initialization data, to be read from Settings.
+ double sigmaQ, enhancedFraction, enhancedWidth;
+
+ // pT fragmentation spectrum.
+ double pxy();
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_FragmentationFlavZpT_H
--- /dev/null
+// FragmentationSystems.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains auxiliary classes in the fragmentation process.
+// ColSinglet contains info on an individual singlet.
+// ColConfig describes the colour configuration of the whole event.
+// StringRegion keeps track on string momenta and directions.
+// StringSystem contains all the StringRegions of the colour singlet.
+
+#ifndef Pythia8_FragmentationSystems_H
+#define Pythia8_FragmentationSystems_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "FragmentationFlavZpT.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ColSinglet class contains info on an individual singlet.
+// Only to be used inside ColConfig, so no private members.
+
+class ColSinglet {
+
+public:
+
+ // Constructors.
+ ColSinglet() : pSum(0., 0., 0., 0.), mass(0.), massExcess(0.),
+ hasJunction(false), isClosed(false), isCollected(false) {}
+ ColSinglet(vector<int>& iPartonIn, Vec4 pSumIn, double massIn,
+ double massExcessIn, bool hasJunctionIn = false,
+ bool isClosedIn = false, bool isCollectedIn = false)
+ : iParton(iPartonIn), pSum(pSumIn), mass(massIn),
+ massExcess(massExcessIn), hasJunction(hasJunctionIn),
+ isClosed(isClosedIn), isCollected(isCollectedIn) {}
+
+ // Size of iParton array.
+ int size() const { return iParton.size();}
+
+ // Stored quantities.
+ vector<int> iParton;
+ Vec4 pSum;
+ double mass, massExcess;
+ bool hasJunction, isClosed, isCollected;
+
+};
+
+//**************************************************************************
+
+// The ColConfig class describes the colour configuration of the whole event.
+
+class ColConfig {
+
+public:
+
+ // Constructor.
+ ColConfig() {}
+
+ // Initialize and save pointers.
+ void init(StringFlav* flavSelPtrIn);
+
+ // Number of colour singlets.
+ int size() const {return singlets.size();}
+
+ // Overload index operator to access separate colour singlets.
+ ColSinglet& operator[](int iSub) {return singlets[iSub];}
+
+ // Clear contents.
+ void clear() {singlets.resize(0);}
+
+ // Insert a new colour singlet system in ascending mass order.
+ // Calculate its properties. Join nearby partons.
+ void insert( vector<int>& iPartonIn, Event& event);
+
+ // Collect all partons of singlet to be consecutively ordered.
+ void collect(int iSub, Event& event);
+
+ // List all currently identified singlets.
+ void list(ostream& os = cout);
+
+private:
+
+ // Pointer to class for flavour generation.
+ StringFlav* flavSelPtr;
+
+ // Initialization data, to be read from Settings.
+ double mJoin, mJoinJunction, mStringMin;
+
+ // List of all separate colour singlets.
+ vector<ColSinglet> singlets;
+
+ // Join two legs of junction to a diquark for small invariant masses.
+ bool joinJunction( vector<int>& iPartonIn, Event& event,
+ double massExcessIn);
+
+};
+
+//**************************************************************************
+
+// The StringRegion class contains the information related to
+// one string section in the evolution of a multiparton system.
+// Only to be used inside StringFragmentation and MiniStringFragmentation,
+// so no private members.
+
+class StringRegion {
+
+public:
+
+ // Constructor.
+ StringRegion() : isSetUp(false), isEmpty(true) {}
+
+ // Constants: could only be changed in the code itself.
+ static const double MJOIN, TINY;
+
+ // Data members.
+ bool isSetUp, isEmpty;
+ Vec4 pPos, pNeg, eX, eY;
+ double w2, xPosProj, xNegProj, pxProj, pyProj;
+
+ // Set up four-vectors for longitudinal and transverse directions.
+ void setUp(Vec4 p1, Vec4 p2, bool isMassless = false);
+
+ // Construct a four-momentum from (x+, x-, px, py).
+ Vec4 pHad( double xPosIn, double xNegIn, double pxIn, double pyIn)
+ { return xPosIn * pPos + xNegIn * pNeg + pxIn * eX + pyIn * eY; }
+
+ // Project a four-momentum onto (x+, x-, px, py). Read out projection.
+ void project(Vec4 pIn);
+ void project( double pxIn, double pyIn, double pzIn, double eIn)
+ { project( Vec4( pxIn, pyIn, pzIn, eIn) ); }
+ double xPos() const {return xPosProj;}
+ double xNeg() const {return xNegProj;}
+ double px() const {return pxProj;}
+ double py() const {return pyProj;}
+
+};
+
+//**************************************************************************
+
+// The StringSystem class contains the complete set of all string regions.
+// Only to be used inside StringFragmentation, so no private members.
+
+class StringSystem {
+
+public:
+
+ // Constructor.
+ StringSystem() {}
+
+ // Set up system from parton list.
+ void setUp(vector<int>& iSys, Event& event);
+
+ // Calculate string region from (iPos, iNeg) pair.
+ int iReg( int iPos, int iNeg) const
+ {return (iPos * (indxReg - iPos)) / 2 + iNeg;}
+
+ // Reference to string region specified by (iPos, iNeg) pair.
+ StringRegion& region(int iPos, int iNeg) {return system[iReg(iPos, iNeg)];}
+
+ // Reference to low string region specified either by iPos or iNeg.
+ StringRegion& regionLowPos(int iPos) {return system[iReg(iPos, iMax - iPos)];}
+ StringRegion& regionLowNeg(int iNeg) {return system[iReg(iMax - iNeg, iNeg)];}
+
+ // Main content: a vector with all the string regions of the system.
+ vector<StringRegion> system;
+
+ // Other data members.
+ int sizePartons, sizeStrings, sizeRegions, indxReg, iMax;
+ double mJoin, m2Join;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_FragmentationSystems_H
--- /dev/null
+// HadronLevel.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the main class for hadron-level generation.
+// HadronLevel: handles administration of fragmentation and decay.
+
+#ifndef Pythia8_HadronLevel_H
+#define Pythia8_HadronLevel_H
+
+#include "Basics.h"
+#include "BoseEinstein.h"
+#include "Event.h"
+#include "FragmentationFlavZpT.h"
+#include "FragmentationSystems.h"
+#include "Info.h"
+#include "MiniStringFragmentation.h"
+#include "ParticleData.h"
+#include "ParticleDecays.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+#include "StringFragmentation.h"
+#include "TimeShower.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The HadronLevel class contains the top-level routines to generate
+// the transition from the partonic to the hadronic stage of an event.
+
+class HadronLevel {
+
+public:
+
+ // Constructor.
+ HadronLevel() {}
+
+ // Initialize HadronLevel classes as required.
+ bool init(Info* infoPtrIn, TimeShower* timesDecPtr,
+ DecayHandler* decayHandlePtr, vector<int> handledParticles);
+
+ // Get pointer to StringFlav instance (needed by BeamParticle).
+ StringFlav* getStringFlavPtr() {return &flavSel;}
+
+ // Generate the next event.
+ bool next(Event& event);
+
+ // Special routine to allow more decays if on/off switches changed.
+ bool moreDecays(Event& event);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRYJNREST;
+ static const double JJSTRINGM2MAX, JJSTRINGM2FRAC, CONVJNREST, MTHAD;
+
+ // Initialization data, read from Settings.
+ bool doHadronize, doDecay, doBoseEinstein;
+ double mStringMin, eNormJunction, widthSepBE;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Configuration of colour-singlet systems.
+ ColConfig colConfig;
+
+ // Colour information.
+ vector<int> iColEnd, iAcolEnd, iColAndAcol, iParton, iPartonJun,
+ iPartonAntiJun, iJunLegA, iJunLegB, iJunLegC,
+ iAntiLegA, iAntiLegB, iAntiLegC, iGluLeg;
+ vector<double> m2Pair;
+
+ // The generator class for normal string fragmentation.
+ StringFragmentation stringFrag;
+
+ // The generator class for special low-mass string fragmentation.
+ MiniStringFragmentation ministringFrag;
+
+ // The generator class for normal decays.
+ ParticleDecays decays;
+
+ // The generator class for Bose-Einstein effects.
+ BoseEinstein boseEinstein;
+
+ // Classes for flavour, pT and z generation.
+ StringFlav flavSel;
+ StringPT pTSel;
+ StringZ zSel;
+
+ // Special case: colour-octet onium decays, to be done initially.
+ bool decayOctetOnia(Event& event);
+
+ // Trace colour flow in the event to form colour singlet subsystems.
+ bool findSinglets(Event& event);
+
+ // Trace a colour line, from a colour, from an anticolour, or in loop.
+ bool traceFromCol(int indxCol, Event& event, int iJun = -1, int iCol = -1);
+ bool traceFromAcol(int indxCol, Event& event, int iJun = -1, int iCol = -1);
+ bool traceInLoop(int indxCol, int indxAcol, Event& event);
+
+ // Split junction-antijunction system into two, or simplify other way.
+ bool splitJunctionPair(Event& event);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_HadronLevel_H
--- /dev/null
+// HepMCInterface.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Mikhail Kirsanov, Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+//--------------------------------------------------------------------------
+#ifndef Pythia8_HepMCInterface_H
+#define Pythia8_HepMCInterface_H
+
+//////////////////////////////////////////////////////////////////////////
+// Mikhail.Kirsanov@Cern.CH
+// Pythia8 I class
+//////////////////////////////////////////////////////////////////////////
+//
+
+#include <set>
+#include <vector>
+#include "HepMC/IO_BaseClass.h"
+#include "Pythia.h"
+
+namespace HepMC {
+
+ class GenEvent;
+ class GenVertex;
+ class GenParticle;
+ class ParticleDataTable;
+
+ class I_Pythia8 : public IO_BaseClass {
+ public:
+ I_Pythia8();
+ virtual ~I_Pythia8();
+ bool fill_next_event( Pythia8::Event& pyev, GenEvent* evt,
+ int ievnum = -1 );
+ bool fill_next_event( Pythia8::Pythia& pythia, GenEvent* evt,
+ int ievnum = -1,
+ bool convertGluonTo0 = false );
+ void put_pdf_info( GenEvent* evt, Pythia8::Pythia& pythia,
+ bool convertGluonTo0 = false );
+
+ // see comments below for these switches.
+ bool trust_both_mothers_and_daughters() const;
+ bool trust_mothers_before_daughters() const;
+ bool print_inconsistency_errors() const;
+ void set_trust_mothers_before_daughters( bool b = 1 );
+ void set_trust_both_mothers_and_daughters( bool b = 0 );
+ void set_print_inconsistency_errors( bool b = 1 );
+ void set_crash_on_problem( bool b = 1 );
+ void set_convert_to_mev( bool b = 1 );
+
+ private: // following are not (yet?) implemented for this class
+ virtual bool fill_next_event( GenEvent* ) { return 0; }
+ virtual void write_event( const GenEvent* ) {;}
+ virtual void write_particle_data_table( const ParticleDataTable* ){}
+ virtual bool fill_particle_data_table( ParticleDataTable* )
+ { return 0; }
+
+ private: // use of copy constructor is not allowed
+ I_Pythia8( const I_Pythia8& ) : IO_BaseClass() {}
+
+ private: // data members
+
+ bool m_trust_mothers_before_daughters;
+ bool m_trust_both_mothers_and_daughters;
+ bool m_print_inconsistency_errors;
+ int m_internal_event_number;
+ bool m_crash_on_problem;
+ bool m_convert_to_mev;
+ float m_mom_scale_factor;
+
+ };
+
+ ////////////////////////////
+ // INLINES access methods //
+ ////////////////////////////
+ inline bool I_Pythia8::trust_both_mothers_and_daughters() const
+ { return m_trust_both_mothers_and_daughters; }
+
+ inline bool I_Pythia8::trust_mothers_before_daughters() const
+ { return m_trust_mothers_before_daughters; }
+
+ inline bool I_Pythia8::print_inconsistency_errors() const
+ { return m_print_inconsistency_errors; }
+
+ inline void I_Pythia8::set_trust_both_mothers_and_daughters( bool b )
+ { m_trust_both_mothers_and_daughters = b; }
+
+ inline void I_Pythia8::set_trust_mothers_before_daughters( bool b )
+ { m_trust_mothers_before_daughters = b; }
+
+ inline void I_Pythia8::set_print_inconsistency_errors( bool b )
+ { m_print_inconsistency_errors = b; }
+
+ inline void I_Pythia8::set_crash_on_problem( bool b )
+ { m_crash_on_problem = b; }
+
+ inline void I_Pythia8::set_convert_to_mev( bool b )
+ { m_convert_to_mev = b; m_mom_scale_factor = 1000.; }
+
+} // HepMC
+
+#endif // Pythia8_HepMCInterface_H
+
+//--------------------------------------------------------------------------
--- /dev/null
+// Info.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains a class that keep track of generic event info.
+// Info: contains information on the generation process and errors.
+
+#ifndef Pythia8_Info_H
+#define Pythia8_Info_H
+
+#include "PythiaStdlib.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The Info class contains a mixed bag of information on the event
+// generation activity, especially on the current subprocess properties,
+// and on the number of errors encountered. This is used by the
+// generation machinery, but can also be read by the user.
+
+class Info {
+
+public:
+
+ // Constructor.
+ Info() {}
+
+ // Listing of most available information on current event.
+ void list(ostream& os = cout);
+
+ // Beam particles (in rest frame). CM energy of event.
+ int idA() const {return idASave;}
+ int idB() const {return idBSave;}
+ double pzA() const {return pzASave;}
+ double pzB() const {return pzBSave;}
+ double eA() const {return eASave;}
+ double eB() const {return eBSave;}
+ double mA() const {return mASave;}
+ double mB() const {return mBSave;}
+ double eCM() const {return eCMSave;}
+ double s() const {return sSave;}
+
+ // Process name and code, and the number of final-state particles.
+ string name() const {return nameSave;}
+ int code() const {return codeSave;}
+ int nFinal() const {return nFinalSave;}
+
+ // Are beam particles resolved, with pdf's? Are they diffractive?
+ bool isResolved() const {return isRes;}
+ bool isDiffractiveA() const {return isDiffA;}
+ bool isDiffractiveB() const {return isDiffB;}
+ bool isMinBias() const {return isMB;}
+
+ // Information for Les Houches Accord and reading files.
+ bool isLHA() const {return isLH;}
+ bool atEndOfFile() const {return atEOF;}
+
+ // For minbias and Les Houches Accord identify hardest subprocess.
+ bool hasSub() const {return hasSubSave;}
+ string nameSub() const {return nameSubSave;}
+ int codeSub() const {return codeSubSave;}
+ int nFinalSub() const {return nFinalSubSave;}
+
+ // Incoming parton flavours and x values.
+ int id1() const {return id1Save;}
+ int id2() const {return id2Save;}
+ double x1() const {return x1Save;}
+ double x2() const {return x2Save;}
+ double y() const {return 0.5 * log( x1Save / x2Save );}
+ double tau() const {return x1Save * x2Save;}
+
+ // Incoming parton densities, hard process couplings, Q2 scales.
+ double pdf1() const {return pdf1Save;}
+ double pdf2() const {return pdf2Save;}
+ double QFac() const {return sqrtpos(Q2FacSave);}
+ double Q2Fac() const {return Q2FacSave;}
+ bool isValence1() const {return isVal1;}
+ bool isValence2() const {return isVal2;}
+ double alphaS() const {return alphaSSave;}
+ double alphaEM() const {return alphaEMSave;}
+ double QRen() const {return sqrtpos(Q2RenSave);}
+ double Q2Ren() const {return Q2RenSave;}
+
+ // Mandelstam variables (notation as if subcollision).
+ double mHat() const {return sqrt(sH);}
+ double sHat() const {return sH;}
+ double tHat() const {return tH;}
+ double uHat() const {return uH;}
+ double pTHat() const {return pTH;}
+ double pT2Hat() const {return pTH*pTH;}
+ double m3Hat() const {return m3H;}
+ double m4Hat() const {return m4H;}
+ double thetaHat() const {return thetaH;}
+ double phiHat() const {return phiH;}
+
+ // Weight of current event; normally 1, but used for Les Houches events.
+ double weight() const {return weightSave;}
+
+ // Cross section estimate.
+ long nTried() const {return nTry;}
+ long nSelected() const {return nSel;}
+ long nAccepted() const {return nAcc;}
+ double sigmaGen() const {return sigGen;}
+ double sigmaErr() const {return sigErr;}
+
+ // Impact parameter picture.
+ double bMI() const {return (bIsSet) ? bMISave : 1.;}
+ double enhanceMI() const {return (bIsSet) ? enhanceMISave : 1.;}
+
+ // Maximum pT scales for MI, ISR and FSR (in hard process).
+ double pTmaxMI() const {return pTmaxMISave;}
+ double pTmaxISR() const {return pTmaxISRSave;}
+ double pTmaxFSR() const {return pTmaxFSRSave;}
+
+ // Number of multiple interactions, with code and pT for them.
+ int nMI() const {return nMISave;}
+ int codeMI(int i) const {return codeMISave[i];}
+ double pTMI(int i) const {return pTMISave[i];}
+
+ // Number of times other steps have been carried out.
+ int nISR() const {return nISRSave;}
+ int nFSRinProc() const {return nFSRinProcSave;}
+ int nFSRinRes() const {return nFSRinResSave;}
+
+ // Reset to empty map of error messages.
+ void errorReset() {messages.clear();}
+
+ // Print a message the first few times. Insert in database.
+ void errorMsg(string messageIn, string extraIn = " ",
+ ostream& os = cout);
+
+ // Provide total number of errors/aborts/warnings experienced to date.
+ int errorTotalNumber();
+
+ // Print statistics on errors/aborts/warnings.
+ void errorStatistics(ostream& os = cout);
+
+private:
+
+ // Store common beam quantities.
+ int idASave, idBSave;
+ double pzASave, eASave,mASave, pzBSave, eBSave, mBSave, eCMSave, sSave;
+
+ // Store common integrated cross section quantities.
+ long nTry, nSel, nAcc;
+ double sigGen, sigErr;
+
+ // Store current-event quantities.
+ bool isRes, isDiffA, isDiffB, isMB, isLH, hasSubSave, bIsSet, evolIsSet,
+ atEOF, isVal1, isVal2;
+ int codeSave, codeSubSave, nFinalSave, nFinalSubSave, nTotal,
+ id1Save, id2Save, nMISave, nISRSave, nFSRinProcSave, nFSRinResSave;
+ double x1Save, x2Save, pdf1Save, pdf2Save, Q2FacSave, alphaEMSave,
+ alphaSSave, Q2RenSave, sH, tH, uH, pTH, m3H, m4H, thetaH, phiH,
+ weightSave, bMISave, enhanceMISave, pTmaxMISave, pTmaxISRSave,
+ pTmaxFSRSave;
+ string nameSave, nameSubSave;
+ vector<int> codeMISave;
+ vector<double> pTMISave;
+
+ // Friend classes allowed to set info.
+ friend class Pythia;
+ friend class ProcessLevel;
+ friend class ProcessContainer;
+ friend class PartonLevel;
+ friend class MultipleInteractions;
+
+ // Set info on the two incoming beams: only from Pythia class.
+ void setBeamA( int idAin, double pzAin, double eAin, double mAin) {
+ idASave = idAin; pzASave = pzAin; eASave = eAin; mASave = mAin;}
+ void setBeamB( int idBin, double pzBin, double eBin, double mBin) {
+ idBSave = idBin; pzBSave = pzBin; eBSave = eBin; mBSave = mBin;}
+ void setECM( double eCMin) {eCMSave = eCMin; sSave = eCMSave * eCMSave;}
+
+ // Reset info for current event: only from Pythia class.
+ void clear() { isRes = isDiffA = isDiffB = isMB = isLH = atEOF = bIsSet
+ = isVal1 =isVal2 = false; codeSave = nFinalSave = nTotal = id1Save
+ = id2Save = nMISave = nISRSave = nFSRinProcSave = nFSRinResSave = 0;
+ x1Save = x2Save = pdf1Save = pdf2Save = Q2FacSave = alphaEMSave
+ = alphaSSave = Q2RenSave = sH = tH = uH = pTH = m3H = m4H = thetaH
+ = phiH = 0.; nameSave = " "; weightSave = bMISave = enhanceMISave = 1.;
+ codeMISave.resize(0); pTMISave.resize(0);}
+
+ // Set info on the (sub)process: from ProcessLevel, ProcessContainer or
+ // MultipleInteractions classes.
+ void setType( string nameIn, int codeIn, int nFinalIn,
+ bool isMinBiasIn = false, bool isResolvedIn = true,
+ bool isDiffractiveAin = false, bool isDiffractiveBin = false,
+ bool isLHAin = false) {nameSave = nameIn; codeSave = codeIn;
+ nFinalSave = nFinalIn; isMB = isMinBiasIn; isRes = isResolvedIn;
+ isDiffA = isDiffractiveAin; isDiffB = isDiffractiveBin; isLH = isLHAin;
+ nTotal = 2 + nFinalSave; bIsSet = false; hasSubSave = false;
+ nameSubSave = " "; codeSubSave = 0; nFinalSubSave = 0; evolIsSet = false;}
+ void setSubType( string nameSubIn, int codeSubIn, int nFinalSubIn) {
+ hasSubSave = true; nameSubSave = nameSubIn; codeSubSave = codeSubIn;
+ nFinalSubSave = nFinalSubIn;}
+ void setPDFalpha( int id1In, int id2In, double pdf1In, double pdf2In,
+ double Q2FacIn, double alphaEMIn, double alphaSIn, double Q2RenIn)
+ {id1Save = id1In; id2Save = id2In; pdf1Save = pdf1In; pdf2Save = pdf2In;
+ Q2FacSave = Q2FacIn; alphaEMSave = alphaEMIn; alphaSSave = alphaSIn;
+ Q2RenSave = Q2RenIn;}
+ void setKin( double x1In, double x2In, double sHatIn, double tHatIn,
+ double uHatIn, double pTHatIn, double m3HatIn, double m4HatIn,
+ double thetaHatIn, double phiHatIn) {x1Save = x1In; x2Save = x2In;
+ sH = sHatIn; tH = tHatIn; uH = uHatIn; pTH = pTHatIn; m3H = m3HatIn;
+ m4H = m4HatIn; thetaH = thetaHatIn; phiH = phiHatIn;}
+ void setTypeMI( int codeMIIn, double pTMIIn) {
+ codeMISave.push_back(codeMIIn); pTMISave.push_back(pTMIIn);}
+
+ // Set info on cross section: from ProcessLevel.
+ void setSigma( long nTryIn, long nSelIn, long nAccIn, double sigGenIn,
+ double sigErrIn) { nTry = nTryIn; nSel = nSelIn; nAcc = nAccIn;
+ sigGen = sigGenIn; sigErr = sigErrIn;}
+
+ // Set info on valence character of hard collision partons: from PartonLevel.
+ void setValence( bool isVal1In, bool isVal2In) {isVal1 = isVal1In;
+ isVal2 = isVal2In;}
+
+ // Set info on impact parameter: from PartonLevel.
+ void setImpact( double bMIIn, double enhanceMIIn) {bMISave = bMIIn;
+ enhanceMISave = enhanceMIIn, bIsSet = true;}
+
+ // Set info on pTmax scales and number of evolution steps: from PartonLevel.
+ void setEvolution( double pTmaxMIIn, double pTmaxISRIn, double pTmaxFSRIn,
+ int nMIIn, int nISRIn, int nFSRinProcIn, int nFSRinResIn) {
+ pTmaxMISave = pTmaxMIIn; pTmaxISRSave = pTmaxISRIn;
+ pTmaxFSRSave = pTmaxFSRIn; nMISave = nMIIn; nISRSave = nISRIn;
+ nFSRinProcSave = nFSRinProcIn; nFSRinResSave = nFSRinResIn;
+ evolIsSet = true;}
+
+ // Set info whether reading of Les Houches Accord file at end.
+ void setEndOfFile( bool atEOFin) {atEOF = atEOFin;}
+
+ // Set event weight; currently only for Les Houches description.
+ void setWeight( double weightIn) {weightSave = weightIn;}
+
+ // Number of times the same error message is repeated.
+ static const int TIMESTOPRINT;
+
+ // Map for all error messages.
+ map<string, int> messages;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_Info_H
--- /dev/null
+// LHAFortran.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for Fortran Les Houches Accord user process information.
+// LHAupFortran: derived class with the HEPRUP and HEPEUP Fortran info.
+// You are expected to supply the fillHepRup and fillHepEup methods.
+
+#ifndef Pythia8_LHAFortran_H
+#define Pythia8_LHAFortran_H
+
+#include "PythiaStdlib.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Give access to the HEPRUP and HEPEUP Fortran commonblocks.
+
+extern "C" {
+
+ extern struct {
+ int idbmup[2];
+ double ebmup[2];
+ int pdfgup[2], pdfsup[2], idwtup, nprup;
+ double xsecup[100], xerrup[100], xmaxup[100];
+ int lprup[100];
+ } heprup_;
+
+ extern struct {
+ int nup, idprup;
+ double xwgtup, scalup, aqedup, aqcdup;
+ int idup[500], istup[500], mothup[500][2], icolup[500][2];
+ double pup[500][5], vtimup[500],spinup[500];
+ } hepeup_;
+
+}
+
+//*********
+
+// A derived class with initialization information from the HEPRUP
+// Fortran commonblock and event information from the HEPEUP one.
+
+class LHAupFortran : public LHAup {
+
+public:
+
+ // Constructor.
+ LHAupFortran() {}
+
+ // Routine for doing the job of setting initialization info.
+ bool setInit() {
+ // Call the routine that does the job.
+ if (!fillHepRup()) return false;
+ // Store beam and strategy info.
+ setBeamA(heprup_.idbmup[0], heprup_.ebmup[0], heprup_.pdfgup[0],
+ heprup_.pdfsup[0]);
+ setBeamB(heprup_.idbmup[1], heprup_.ebmup[1], heprup_.pdfgup[1],
+ heprup_.pdfsup[1]);
+ setStrategy(heprup_.idwtup);
+ // Store process info. Protect against vanishing cross section.
+ for (int ip = 0; ip < heprup_.nprup; ++ip) {
+ double xsec = max( 1e-10, heprup_.xsecup[ip]);
+ addProcess( heprup_.lprup[ip], xsec, heprup_.xerrup[ip],
+ heprup_.xmaxup[ip] );
+ }
+ // Done.
+ return true;
+ }
+
+ // Routine for doing the job of setting info on next event.
+ bool setEvent(int idProcIn = 0) {
+ // In some strategies the type of the next event has been set.
+ hepeup_.idprup = idProcIn;
+ // Call the routine that does the job.
+ if (!fillHepEup()) return false;
+ // Store process info.
+ setProcess(hepeup_.idprup, hepeup_.xwgtup, hepeup_.scalup,
+ hepeup_.aqedup, hepeup_.aqcdup);
+ // Store particle info.
+ for (int ip = 0; ip < hepeup_.nup; ++ip) addParticle(hepeup_.idup[ip],
+ hepeup_.istup[ip], hepeup_.mothup[ip][0], hepeup_.mothup[ip][1],
+ hepeup_.icolup[ip][0], hepeup_.icolup[ip][1], hepeup_.pup[ip][0],
+ hepeup_.pup[ip][1], hepeup_.pup[ip][2], hepeup_.pup[ip][3],
+ hepeup_.pup[ip][4], hepeup_.vtimup[ip], hepeup_.spinup[ip]) ;
+ // Done.
+ return true;
+ }
+
+private:
+
+ // User-written routine that does the intialization and fills heprup.
+ bool fillHepRup();
+
+ // User-written routine that does the event generation and fills hepeup.
+ bool fillHepEup();
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_LHAFortran_H
--- /dev/null
+// LHAPDFInterface.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the LHAPDF f77 external linkage to C++.
+// All required code is contained here, i.e. there is no matching .cc file.
+
+#ifndef Pythia8_LHAPDFInterface_H
+#define Pythia8_LHAPDFInterface_H
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Declare the LHAPDF f77 subroutines that are needed.
+
+extern "C" {
+
+ extern void initpdfsetm_(int&, const char*, int);
+
+ extern void initpdfsetbynamem_(int&, const char*, int);
+
+ extern void initpdfm_(int&, int&);
+
+ extern void evolvepdfm_(int&, double&, double&, double*);
+
+ extern void setlhaparm_(const char*, int);
+
+}
+
+//**************************************************************************
+
+// Interfaces to the above routines, to make the C++ calls similar to f77.
+
+class LHAPDFInterface {
+
+public:
+
+ // Initialize set with full pathname, allowing multiple sets.
+ static void initPDFsetM( int nSet, string name) {
+ const char* cName = name.c_str(); int lenName = name.length();
+ initpdfsetm_( nSet, cName, lenName);
+ }
+
+ // Initialize set with simple name, allowing multiple sets.
+ static void initPDFsetByNameM( int nSet, string name) {
+ const char* cName = name.c_str(); int lenName = name.length();
+ initpdfsetbynamem_( nSet, cName, lenName);
+ }
+
+ // Initialize member of set.
+ static void initPDFM(int nSet, int member) {
+ initpdfm_(nSet, member);
+ }
+
+ // Evaluate x f_i(x, Q).
+ static void evolvePDFM( int nSet, double x, double Q, double* xfArray) {
+ evolvepdfm_( nSet, x, Q, xfArray);
+ }
+
+ // Extrapolate PDF set beyond boundaries, or freeze them there.
+ static void setPDFparm(string name) {
+ const char* cName = name.c_str(); int lenName = name.length();
+ setlhaparm_( cName, lenName);
+ }
+
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_LHAPDFInterface_H
--- /dev/null
+// LesHouches.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for Les Houches Accord user process information.
+// LHAup: base class for initialization and event information.
+// LHAupLHEF: derived class for reading from an Les Houches Event File.
+// Code for interfacing with Fortran commonblocks is found in LHAFortran.h.
+
+#ifndef Pythia8_LesHouches_H
+#define Pythia8_LesHouches_H
+
+#include "Event.h"
+#include "Info.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// LHAup is base class for initialization and event information
+// from an external parton-level generator.
+
+class LHAup {
+
+public:
+
+ // Destructor.
+ virtual ~LHAup() {}
+
+ // Set info pointer.
+ void setPtr(Info* infoPtrIn) {infoPtr = infoPtrIn;}
+
+ // A pure virtual method setInit, wherein all initialization information
+ // is supposed to be set in the derived class. Can do this by reading a
+ // file or some other way, as desired. Returns false if it did not work.
+ virtual bool setInit() = 0;
+
+ // Give back info on beams.
+ int idBeamA() const {return idBeamASave;}
+ int idBeamB() const {return idBeamBSave;}
+ double eBeamA() const {return eBeamASave;}
+ double eBeamB() const {return eBeamBSave;}
+ int pdfGroupBeamA() const {return pdfGroupBeamASave;}
+ int pdfGroupBeamB() const {return pdfGroupBeamBSave;}
+ int pdfSetBeamA() const {return pdfSetBeamASave;}
+ int pdfSetBeamB() const {return pdfSetBeamBSave;}
+
+ // Give back weight strategy.
+ int strategy() const {return strategySave;}
+
+ // Give back info on processes.
+ int sizeProc() const {return processes.size();}
+ int idProcess(int proc) const {return processes[proc].idProc;}
+ double xSec(int proc) const {return processes[proc].xSecProc;}
+ double xErr(int proc) const {return processes[proc].xErrProc;}
+ double xMax(int proc) const {return processes[proc].xMaxProc;}
+
+ // Print the initialization info; useful to check that setting it worked.
+ void listInit(ostream& os = cout);
+
+ // A pure virtual method setEvent, wherein information on the next event
+ // is supposed to be set in the derived class.
+ // Strategies +-1 and +-2: idProcIn is the process type, selected by PYTHIA.
+ // Strategies +-3 and +-4: idProcIn is dummy; process choice is made locally.
+ // The method can find the next event by a runtime interface to another
+ // program, or by reading a file, as desired.
+ // The method should return false if it did not work.
+ virtual bool setEvent(int idProcIn = 0) = 0;
+
+ // Give back process number, weight, scale, alpha_em, alpha_s.
+ int idProcess() const {return idProc;}
+ double weight() const {return weightProc;}
+ double scale() const {return scaleProc;}
+ double alphaQED() const {return alphaQEDProc;}
+ double alphaQCD() const {return alphaQCDProc;}
+
+ // Give back info on separate particle.
+ int sizePart() const {return particles.size();}
+ int id(int part) const {return particles[part].idPart;}
+ int status(int part) const {return particles[part].statusPart;}
+ int mother1(int part) const {return particles[part].mother1Part;}
+ int mother2(int part) const {return particles[part].mother2Part;}
+ int col1(int part) const {return particles[part].col1Part;}
+ int col2(int part) const {return particles[part].col2Part;}
+ double px(int part) const {return particles[part].pxPart;}
+ double py(int part) const {return particles[part].pyPart;}
+ double pz(int part) const {return particles[part].pzPart;}
+ double e(int part) const {return particles[part].ePart;}
+ double m(int part) const {return particles[part].mPart;}
+ double tau(int part) const {return particles[part].tauPart;}
+ double spin(int part) const {return particles[part].spinPart;}
+
+ // Optional: give back info on parton density values of event.
+ bool pdfIsSet() const {return pdfIsSetSave;}
+ int id1() const {return id1Save;}
+ int id2() const {return id2Save;}
+ double x1() const {return x1Save;}
+ double x2() const {return x2Save;}
+ double scalePDF() const {return scalePDFSave;}
+ double xpdf1() const {return xpdf1Save;}
+ double xpdf2() const {return xpdf2Save;}
+
+ // Print the info; useful to check that reading an event worked.
+ void listEvent(ostream& os = cout);
+
+ // Four routines to write a Les Houches Event file in steps.
+ bool openLHEF(string fileNameIn);
+ bool initLHEF();
+ bool eventLHEF();
+ bool closeLHEF(bool updateInit = false);
+
+protected:
+
+ // Constructor. Sets default to be that events come with unit weight.
+ LHAup(int strategyIn = 3) : strategySave(strategyIn)
+ { processes.reserve(10); particles.reserve(20); }
+
+ // Allow conversion from mb to pb.
+ static const double CONVERTMB2PB;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Input beam info.
+ void setBeamA(int idIn, double eIn, int pdfGroupIn = 0, int pdfSetIn = 0)
+ { idBeamASave = idIn; eBeamASave = eIn; pdfGroupBeamASave = pdfGroupIn;
+ pdfSetBeamASave = pdfSetIn;}
+ void setBeamB(int idIn, double eIn, int pdfGroupIn = 0, int pdfSetIn = 0)
+ { idBeamBSave = idIn; eBeamBSave = eIn; pdfGroupBeamBSave = pdfGroupIn;
+ pdfSetBeamBSave = pdfSetIn;}
+
+ // Input process weight strategy.
+ void setStrategy(int strategyIn) {strategySave = strategyIn;}
+
+ // Input process info.
+ void addProcess(int idProcIn, double xSecIn = 1., double xErrIn = 0.,
+ double xMaxIn = 1.) { processes.push_back( LHAProcess( idProcIn,
+ xSecIn, xErrIn, xMaxIn)); }
+
+ // Possibility to update some cross section info at end of run.
+ void setXSec(int iP, double xSecIn) {processes[iP].xSecProc = xSecIn;}
+ void setXErr(int iP, double xErrIn) {processes[iP].xErrProc = xErrIn;}
+ void setXMax(int iP, double xMaxIn) {processes[iP].xMaxProc = xMaxIn;}
+
+ // Input info on the selected process.
+ void setProcess(int idProcIn = 0, double weightIn = 1., double
+ scaleIn = 0., double alphaQEDIn = 0.0073, double alphaQCDIn = 0.12) {
+ idProc = idProcIn; weightProc = weightIn; scaleProc = scaleIn;
+ alphaQEDProc = alphaQEDIn; alphaQCDProc = alphaQCDIn;
+ // Clear particle list. Add empty zeroth particle for correct indices.
+ particles.clear(); addParticle(0); pdfIsSetSave = false;}
+
+ // Input particle info, one particle at the time.
+ void addParticle(int idIn, int statusIn = 0, int mother1In = 0,
+ int mother2In = 0, int col1In = 0, int col2In = 0, double pxIn = 0.,
+ double pyIn = 0., double pzIn = 0., double eIn = 0., double mIn = 0.,
+ double tauIn = 0., double spinIn = 9.) {
+ particles.push_back( LHAParticle( idIn, statusIn, mother1In, mother2In,
+ col1In, col2In, pxIn, pyIn, pzIn, eIn, mIn, tauIn, spinIn)); }
+
+ // Optionally input info on parton density values of event.
+ void setPdf(int id1In, int id2In, double x1In, double x2In,
+ double scalePDFIn, double xpdf1In, double xpdf2In)
+ { id1Save = id1In; id2Save = id2In; x1Save = x1In; x2Save = x2In;
+ scalePDFSave = scalePDFIn; xpdf1Save = xpdf1In; xpdf2Save = xpdf2In;
+ pdfIsSetSave = true;}
+
+private:
+
+ // Event weighting and mixing strategy.
+ int strategySave;
+
+ // Beam particle properties.
+ int idBeamASave, idBeamBSave;
+ double eBeamASave, eBeamBSave;
+ int pdfGroupBeamASave, pdfGroupBeamBSave, pdfSetBeamASave, pdfSetBeamBSave;
+
+ // A nested class for processes...
+ class LHAProcess {
+ public:
+ LHAProcess() : idProc(0), xSecProc(0.), xErrProc(0.), xMaxProc(0.) { }
+ LHAProcess(int idProcIn, double xSecIn, double xErrIn, double xMaxIn) :
+ idProc(idProcIn), xSecProc(xSecIn), xErrProc(xErrIn),
+ xMaxProc(xMaxIn) { }
+ int idProc;
+ double xSecProc, xErrProc, xMaxProc;
+ } ;
+
+ // ...so that the process list can be kept as a vector.
+ vector<LHAProcess> processes;
+
+ // Store info on the selected process.
+ int idProc;
+ double weightProc, scaleProc, alphaQEDProc, alphaQCDProc;
+
+ // A nested class for particles...
+ class LHAParticle {
+ public:
+ LHAParticle() : idPart(0), statusPart(0), mother1Part(0),
+ mother2Part(0), col1Part(0), col2Part(0), pxPart(0.), pyPart(0.),
+ pzPart(0.), ePart(0.), mPart(0.), tauPart(0.), spinPart(9.) { }
+ LHAParticle(int idIn, int statusIn, int mother1In, int mother2In,
+ int col1In, int col2In, double pxIn, double pyIn, double pzIn,
+ double eIn, double mIn, double tauIn, double spinIn) :
+ idPart(idIn), statusPart(statusIn), mother1Part(mother1In),
+ mother2Part(mother2In), col1Part(col1In), col2Part(col2In),
+ pxPart(pxIn), pyPart(pyIn), pzPart(pzIn), ePart(eIn), mPart(mIn),
+ tauPart(tauIn), spinPart(spinIn) { }
+ int idPart, statusPart, mother1Part, mother2Part, col1Part, col2Part;
+ double pxPart, pyPart, pzPart, ePart, mPart, tauPart, spinPart;
+ } ;
+
+ // ...so that the particle list can be kept as a vector.
+ vector<LHAParticle> particles;
+
+ // Optional info on parton density values of event.
+ bool pdfIsSetSave;
+ int id1Save, id2Save;
+ double x1Save, x2Save, scalePDFSave, xpdf1Save, xpdf2Save;
+
+ // File to which to write Les Houches Event File information.
+ string fileName;
+ fstream osLHEF;
+ char dateNow[12];
+ char timeNow[9];
+
+};
+
+//**************************************************************************
+
+// A derived class with information read from a Les Houches Event File.
+
+class LHAupLHEF : public LHAup {
+
+public:
+
+ // Constructor.
+ LHAupLHEF(const char* fileIn) : is(fileIn) {}
+
+ // Destructor.
+ ~LHAupLHEF() {}
+
+ // Routine for doing the job of reading and setting initialization info.
+ bool setInit();
+
+ // Routine for doing the job of reading and setting info on next event.
+ bool setEvent(int = 0);
+
+private:
+
+ // File from which to read.
+ ifstream is;
+
+};
+
+//**************************************************************************
+
+// A derived class with information read from PYTHIA 8 itself, for output.
+
+class LHAupFromPYTHIA8 : public LHAup {
+
+public:
+
+ // Constructor.
+ LHAupFromPYTHIA8(Event* processPtrIn, Info* infoPtrIn) {
+ processPtr = processPtrIn; infoPtr = infoPtrIn;}
+
+ // Destructor.
+ ~LHAupFromPYTHIA8() {}
+
+ // Routine for doing the job of reading and setting initialization info.
+ bool setInit();
+
+ // Routine for doing the job of reading and setting info on next event.
+ bool setEvent(int = 0);
+
+ // Update cross-section information at the end of the run.
+ bool updateSigma();
+
+private:
+
+ // Pointers to process event record and further information.
+ Event* processPtr;
+ Info* infoPtr;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_LesHouches_H
--- /dev/null
+// MiniStringFragmentation.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the class for "cluster" fragmentation.
+// MiniStringFragmentation: handle the fragmentation of low-mass systems.
+
+#ifndef Pythia8_MiniStringFragmentation_H
+#define Pythia8_MiniStringFragmentation_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "FragmentationFlavZpT.h"
+#include "FragmentationSystems.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The MiniStringFragmentation class contains the routines to fragment
+// occasional low-mass colour singlet partonic systems, where the string
+// approach is not directly applicable (for technical reasons).
+
+class MiniStringFragmentation {
+
+public:
+
+ // Constructor.
+ MiniStringFragmentation() {}
+
+ // Initialize and save pointers.
+ void init(Info* infoPtrIn, StringFlav* flavSelPtrIn);
+
+ // Do the fragmentation: driver routine.
+ bool fragment( int iSub, ColConfig& colConfig, Event& event,
+ bool isDiff = false);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRYDIFFRACTIVE, NTRYLASTRESORT, NTRYFLAV;
+ static const double SIGMAMIN;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointer to class for flavour generation.
+ StringFlav* flavSelPtr;
+
+ // Initialization data, read from Settings.
+ int nTryMass;
+ double sigma, sigma2Had, bLund;
+
+ // Data members.
+ bool isClosed;
+ double mSum, m2Sum;
+ Vec4 pSum;
+ vector<int> iParton;
+ FlavContainer flav1, flav2;
+
+ // Attempt to produce two particles from a cluster.
+ bool ministring2two( int nTry, Event& event);
+
+ // Attempt to produce one particle from a cluster.
+ bool ministring2one( int iSub, ColConfig& colConfig, Event& event);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_MiniStringFragmentation_H
--- /dev/null
+// MultipleInteractions.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the main classes for multiple interactions physics.
+// SigmaMultiple stores allowed processes by in-flavour combination.
+// MultipleInteractions: generates multiple parton-parton interactions.
+
+#ifndef Pythia8_MultipleInteractions_H
+#define Pythia8_MultipleInteractions_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Event.h"
+#include "Info.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+#include "SigmaTotal.h"
+#include "SigmaProcess.h"
+#include "StandardModel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// SigmaMultiple is a helper class to MultipleInteractions.
+// It packs pointers to the allowed processes for different
+// flavour combinations and levels of ambition.
+
+class SigmaMultiple {
+
+public:
+
+ // Constructor.
+ SigmaMultiple() {}
+
+ // Destructor.
+ ~SigmaMultiple() {
+ for (int i = 0; i < int(sigmaT.size()); ++i) delete sigmaT[i];
+ for (int i = 0; i < int(sigmaU.size()); ++i) delete sigmaU[i];}
+
+ // Initialize list of processes.
+ bool init(int inState, int processLevel);
+
+ // Calculate cross section summed over possibilities.
+ double sigma( int id1, int id2, double x1, double x2, double sHat,
+ double tHat, double uHat, double alpS, double alpEM);
+
+ // Return one subprocess, picked according to relative cross sections.
+ SigmaProcess* sigmaSel();
+ bool swapTU() {return pickedU;}
+
+ // Return code or name of a specified process, for statistics table.
+ int nProc() const {return nChan;}
+ int codeProc(int iProc) const {return sigmaT[iProc]->code();}
+ string nameProc(int iProc) const {return sigmaT[iProc]->name();}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double MASSMARGIN, OTHERFRAC;
+
+ // Number of processes. Some use massive matrix elements.
+ int nChan;
+ vector<bool> needMasses;
+ vector<double> m3Fix, m4Fix, sHatMin;
+
+ // Vector of process list, one for t-channel and one for u-channel.
+ vector<SigmaProcess*> sigmaT, sigmaU;
+
+ // Values of cross sections in process list above.
+ vector<double> sigmaTval, sigmaUval;
+ double sigmaTsum, sigmaUsum;
+ bool pickedU;
+
+};
+
+//**************************************************************************
+
+// The MultipleInteractions class contains the main methods for the
+// generation of multiple parton-parton interactions in hadronic collisions.
+
+class MultipleInteractions {
+
+public:
+
+ // Constructor.
+ MultipleInteractions() {sudExpPT.resize(NBINS+1);}
+
+ // Initialize the generation process for given beams.
+ bool init( bool doMIinit, Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn, SigmaTotal* sigmaTotPtrIn,
+ ostream& os = cout);
+
+ // Reset impact parameter choice and update the CM energy.
+ void clear() {bIsSet = false; bSetInFirst = false;
+ eCM = infoPtr->eCM(); sCM = eCM * eCM;}
+
+ // Select first = hardest pT in minbias process.
+ void pTfirst();
+
+ // Set up kinematics for first = hardest pT in minbias process.
+ void setupFirstSys( Event& process);
+
+ // Find whether to limit maximum scale of emissions.
+ bool limitPTmax( Event& event);
+
+ // Prepare system for evolution.
+ void prepare(double pTscale = 1000.) {
+ if (!bSetInFirst) overlapNext(pTscale);}
+
+ // Select next pT in downwards evolution.
+ double pTnext( double pTbegAll, double pTendAll);
+
+ // Set up kinematics of acceptable interaction.
+ void scatter( Event& event);
+
+ // Get some information on current interaction.
+ double Q2Ren() const {return pT2Ren;}
+ double alphaSH() const {return alpS;}
+ double alphaEMH() const {return alpEM;}
+ double x1H() const {return x1;}
+ double x2H() const {return x2;}
+ double Q2Fac() const {return pT2Fac;}
+ double pdf1() const {return xPDF1now;}
+ double pdf2() const {return xPDF2now;}
+ double bMI() const {return (bIsSet) ? bNow / bAvg : 0.;}
+ double enhanceMI() const {return (bIsSet) ? enhanceB / zeroIntCorr : 1.;}
+
+ // Update and print statistics on number of processes.
+ void accumulate() { int iBeg = (infoPtr->isMinBias()) ? 0 : 1;
+ for (int i = iBeg; i < infoPtr->nMI(); ++i) ++nGen[ infoPtr->codeMI(i) ];}
+ void statistics(bool reset = false, ostream& os = cout);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const bool SHIFTFACSCALE;
+ static const int NBINS;
+ static const double SIGMAFUDGE, RPT20, PT0STEP, SIGMASTEP, EXPPOWMIN,
+ PROBATLOWB, BSTEP, BMAX, EXPMAX, KCONVERGE,
+ CONVERT2MB;
+
+ // Initialization data, read from Settings.
+ int pTmaxMatch, alphaSorder, alphaEMorder, bProfile,
+ processLevel, nQuarkIn, nSample;
+ double alphaSvalue, Kfactor, pT0Ref, ecmRef, ecmPow,
+ pTmin, coreRadius, coreFraction, expPow;
+
+ // Other initialization data.
+ bool hasLowPow;
+ double eCM, sCM, pT0, pT20, pT2min, pTmax, pT2max, pT20R, pT20minR,
+ pT20maxR, pT20min0maxR, pT2maxmin, sigmaND, pT4dSigmaMax,
+ pT4dProbMax, dSigmaApprox, sigmaInt, zeroIntCorr, normOverlap,
+ nAvg, kNow, normPi, bAvg, bDiv, probLowB, radius2B, radius2C,
+ fracA, fracB, fracC, fracAhigh, fracBhigh, fracChigh, fracABChigh,
+ expRev, cDiv, cMax;
+ vector<double> sudExpPT;
+
+ // Properties specific to current system.
+ int id1, id2;
+ double bNow, enhanceB, pT2, pT2shift, pT2Ren, pT2Fac, x1, x2, xT, xT2,
+ tau, y, sHat, tHat, uHat, alpS, alpEM, xPDF1now, xPDF2now;
+ bool bIsSet, bSetInFirst, isAtLowB;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to the two incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Pointer to total cross section parametrization.
+ SigmaTotal* sigmaTotPtr;
+
+ // Collections of parton-level 2 -> 2 cross sections. Selected one.
+ SigmaMultiple sigma2gg, sigma2qg, sigma2qqbarSame, sigma2qq;
+ SigmaProcess* dSigmaDtSel;
+
+ // Statistics on generated 2 -> 2 processes.
+ map<int, int> nGen;
+
+ // alphaStrong and alphaEM calculations.
+ AlphaStrong alphaS;
+ AlphaEM alphaEM;
+
+ // Determine constant in d(Prob)/d(pT2) < const / (pT2 + r * pT20)^2.
+ void upperEnvelope();
+
+ // Integrate the parton-parton interaction cross section.
+ void jetCrossSection();
+
+ // Evaluate "Sudakov form factor" for not having a harder interaction.
+ double sudakov(double pT2sud, double enhance = 1.);
+
+ // Do a quick evolution towards the next smaller pT.
+ double fastPT2( double pT2beg);
+
+ // Calculate the actual cross section, either for the first interaction
+ // (including at initialization) or for any subsequent in the sequence.
+ double sigmaPT2(bool isFirst = false);
+
+ // Calculate factor relating matter overlap and interaction rate.
+ void overlapInit();
+
+ // Pick impact parameter and interaction rate enhancement,
+ // either before the first interaction (for minbias) or after it.
+ void overlapFirst();
+ void overlapNext(double pTscale);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_MultipleInteractions_H
--- /dev/null
+// ParticleData.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the classes containing particle data.
+// DecayChannel contains info on a single decay channel.
+// DecayTable contains all decay channels of a particle.
+// ParticleDataEntry contains info on a single particle species.
+// ParticleDataTable collects info on all particles as a map.
+
+#ifndef Pythia8_ParticleData_H
+#define Pythia8_ParticleData_H
+
+#include "Basics.h"
+#include "Info.h"
+#include "PythiaStdlib.h"
+#include "ResonanceWidths.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Forward reference to the ResonanceWidths class.
+class ResonanceWidths;
+
+//**************************************************************************
+
+// This class holds info on a single decay channel.
+
+class DecayChannel {
+
+public:
+ // Constructor.
+ DecayChannel(int onModeIn = 0, double bRatioIn = 0., int meModeIn = 0,
+ int prod0 = 0, int prod1 = 0, int prod2 = 0, int prod3 = 0,
+ int prod4 = 0, int prod5 = 0, int prod6 = 0, int prod7 = 0)
+ : onModeSave(onModeIn), bRatioSave(bRatioIn), currentBRSave(0.),
+ meModeSave(meModeIn), nProd(0), hasChangedSave(true) {
+ prod[0] = prod0; prod[1] = prod1; prod[2] = prod2; prod[3] = prod3;
+ prod[4] = prod4; prod[5] = prod5; prod[6] = prod6; prod[7] = prod7;
+ for (int j = 0; j < 8; ++j) if (prod[j] != 0 && j == nProd) ++nProd; }
+
+ // Member functions for input.
+ void onMode(int onModeIn) {onModeSave = onModeIn; hasChangedSave = true;}
+ void bRatio(double bRatioIn, bool countAsChanged = true) {
+ bRatioSave = bRatioIn; if (countAsChanged) hasChangedSave = true;}
+ void rescaleBR(double fac) {bRatioSave *= fac; hasChangedSave = true;}
+ void meMode(int meModeIn) {meModeSave = meModeIn; hasChangedSave = true;}
+ void multiplicity(int multIn) {nProd = multIn; hasChangedSave = true;}
+ void product(int i, int prodIn) {prod[i] = prodIn; nProd = 0;
+ for (int j = 0; j < 8; ++j) if (prod[j] != 0 && j == nProd) ++nProd;
+ hasChangedSave = true;}
+ void setHasChanged(bool hasChangedIn) {hasChangedSave = hasChangedIn;}
+
+ // Member functions for output.
+ int onMode() const {return onModeSave;}
+ double bRatio() const {return bRatioSave;}
+ int meMode() const {return meModeSave;}
+ int multiplicity() const {return nProd;}
+ int product(int i) const {return (i >= 0 && i < nProd) ? prod[i] : 0;}
+ bool hasChanged() const { return hasChangedSave;}
+
+ // Check for presence of particles anywhere in decay list.
+ bool contains(int id1) const;
+ bool contains(int id1, int id2) const;
+ bool contains(int id1, int id2, int id3) const;
+
+ // Input/output for current selection of decay modes.
+ // Takes into account on/off switches and dynamic width for resonances.
+ void currentBR(double currentBRIn) {currentBRSave = currentBRIn;}
+ double currentBR() const {return currentBRSave;}
+
+ // Input/output for nominal partial width; used by resonances.
+ void onShellWidth(double onShellWidthIn) {
+ onShellWidthSave = onShellWidthIn;}
+ double onShellWidth() const {return onShellWidthSave;}
+ void onShellWidthFactor(double factor) {onShellWidthSave *= factor;}
+
+ // Input/output for fraction of secondary open widths; used by resonances.
+ void openSec(int idSgn, double openSecIn) {
+ if (idSgn > 0) openSecPos = openSecIn; else openSecNeg = openSecIn;}
+ double openSec(int idSgn) const {
+ return (idSgn > 0) ? openSecPos : openSecNeg;}
+
+private:
+
+ // Decay channel info.
+ int onModeSave;
+ double bRatioSave, currentBRSave, onShellWidthSave, openSecPos,
+ openSecNeg;
+ int meModeSave, nProd, prod[8];
+ bool hasChangedSave;
+
+};
+
+//**************************************************************************
+
+// This class holds info on all decay channels of a particle.
+
+class DecayTable {
+
+public:
+
+ // Constructor.
+ DecayTable() {}
+
+ // Overload index operator to access a channel in the decay table.
+ DecayChannel& operator[](int i){return channel[i];}
+ const DecayChannel& operator[](int i) const {return channel[i];}
+
+ // Add a decay channel to the decay table.
+ void addChannel(int onMode = 0, double bRatio = 0., int meMode = 0,
+ int prod0 = 0, int prod1 = 0, int prod2 = 0, int prod3 = 0,
+ int prod4 = 0, int prod5 = 0, int prod6 = 0, int prod7 = 0) {
+ channel.push_back( DecayChannel( onMode, bRatio, meMode, prod0,
+ prod1, prod2, prod3, prod4, prod5, prod6, prod7) ); }
+
+ // Decay table size.
+ int size() const {return channel.size();}
+
+ // Reset to empty decay table..
+ void clear() {channel.resize(0);}
+
+ // Rescale sum of branching ratios to unity.
+ void rescaleBR(double newSumBR = 1.);
+
+private:
+
+ // A vector containing all the decay channels of the particle.
+ vector<DecayChannel> channel;
+
+};
+
+//**************************************************************************
+
+// This class holds info on a single particle species.
+
+class ParticleDataEntry {
+
+public:
+
+ // Constructors: for antiparticle exists or not.
+ ParticleDataEntry(int idIn = 0, string nameIn = " ",
+ int spinTypeIn = 0, int chargeTypeIn = 0, int colTypeIn = 0,
+ double m0In = 0., double mWidthIn = 0., double mMinIn = 0.,
+ double mMaxIn = 0., double tau0In = 0.) : idSave(abs(idIn)),
+ nameSave(nameIn), antiNameSave("void"), spinTypeSave(spinTypeIn),
+ chargeTypeSave(chargeTypeIn), colTypeSave(colTypeIn), m0Save(m0In),
+ mWidthSave (mWidthIn), mMinSave(mMinIn), mMaxSave(mMaxIn),
+ tau0Save(tau0In), hasAntiSave(false), hasChangedSave(true),
+ resonancePtr(0) {setDefaults();}
+ ParticleDataEntry(int idIn, string nameIn, string antiNameIn,
+ int spinTypeIn = 0, int chargeTypeIn = 0, int colTypeIn = 0,
+ double m0In = 0., double mWidthIn = 0., double mMinIn = 0.,
+ double mMaxIn = 0., double tau0In = 0.) : idSave(abs(idIn)),
+ nameSave(nameIn), antiNameSave(antiNameIn), spinTypeSave(spinTypeIn),
+ chargeTypeSave(chargeTypeIn), colTypeSave(colTypeIn), m0Save(m0In),
+ mWidthSave (mWidthIn), mMinSave(mMinIn), mMaxSave(mMaxIn),
+ tau0Save(tau0In), hasAntiSave(true), hasChangedSave(true),
+ resonancePtr(0) {setDefaults();
+ if (toLower(antiNameIn) == "void") hasAntiSave = false;}
+
+ // Destructor: delete any ResonanceWidths object.
+ ~ParticleDataEntry();
+
+ // Initialize static pointer to Info for error messages.
+ static void initPtr(Info* infoPtrIn) {infoPtr = infoPtrIn;}
+
+ // Initialize static data members.
+ static void initStatic();
+
+ // Initialization of some particle flags.
+ void setDefaults();
+
+ // Prepare for and pick mass according to Breit-Wigner.
+ void initBWmass();
+ double mass();
+
+ // Calculate running mass - for quarks only! (Else normal mass.)
+ double mRun(double mH);
+
+ // Random choice of decay channel according to branching ratios.
+ bool preparePick(int idSgn, double mHat = 0., int idInFlav = 0);
+ DecayChannel& pickChannel();
+
+ // Change current values one at a time (or set if not set before).
+ // (Must use set here since else name+signature clash with get methods.)
+ void setName(string nameIn) {nameSave = nameIn; hasChangedSave = true;}
+ void setAntiName(string antiNameIn) {antiNameSave = antiNameIn;
+ hasChangedSave = true;}
+ void setSpinType(int spinTypeIn) {spinTypeSave = spinTypeIn;
+ hasChangedSave = true;}
+ void setChargeType(int chargeTypeIn) {chargeTypeSave = chargeTypeIn;
+ hasChangedSave = true;}
+ void setColType(int colTypeIn) {colTypeSave = colTypeIn;
+ hasChangedSave = true;}
+ void setM0(double m0In) {m0Save = m0In; setConstituentMass();
+ hasChangedSave = true;}
+ void setMWidth(double mWidthIn, bool countAsChanged = true) {
+ mWidthSave = mWidthIn; if (countAsChanged) hasChangedSave = true;}
+ void setMMin(double mMinIn) {mMinSave = mMinIn; hasChangedSave = true;}
+ void setMMax(double mMaxIn) {mMaxSave = mMaxIn; hasChangedSave = true;}
+ void setTau0(double tau0In) {tau0Save = tau0In; hasChangedSave = true;}
+ void setIsResonance(bool isResonanceIn) {isResonanceSave = isResonanceIn;
+ hasChangedSave = true;}
+ void setMayDecay(bool mayDecayIn, bool countAsChanged = true) {
+ mayDecaySave = mayDecayIn; if (countAsChanged) hasChangedSave = true;}
+ void setDoExternalDecay(bool doExternalDecayIn)
+ {doExternalDecaySave = doExternalDecayIn; hasChangedSave = true;}
+ void setIsVisible(bool isVisibleIn) {isVisibleSave = isVisibleIn;
+ hasChangedSave = true;}
+ void setDoForceWidth(bool doForceWidthIn) {doForceWidthSave = doForceWidthIn;
+ hasChangedSave = true;}
+
+ // Change several values at the same time (or set if not set before).
+ void setNames(string nameIn, string antiNameIn) {nameSave = nameIn;
+ antiNameSave = antiNameIn; hasAntiSave = true; if (toLower(antiNameIn)
+ == "void") hasAntiSave = false; hasChangedSave = true;}
+ void setAll(string nameIn, string antiNameIn, int spinTypeIn = 0,
+ int chargeTypeIn = 0, int colTypeIn = 0, double m0In = 0.,
+ double mWidthIn = 0., double mMinIn = 0., double mMaxIn = 0.,
+ double tau0In = 0.)
+ {nameSave = nameIn; antiNameSave = antiNameIn; hasAntiSave = true;
+ if (toLower(antiNameIn) == "void") hasAntiSave = false;
+ spinTypeSave = spinTypeIn; chargeTypeSave = chargeTypeIn;
+ colTypeSave = colTypeIn; m0Save = m0In; mWidthSave = mWidthIn;
+ mMinSave = mMinIn; mMaxSave = mMaxIn; tau0Save = tau0In;
+ setDefaults(); hasChangedSave = true;}
+ void setHasChanged(bool hasChangedIn) {hasChangedSave = hasChangedIn;
+ for (int i = 0; i < decay.size(); ++i)
+ decay[i].setHasChanged(hasChangedIn);}
+ void rescaleBR(double newSumBR = 1.) {decay.rescaleBR(newSumBR);}
+
+ // Give back current values.
+ int id() const { return idSave; }
+ bool hasAnti() const { return hasAntiSave; }
+ string name(int idIn = 1) const {
+ return (idIn > 0) ? nameSave : antiNameSave; }
+ int spinType() const {return spinTypeSave; }
+ int chargeType(int idIn = 1) const {
+ return (idIn > 0) ? chargeTypeSave : -chargeTypeSave; }
+ double charge(int idIn = 1) const {
+ return (idIn > 0) ? chargeTypeSave / 3. : -chargeTypeSave / 3.; }
+ int colType(int idIn = 1) const {
+ if (colTypeSave == 2) return colTypeSave;
+ return (idIn > 0) ? colTypeSave : -colTypeSave; }
+ double m0() const { return m0Save; }
+ double constituentMass() const { return constituentMassSave; }
+ double mWidth() const { return mWidthSave; }
+ double mMin() const { return mMinSave; }
+ double mMax() const { return mMaxSave; }
+ double m0Min() const {
+ return (modeBWnow == 0) ? m0Save : mMinSave; }
+ double m0Max() const {
+ return (modeBWnow == 0) ? m0Save : mMaxSave; }
+ double tau0() const { return tau0Save; }
+ bool isResonance() const { return isResonanceSave; }
+ bool mayDecay() const { return mayDecaySave; }
+ bool doExternalDecay() const { return doExternalDecaySave; }
+ bool isVisible() const { return isVisibleSave; }
+ bool doForceWidth() const { return doForceWidthSave; }
+
+ // Give back other quantities.
+ bool hasChanged() const { if (hasChangedSave) return true;
+ for (int i = 0; i < decay.size(); ++i)
+ if (decay[i].hasChanged()) return true; return false;}
+ bool useBreitWigner() const { return (modeBWnow > 0); }
+ bool canDecay() const { return (decay.size() > 0);}
+ bool isLepton() const { return (idSave > 10 && idSave < 19);}
+ bool isQuark() const { return (idSave != 0 && idSave < 9);}
+ bool isGluon() const { return (idSave == 21);}
+ bool isDiquark() const { return (idSave > 1000 && idSave < 10000
+ && (idSave/10)%10 == 0);}
+ bool isHadron() const;
+ bool isMeson() const;
+ bool isBaryon() const;
+
+ // Intermediate octet ccbar or bbar states in colour-octet model.
+ bool isOctetHadron() const {return (idSave == 9900441
+ || idSave == 9900443 || idSave == 9900551 || idSave == 9900553
+ || idSave == 9910441 || idSave == 9910551); }
+ int heaviestQuark(int idIn = 1) const;
+ int baryonNumberType(int idIn = 1) const;
+
+ // The decay table.
+ DecayTable decay;
+
+ // Access methods stored in ResonanceWidths.
+ void setResonancePtr(ResonanceWidths* resonancePtrIn);
+ ResonanceWidths* getResonancePtr() const {return resonancePtr;}
+ void resInit();
+ double resWidth(int idSgn, double mHat, int idIn = 0,
+ bool openOnly = false, bool setBR = false);
+ double resWidthOpen(int idSgn, double mHat, int idIn = 0);
+ double resWidthStore(int idSgn, double mHat, int idIn = 0);
+ double resOpenFrac(int idSgn);
+ double resWidthRescaleFactor();
+ double resWidthChan(double mHat, int idAbs1 = 0, int idAbs2 = 0);
+
+private:
+
+ // Static initialization data, normally only set once.
+ static int modeBreitWigner;
+ static double maxEnhanceBW, mQRun[7], Lambda5Run;
+
+ // Constants: could only be changed in the code itself.
+ static const int INVISIBLENUMBER, INVISIBLETABLE[29];
+ static const double MAXTAU0FORDECAY,MINMASSRESONANCE, NARROWMASS,
+ CONSTITUENTMASSTABLE[6];
+
+ // Pointer to various information on the generation.
+ static Info* infoPtr;
+
+ // Particle data.
+ int idSave;
+ string nameSave, antiNameSave;
+ int spinTypeSave, chargeTypeSave, colTypeSave;
+ double m0Save, mWidthSave, mMinSave, mMaxSave, tau0Save,
+ constituentMassSave;
+ bool hasAntiSave, isResonanceSave, mayDecaySave, doExternalDecaySave,
+ isVisibleSave, doForceWidthSave, hasChangedSave;
+
+ // Extra data for mass selection according to a Breit-Wigner.
+ int modeBWnow;
+ double atanLow, atanDif, mThr;
+
+ // Summed branching ratio of currently open channels.
+ double currentBRSum;
+
+ // Pointer to ResonanceWidths object; only used for some particles.
+ ResonanceWidths* resonancePtr;
+
+ // Set constituent mass.
+ void setConstituentMass();
+
+ // Useful functions for string handling.
+ static string toLower(const string& name);
+
+};
+
+//**************************************************************************
+
+// This class holds a map of all ParticleDataEntries.
+
+class ParticleDataTable {
+
+public:
+
+ // Constructor.
+ ParticleDataTable() {}
+
+ // Initialize static pointer.
+ static void initPtr(Info* infoPtrIn) {infoPtr = infoPtrIn;}
+
+ // Read in database from specific file.
+ static bool init(string startFile = "../xmldoc/ParticleData.xml") {
+ return readXML(startFile);}
+
+ // Overwrite existing database by reading from specific file.
+ static bool reInit(string startFile, bool xmlFormat = true) {
+ return (xmlFormat) ? readXML(startFile) : readFF(startFile);}
+
+ // Initialize the handling of Breit-Wigner mass selection.
+ static void initBWmass() {
+ for (map<int, ParticleDataEntry>::iterator pdtEntry = pdt.begin();
+ pdtEntry != pdt.end(); ++pdtEntry) pdtEntry->second.initBWmass(); }
+
+ // Initialize the special handling of resonances in ResonanceWidths.
+ static void initResonances(vector<ResonanceWidths*> resonancePtrs,
+ bool reInit = false);
+
+ // Calculate a mass, picked according to Breit-Wigner.
+ static double mass(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].mass() : 0. ; }
+
+ // Calculate running mass - for quarks only! (Else normal mass.)
+ static double mRun(int idIn, double mH) {
+ return isParticle(idIn) ? pdt[abs(idIn)].mRun(mH) : 0. ; }
+
+ // Read or list whole (or part of) database from/to an XML file.
+ static bool readXML(string inFile, bool reset = true) ;
+ static void listXML(string outFile) ;
+
+ // Read or list whole (or part of) database from/to a free format file.
+ static bool readFF(string inFile, bool reset = true) ;
+ static void listFF(string outFile) ;
+
+ // Read in one update from a single line.
+ static bool readString(string lineIn, bool warn = true,
+ ostream& os = cout) ;
+
+ // Print out table of whole database, or of only part of it.
+ static void listAll(ostream& os = cout) {list(false, true, os);}
+ static void listChanged(ostream& os = cout) {list(true, false, os);}
+ static void listChanged(bool changedRes, ostream& os = cout)
+ {list(true, changedRes, os);}
+ static void list(bool changedOnly = false, bool changedRes = true,
+ ostream& os = cout) ;
+ static void list(int idList, ostream& os = cout) {
+ vector<int> idListTemp; idListTemp.push_back(idList);
+ list( idListTemp, os);}
+ static void list(vector<int> idList, ostream& os = cout) ;
+
+ // Check that table makes sense, especially for decays.
+ static void checkTable(ostream& os = cout) {checkTable(1, os);};
+ static void checkTable(int verbosity, ostream& os = cout) ;
+
+ // Add new entry.
+ static void addParticle(int idIn, string nameIn = " ",
+ int spinTypeIn = 0, int chargeTypeIn = 0, int colTypeIn = 0,
+ double m0In = 0., double mWidthIn = 0., double mMinIn = 0.,
+ double mMaxIn = 0., double tau0In = 0.)
+ { pdt[abs(idIn)] = ParticleDataEntry(idIn, nameIn, spinTypeIn,
+ chargeTypeIn, colTypeIn, m0In, mWidthIn, mMinIn, mMaxIn, tau0In); }
+ static void addParticle(int idIn, string nameIn, string antiNameIn,
+ int spinTypeIn = 0, int chargeTypeIn = 0, int colTypeIn = 0,
+ double m0In = 0., double mWidthIn = 0., double mMinIn = 0.,
+ double mMaxIn = 0., double tau0In = 0.)
+ { pdt[abs(idIn)] = ParticleDataEntry(idIn, nameIn, antiNameIn,
+ spinTypeIn, chargeTypeIn, colTypeIn, m0In, mWidthIn, mMinIn,
+ mMaxIn, tau0In); }
+
+ // Query existence of an entry.
+ static bool isParticle(int idIn) {
+ if (pdt.find(abs(idIn)) == pdt.end()) return false;
+ if (idIn > 0 || pdt[abs(idIn)].hasAnti()) return true;
+ return false; }
+
+ // Return pointer to entry.
+ static ParticleDataEntry* particleDataPtr(int idIn) {
+ return (isParticle(idIn)) ? &pdt[abs(idIn)] : &pdt[0]; }
+
+ // Return the id of the sequentially next particle stored in table.
+ static int nextId(int idIn) ;
+
+ // Change current values one at a time (or set if not set before).
+ static void name(int idIn, string nameIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setName(nameIn); }
+ static void antiName(int idIn, string antiNameIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setAntiName(antiNameIn); }
+ static void spinType(int idIn, int spinTypeIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setSpinType(spinTypeIn); }
+ static void chargeType(int idIn, int chargeTypeIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setChargeType(chargeTypeIn); }
+ static void colType(int idIn, int colTypeIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setColType(colTypeIn); }
+ static void m0(int idIn, double m0In) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setM0(m0In); }
+ static void mWidth(int idIn, double mWidthIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setMWidth(mWidthIn); }
+ static void mMin(int idIn, double mMinIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setMMin(mMinIn); }
+ static void mMax(int idIn, double mMaxIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setMMax(mMaxIn); }
+ static void tau0(int idIn, double tau0In) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setTau0(tau0In); }
+ static void isResonance(int idIn, bool isResonanceIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setIsResonance(isResonanceIn); }
+ static void mayDecay(int idIn, bool mayDecayIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setMayDecay(mayDecayIn); }
+ static void doExternalDecay(int idIn, bool doExternalDecayIn) {
+ if (isParticle(idIn))
+ pdt[abs(idIn)].setDoExternalDecay(doExternalDecayIn); }
+ static void isVisible(int idIn, bool isVisibleIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setIsVisible(isVisibleIn); }
+ static void doForceWidth(int idIn, bool doForceWidthIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setDoForceWidth(doForceWidthIn); }
+
+ // Change several values at the same time (or set if not set before).
+ static void names(int idIn, string nameIn, string antiNameIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setNames(nameIn, antiNameIn); }
+ static void setAll(int idIn, string nameIn, string antiNameIn,
+ int spinTypeIn = 0, int chargeTypeIn = 0, int colTypeIn = 0,
+ double m0In = 0., double mWidthIn = 0., double mMinIn = 0.,
+ double mMaxIn = 0.,double tau0In = 0.)
+ { if (isParticle(idIn)) pdt[abs(idIn)].setAll( nameIn, antiNameIn,
+ spinTypeIn, chargeTypeIn, colTypeIn, m0In, mWidthIn, mMinIn, mMaxIn,
+ tau0In); }
+ static void hasChanged(int idIn, bool hasChangedIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].setHasChanged(hasChangedIn); }
+ static void rescaleBR(int idIn, double newSumBR = 1.) {
+ if (isParticle(idIn)) pdt[abs(idIn)].rescaleBR(newSumBR); }
+
+ // Give back current values.
+ static bool hasAnti(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].hasAnti() : false ; }
+ static string name(int idIn) {
+ return (isParticle(abs(idIn))) ? pdt[abs(idIn)].name(idIn) : " "; }
+ static int spinType(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].spinType() : 0 ; }
+ static int chargeType(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].chargeType(idIn) : 0 ; }
+ static double charge(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].charge(idIn) : 0 ; }
+ static int colType(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].colType(idIn) : 0 ; }
+ static double m0(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].m0() : 0. ; }
+ static double constituentMass(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].constituentMass() : 0. ; }
+ static double mWidth(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].mWidth() : 0. ; }
+ static double mMin(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].mMin() : 0. ; }
+ static double m0Min(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].m0Min() : 0. ; }
+ static double mMax(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].mMax() : 0. ; }
+ static double m0Max(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].m0Max() : 0. ; }
+ static double tau0(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].tau0() : 0. ; }
+ static bool isResonance(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isResonance() : false ; }
+ static bool mayDecay(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].mayDecay() : false ; }
+ static bool doExternalDecay(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].doExternalDecay() : false ; }
+ static bool isVisible(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isVisible() : false ; }
+ static bool doForceWidth(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].doForceWidth() : false ; }
+
+ // Give back other quantities.
+ static bool hasChanged(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].hasChanged() : false ; }
+ static bool useBreitWigner(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].useBreitWigner() : false ; }
+ static bool canDecay(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].canDecay() : false ; }
+ static bool isLepton(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isLepton() : false ; }
+ static bool isQuark(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isQuark() : false ; }
+ static bool isGluon(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isGluon() : false ; }
+ static bool isDiquark(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isDiquark() : false ; }
+ static bool isHadron(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isHadron() : false ; }
+ static bool isMeson(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isMeson() : false ; }
+ static bool isBaryon(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isBaryon() : false ; }
+ static bool isOctetHadron(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].isOctetHadron() : false ; }
+ static int heaviestQuark(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].heaviestQuark(idIn) : 0 ; }
+ static int baryonNumberType(int idIn) {
+ return isParticle(idIn) ? pdt[abs(idIn)].baryonNumberType(idIn) : 0 ; }
+
+ // Access methods stored in ResonanceWidths.
+ static void resInit(int idIn) {
+ if (isParticle(idIn)) pdt[abs(idIn)].resInit();}
+ static double resWidth(int idIn, double mHat, int idInFlav = 0,
+ bool openOnly = false, bool setBR = false) {
+ return isParticle(idIn) ? pdt[abs(idIn)].resWidth(idIn, mHat,
+ idInFlav, openOnly, setBR) : 0.;}
+ static double resWidthOpen(int idIn, double mHat, int idInFlav = 0) {
+ return isParticle(idIn) ? pdt[abs(idIn)].resWidthOpen(idIn, mHat,
+ idInFlav) : 0.;}
+ static double resWidthStore(int idIn, double mHat, int idInFlav = 0) {
+ return isParticle(idIn) ? pdt[abs(idIn)].resWidthStore(idIn, mHat,
+ idInFlav) : 0.;}
+ static double resOpenFrac(int id1In, int id2In = 0, int id3In = 0);
+ static double resWidthRescaleFactor(int idIn) { return isParticle(idIn)
+ ? pdt[abs(idIn)].resWidthRescaleFactor() : 0.;}
+ static double resWidthChan(int idIn, double mHat, int idAbs1 = 0,
+ int idAbs2 = 0) { return isParticle(idIn)
+ ? pdt[abs(idIn)].resWidthChan( mHat, idAbs1, idAbs2) : 0.;}
+
+private:
+
+ // Pointer to various information on the generation.
+ static Info* infoPtr;
+
+ // All particle data stored in a map.
+ static map<int, ParticleDataEntry> pdt;
+
+ // Pointer to current particle (e.g. when reading decay channels).
+ static ParticleDataEntry* particlePtr;
+
+ // Flag that initialization has been performed.
+ static bool isInit;
+
+ // Useful functions for string handling.
+ static string toLower(const string& name);
+ static bool boolString(string tag);
+ static string attributeValue(string line, string attribute);
+ static bool boolAttributeValue(string line, string attribute);
+ static int intAttributeValue(string line, string attribute);
+ static double doubleAttributeValue(string line, string attribute);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_ParticleData_H
--- /dev/null
+// ParticleDecays.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the classes to perform a particle decay.
+// DecayHandler: base class for external handling of decays.
+// ParticleDecays: decay a particle.
+
+#ifndef Pythia8_ParticleDecays_H
+#define Pythia8_ParticleDecays_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "FragmentationFlavZpT.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+#include "TimeShower.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// DecayHandler is base class for the external handling of decays.
+// There is only one pure virtual method, that should do the decay.
+
+class DecayHandler {
+
+public:
+
+ // A pure virtual method, wherein the derived class method does a decay.
+ virtual bool decay(vector<int>& idProd, vector<double>& mProd,
+ vector<Vec4>& pProd, int iDec, const Event& event) = 0;
+
+protected:
+
+ // Destructor.
+ virtual ~DecayHandler() {}
+
+};
+
+//**************************************************************************
+
+// The ParticleDecays class contains the routines to decay a particle.
+
+class ParticleDecays {
+
+public:
+
+ // Constructor.
+ ParticleDecays() {}
+
+ // Initialize: store pointers and find settings
+ void init(Info* infoPtrIn, TimeShower* timesDecPtrIn,
+ StringFlav* flavSelPtrIn, DecayHandler* decayHandlePtrIn,
+ vector<int> handledParticles);
+
+ // Perform a decay of a single particle.
+ bool decay(int iDec, Event& event);
+
+ // Did decay result in new partons to hadronize?
+ bool moreToDo() const {return hasPartons && keepPartons;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRYDECAY, NTRYPICK;
+ static const double MSAFEDALITZ, WTCORRECTION[11];
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to timelike showers, for decays to partons (e.g. Upsilon).
+ TimeShower* timesDecPtr;
+
+ // Pointer to class for flavour generation; needed when to pick hadrons.
+ StringFlav* flavSelPtr;
+
+ // Pointer to a handler of external decays.
+ DecayHandler* decayHandlePtr;
+
+ // Initialization data, read from Settings..
+ bool limitTau0, limitTau, limitRadius, limitCylinder, limitDecay,
+ mixB, doFSRinDecays;
+ double mSafety, tau0Max, tauMax, rMax, xyMax, zMax, xBdMix, xBsMix,
+ sigmaSoft, multIncrease, multRefMass, multGoffset, colRearrange,
+ stopMass, sRhoDal, wRhoDal;
+
+ // Multiplicity. Decay products positions and masses.
+ bool hasPartons, keepPartons;
+ int idDec, meMode, mult;
+ vector<int> iProd, idProd, cols, acols, idPartons;
+ vector<double> mProd, mInv, rndmOrd;
+ vector<Vec4> pInv, pProd;
+ vector<FlavContainer> flavEnds;
+
+ // Pointer to particle data for currently decaying particle
+ ParticleDataEntry* decDataPtr;
+
+ // Check whether a decay is allowed, given the upcoming decay vertex.
+ bool checkVertex(Particle& decayer);
+
+ // Check for oscillations B0 <-> B0bar or B_s0 <-> B_s0bar.
+ bool oscillateB(Particle& decayer);
+
+ // Do a one-body decay.
+ bool oneBody(Event& event);
+
+ // Do a two-body decay;
+ bool twoBody(Event& event);
+
+ // Do a three-body decay;
+ bool threeBody(Event& event);
+
+ // Do a multibody decay using the M-generator algorithm.
+ bool mGenerator(Event& event);
+
+ // Select mass of lepton pair in a Dalitz decay.
+ bool dalitzMass();
+
+ // Do kinematics of gamma* -> l- l+ in Dalitz decay.
+ bool dalitzKinematics(Event& event);
+
+ // Translate a partonic content into a set of actual hadrons.
+ bool pickHadrons();
+
+ // Set colour flow and scale in a decay explicitly to partons.
+ bool setColours(Event& event);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_ParticleDecays_H
--- /dev/null
+// PartonDistributions.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for parton densities.
+// PDF: base class.
+// GRV94L: derived class for the GRV 94L parton densities.
+// CTEQ5L: derived class for the CTEQ 5L parton densities.
+// LHAPDFinterface: derived class for interface to the LHAPDF library.
+// Lepton: derived class for parton densities inside a lepton.
+// LeptonPoint: derived class for unresolved lepton (mainly dummy).
+
+#ifndef Pythia8_PartonDistributions_H
+#define Pythia8_PartonDistributions_H
+
+#include "Basics.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Base class for parton distribution functions.
+
+class PDF {
+
+public:
+
+ // Constructor.
+ PDF(int idBeamIn = 2212) {idBeam = idBeamIn; idSav = 9; xSav = -1.;
+ Q2Sav = -1.; isSet = true; isInit = false;}
+
+ // Destructor.
+ virtual ~PDF() {}
+
+ // Confirm that PDF has been set up (important for LHAPDF).
+ bool isSetup() {return isSet;}
+
+ // Allow extrapolation beyond boundaries. This is optional.
+ virtual void setExtrapolate(bool) {}
+
+ // Read out parton density
+ double xf(int id, double x, double Q2);
+
+ // Read out valence and sea part of parton densities.
+ double xfVal(int id, double x, double Q2);
+ double xfSea(int id, double x, double Q2);
+
+protected:
+
+ // Store relevant quantities.
+ int idBeam, idSav;
+ double xSav, Q2Sav;
+ double xu, xd, xubar, xdbar, xs, xc, xb, xg, xlepton, xgamma,
+ xuVal, xuSea, xdVal, xdSea;
+ bool isSet, isInit, hasLimits;
+
+ // Update parton densities.
+ virtual void xfUpdate(int id, double x, double Q2) = 0;
+
+};
+
+//**************************************************************************
+
+// Gives the GRV 94 L (leading order) parton distribution function set
+// in parametrized form. Authors: M. Glueck, E. Reya and A. Vogt.
+
+class GRV94L : public PDF {
+
+public:
+
+ // Constructor.
+ GRV94L(int idBeamIn = 2212) : PDF(idBeamIn) {}
+
+private:
+
+ // Update PDF values.
+ void xfUpdate(int id, double x, double Q2);
+
+ // Auxiliary routines used during the updating.
+ double grvv (double x, double n, double ak, double bk, double a,
+ double b, double c, double d);
+ double grvw (double x, double s, double al, double be, double ak,
+ double bk, double a, double b, double c, double d, double e, double es);
+ double grvs (double x, double s, double sth, double al, double be,
+ double ak, double ag, double b, double d, double e, double es);
+
+};
+
+//**************************************************************************
+
+// Gives the GRV 94 L (leading order) parton distribution function set
+// in parametrized form. Authors: M. Glueck, E. Reya and A. Vogt.
+
+class CTEQ5L : public PDF {
+
+public:
+
+ // Constructor.
+ CTEQ5L(int idBeamIn = 2212) : PDF(idBeamIn) {}
+
+private:
+
+ // Update PDF values.
+ void xfUpdate(int id, double x, double Q2);
+
+};
+
+//**************************************************************************
+
+// Provide interface to the LHAPDF library of parton densities.
+
+class LHAPDF : public PDF {
+
+public:
+
+ // Constructor.
+ LHAPDF(int idBeamIn, string setName, int member, int nSetIn = 1,
+ Info* infoPtr = 0) : PDF(idBeamIn), nSet(nSetIn)
+ {init( setName, member, infoPtr);}
+
+ // Allow extrapolation beyond boundaries. This is optional.
+ void setExtrapolate(bool extrapol);
+
+private:
+
+ // Initialization of PDF set.
+ void init(string setName, int member, Info* infoPtr);
+
+ // Update all PDF values.
+ void xfUpdate(int , double x, double Q2);
+
+ // Current set and pdf values.
+ int nSet;
+ double xfArray[13];
+
+ // Keep track of latest initialized PDF, so does not have to repeat.
+ static string latestSetName;
+ static int latestMember, latestNSet;
+
+};
+
+//**************************************************************************
+
+// Gives electron (or muon, or tau) parton distribution.
+
+class Lepton : public PDF {
+
+public:
+
+ // Constructor.
+ Lepton(int idBeamIn = 11) : PDF(idBeamIn) {}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double ALPHAEM;
+
+ // Update PDF values.
+ void xfUpdate(int id, double x, double Q2);
+
+ // The lepton mass, set at initialization.
+ double m2Lep;
+
+};
+
+//**************************************************************************
+
+// Gives electron (or other lepton) parton distribution when unresolved.
+
+class LeptonPoint : public PDF {
+
+public:
+
+ // Constructor.
+ LeptonPoint(int idBeamIn = 11) : PDF(idBeamIn) {}
+
+private:
+
+ // Update PDF values in trivial way.
+ void xfUpdate(int , double , double ) {xlepton = 1; xgamma = 0.;}
+
+};
+
+} // end namespace Pythia8
+
+//**************************************************************************
+
+#endif // Pythia8_PartonDistributions_H
--- /dev/null
+// PartonLevel.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the main class for parton-level event generation
+// PartonLevel: administrates showers, multiple interactions and remnants.
+
+#ifndef Pythia8_PartonLevel_H
+#define Pythia8_PartonLevel_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "BeamRemnants.h"
+#include "Event.h"
+#include "Info.h"
+#include "MultipleInteractions.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+#include "SigmaTotal.h"
+#include "SpaceShower.h"
+#include "TimeShower.h"
+#include "UserHooks.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The PartonLevel class contains the top-level routines to generate
+// the partonic activity of an event.
+
+class PartonLevel {
+
+public:
+
+ // Constructor.
+ PartonLevel() : userHooksPtr(0) {}
+
+ // Initialization of all classes at the parton level.
+ bool init( Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn, SigmaTotal* sigmaTotPtr,
+ TimeShower* timesDecPtrIn, TimeShower* timesPtrIn,
+ SpaceShower* spacePtrIn, UserHooks* userHooksPtrIn);
+
+ // Generate the next parton-level process.
+ bool next( Event& process, Event& event);
+
+ // Tell whether failure was due to vetoing.
+ bool hasVetoed() const {return doVeto;}
+
+ // Accumulate and print statistics.
+ void accumulate() {multi.accumulate();}
+ void statistics(bool reset = false) {if (doMI) multi.statistics(reset);}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRY;
+
+ // Initialization data, mainly read from Settings.
+ bool doMI, doISR, doFSRduringProcess, doFSRafterProcess,
+ doFSRinResonances, doRemnants, doSecondHard, doMIinit,
+ hasLeptonBeams, hasPointLeptons, canVetoPT, canVetoStep;
+
+ // Event generation strategy. Number of steps. Maximum pT scales.
+ bool doVeto;
+ int nMI, nISR, nFSRinProc, nFSRinRes, nISRhard, nFSRhard,
+ typeLatest, nVetoStep, typeVetoStep, iSysNow;
+ double pTsaveMI, pTsaveISR, pTsaveFSR, pTvetoPT;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to the two incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Pointer to userHooks object for user interaction with program.
+ UserHooks* userHooksPtr;
+
+ // Pointers to timelike showers for resonance decays and the rest.
+ TimeShower* timesDecPtr;
+ TimeShower* timesPtr;
+
+ // Pointer to spacelike showers.
+ SpaceShower* spacePtr;
+
+ // The generator class for multiple interactions.
+ MultipleInteractions multi;
+
+ // The generator class to construct beam-remnant kinematics.
+ BeamRemnants remnants;
+
+ // Set up the hard process, excluding subsequent resonance decays.
+ void setupHardSys( Event& process, Event& event);
+ // Keep track of how much of hard process has been handled.
+ int nHardDone;
+
+ // Set up an unresolved process, i.e. elastic or diffractive.
+ bool setupUnresolvedSys( Event& process, Event& event);
+
+ // Perform showers in resonance decay chains.
+ int resonanceShowers( Event& process, Event& event);
+ // Position in main event record of hard partons before showers.
+ vector<int> iPosBefShow;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_PartonLevel_H
--- /dev/null
+// PhaseSpace.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for phase space generators in kinematics selection.
+// PhaseSpace: base class for phase space generators.
+// Base class for derived classes> 2 ->1 , 2 -> 2, 2 -> 2 elastic/diffractive,
+// 2 -> 2 minbias, 2 -> 3, Les Houches.
+
+#ifndef Pythia8_PhaseSpace_H
+#define Pythia8_PhaseSpace_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Info.h"
+#include "LesHouches.h"
+#include "MultipleInteractions.h"
+#include "ParticleData.h"
+#include "PartonDistributions.h"
+#include "PythiaStdlib.h"
+#include "SigmaProcess.h"
+#include "SigmaTotal.h"
+#include "Settings.h"
+#include "UserHooks.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Forward reference to the UserHooks class.
+class UserHooks;
+
+//**************************************************************************
+
+// PhaseSpace is a base class for phase space generators
+// used in the selection of hard-process kinematics.
+
+class PhaseSpace {
+
+public:
+
+ // Destructor.
+ virtual ~PhaseSpace() {}
+
+ // Perform simple initialization and store pointers.
+ void init(SigmaProcess* sigmaProcessPtrIn, Info* infoPtrIn,
+ BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
+ SigmaTotal* sigmaTotPtrIn, UserHooks* userHooksPtrIn);
+
+ // Update the CM energy of the event.
+ void newECM(double eCMin) {eCM = eCMin; s = eCM * eCM;}
+
+ // Store or replace Les Houches pointer.
+ void setLHAPtr(LHAup* lhaUpPtrIn) {lhaUpPtr = lhaUpPtrIn;}
+
+ // A pure virtual method, wherein an optimization procedure
+ // is used to determine how phase space should be sampled.
+ virtual bool setupSampling() = 0;
+
+ // A pure virtual method, wherein a trial event kinematics
+ // is to be selected in the derived class
+ virtual bool trialKin(bool inEvent = true, bool repeatSame = false) = 0;
+
+ // A pure virtual method, wherein the accepted event kinematics
+ // is to be constructed in the derived class
+ virtual bool finalKin() = 0;
+
+ // Allow for nonisotropic decays when ME's available.
+ void decayKinematics( Event& process);
+
+ // Give back current or maximum cross section, or set latter.
+ double sigmaNow() const {return sigmaNw;}
+ double sigmaMax() const {return sigmaMx;}
+ bool newSigmaMax() const {return newSigmaMx;}
+ void setSigmaMax(double sigmaMaxIn) {sigmaMx = sigmaMaxIn;}
+
+ // For Les Houches with negative event weight needs
+ virtual double sigmaSumSigned() const {return sigmaMx;}
+
+ // Give back constructed four-vectors and known masses.
+ Vec4 p(int i) const {return pH[i];}
+ double m(int i) const {return mH[i];}
+
+ // Give back other event properties.
+ double ecm() const {return eCM;}
+ double x1() const {return x1H;}
+ double x2() const {return x2H;}
+ double sHat() const {return sH;}
+ double tHat() const {return tH;}
+ double uHat() const {return uH;}
+ double pTHat() const {return pTH;}
+ double thetaHat() const {return theta;}
+ double phiHat() const {return phi;}
+ double runBW3() const {return runBW3H;}
+ double runBW4() const {return runBW4H;}
+ double runBW5() const {return runBW5H;}
+
+ // Inform whether beam particles are resolved in partons or scatter directly.
+ virtual bool isResolved() const {return true;}
+
+protected:
+
+ // Constructor.
+ PhaseSpace() {}
+
+ // Constants: could only be changed in the code itself.
+ static const int NMAXTRY, NTRY3BODY;
+ static const double SAFETYMARGIN, TINY, EVENFRAC, SAMESIGMA, WIDTHMARGIN,
+ SAMEMASS, MASSMARGIN, EXTRABWWTMAX, THRESHOLDSIZE,
+ THRESHOLDSTEP, YRANGEMARGIN, LEPTONXMIN, LEPTONXMAX,
+ LEPTONXLOGMIN, LEPTONXLOGMAX, LEPTONTAUMIN,
+ SHATMINZ, PT2RATMINZ, WTCORRECTION[11];
+
+ // Pointer to cross section.
+ SigmaProcess* sigmaProcessPtr;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Pointer to the total/elastic/diffractive cross section object.
+ SigmaTotal* sigmaTotPtr;
+
+ // Pointer to userHooks object for user interaction with program.
+ UserHooks* userHooksPtr;
+
+ // Pointer to LHAup for generating external events.
+ LHAup* lhaUpPtr;
+
+ // Initialization data, normally only set once.
+ bool useBreitWigners, doEnergySpread, showSearch, showViolation;
+ int gmZmodeGlobal;
+ double mHatGlobalMin, mHatGlobalMax, pTHatGlobalMin, pTHatGlobalMax,
+ pTHatMinDiverge, minWidthBreitWigners;
+
+ // Information on incoming beams.
+ int idA, idB;
+ double mA, mB, eCM, s;
+ bool hasLeptonBeams, hasPointLeptons;
+ // Cross section information.
+ bool newSigmaMx, canModifySigma;
+ int gmZmode;
+ double wtBW, sigmaNw, sigmaMx, sigmaNeg;
+
+ // Process-specific kinematics properties, almost always available.
+ double mHatMin, mHatMax, sHatMin, sHatMax, pTHatMin, pTHatMax,
+ pT2HatMin, pT2HatMax;
+
+ // Event-specific kinematics properties, almost always available.
+ double x1H, x2H, m3, m4, m5, s3, s4, s5, mHat, sH, tH, uH, pAbs, p2Abs,
+ pTH, theta, phi, betaZ;
+ Vec4 pH[6];
+ double mH[6];
+
+ // Reselect decay products momenta isotropically in phase space.
+ void decayKinematicsStep( Event& process, int iRes);
+
+ // Much common code for normal 2 -> 1, 2 -> 2 and 2 -> 3 cases:
+
+ // Determine how phase space should be sampled.
+ void setup3Body();
+ bool setupSampling123(bool is2, bool is3, ostream& os = cout);
+
+ // Select a trial kinematics phase space point.
+ bool trialKin123(bool is2, bool is3, bool inEvent = true, ostream& os = cout);
+
+ // Presence and properties of any s-channel resonances.
+ int idResA, idResB;
+ double mResA, mResB, GammaResA, GammaResB, tauResA, tauResB, widResA,
+ widResB;
+ bool sameResMass;
+
+ // Kinematics properties specific to 2 -> 1/2/3.
+ bool useMirrorWeight;
+ double tau, y, z, tauMin, tauMax, yMax, zMin, zMax, ratio34, unity34,
+ zNeg, zPos, wtTau, wtY, wtZ, wt3Body, runBW3H, runBW4H, runBW5H,
+ intTau0, intTau1, intTau2, intTau3, intTau4, intTau5, intTau6,
+ intY01, intY2, intY34, mTchan1, sTchan1, mTchan2, sTchan2,
+ frac3Flat, frac3Pow1, frac3Pow2;
+ Vec4 p3cm, p4cm, p5cm;
+
+ // Coefficients for optimized selection in 2 -> 1/2/3.
+ int nTau, nY, nZ;
+ double tauCoef[8], yCoef[8], zCoef[8], tauCoefSum[8], yCoefSum[8],
+ zCoefSum[8];
+
+ // Calculate kinematical limits for 2 -> 1/2/3.
+ bool limitTau(bool is2, bool is3);
+ bool limitY();
+ bool limitZ();
+
+ // Select kinematical variable between defined limits for 2 -> 1/2/3.
+ void selectTau(int iTau, double tauVal, bool is2);
+ void selectY(int iY, double yVal);
+ void selectZ(int iZ, double zVal);
+ bool select3Body();
+
+ // Solve equation system for better phase space coefficients in 2 -> 1/2/3.
+ void solveSys( int n, int bin[8], double vec[8], double mat[8][8],
+ double coef[8], ostream& os = cout);
+
+ // Properties specific to resonance mass selection in 2 -> 2 and 2 -> 3.
+ bool useBW[6];
+ int idMass[6];
+ double mPeak[6], sPeak[6], mWidth[6], mMin[6], mMax[6], mw[6], wmRat[6],
+ mLower[6], mUpper[6], sLower[6], sUpper[6], fracFlat[6], fracInv[6],
+ fracInv2[6], atanLower[6], atanUpper[6], intBW[6], intFlat[6],
+ intInv[6], intInv2[6];
+
+ // Setup mass selection for one resonance at a time. Split in two parts.
+ void setupMass1(int iM);
+ void setupMass2(int iM, double distToThresh);
+
+ // Do mass selection and find the associated weight.
+ void trialMass(int iM);
+ double weightMass(int iM);
+
+};
+
+//**************************************************************************
+
+// A derived class with 2 -> 1 kinematics set up in tau, y.
+
+class PhaseSpace2to1tauy : public PhaseSpace {
+
+public:
+
+ // Constructor.
+ PhaseSpace2to1tauy() {}
+
+ // Optimize subsequent kinematics selection.
+ virtual bool setupSampling() {if (!setupMass()) return false;
+ return setupSampling123(false, false);}
+
+ // Construct the trial kinematics.
+ virtual bool trialKin(bool inEvent = true, bool = false) {wtBW = 1.;
+ return trialKin123(false, false, inEvent);}
+
+ // Construct the final event kinematics.
+ virtual bool finalKin();
+
+private:
+
+ // Set up allowed mass range.
+ bool setupMass();
+
+};
+
+//**************************************************************************
+
+// A derived class with 2 -> 2 kinematics set up in tau, y, z = cos(theta).
+
+class PhaseSpace2to2tauyz : public PhaseSpace {
+
+public:
+
+ // Constructor.
+ PhaseSpace2to2tauyz() {}
+
+ // Optimize subsequent kinematics selection.
+ virtual bool setupSampling() {if (!setupMasses()) return false;
+ return setupSampling123(true, false);}
+
+ // Construct the trial kinematics.
+ virtual bool trialKin(bool inEvent = true, bool = false) {
+ if (!trialMasses()) return false;
+ return trialKin123(true, false, inEvent);}
+
+ // Construct the final event kinematics.
+ virtual bool finalKin();
+
+private:
+
+ // Set up for fixed or Breit-Wigner mass selection.
+ bool setupMasses();
+
+ // Select fixed or Breit-Wigner-distributed masses.
+ bool trialMasses();
+
+ // Pick off-shell initialization masses when on-shell not allowed.
+ bool constrainedM3M4();
+ bool constrainedM3();
+ bool constrainedM4();
+
+};
+
+//**************************************************************************
+
+// A derived class with 2 -> 2 kinematics set up for elastic scattering.
+
+class PhaseSpace2to2elastic : public PhaseSpace {
+
+public:
+
+ // Constructor.
+ PhaseSpace2to2elastic() {}
+
+ // Construct the trial or final event kinematics.
+ virtual bool setupSampling();
+ virtual bool trialKin(bool inEvent = true, bool = false);
+ virtual bool finalKin();
+
+ // Are beam particles resolved in partons or scatter directly?
+ virtual bool isResolved() const {return false;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double EXPMAX, CONVERTEL;
+
+ // Kinematics properties specific to 2 -> 2 elastic.
+ bool useCoulomb;
+ double s1, s2, bSlope, lambda12S, tLow, tUpp, tAux, sigmaTot, rho,
+ lambda, tAbsMin, phaseCst, alphaEM0, sigmaNuc, sigmaCou, signCou;
+
+ // Calculation of alphaElectromagnetic.
+ AlphaEM alphaEM;
+
+};
+
+//**************************************************************************
+
+// A derived class with 2 -> 2 kinematics set up for diffractive scattering.
+
+class PhaseSpace2to2diffractive : public PhaseSpace {
+
+public:
+
+ // Constructor.
+ PhaseSpace2to2diffractive(bool isDiffAin = false, bool isDiffBin = false)
+ : isDiffA(isDiffAin), isDiffB(isDiffBin) {}
+
+ // Construct the trial or final event kinematics.
+ virtual bool setupSampling();
+ virtual bool trialKin(bool inEvent = true, bool = false);
+ virtual bool finalKin();
+
+ // Are beam particles resolved in partons or scatter directly?
+ virtual bool isResolved() const {return false;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRY;
+ static const double EXPMAX, DIFFMASSMAX;
+
+ // Kinematics properties specific to 2 -> 2 diffractive.
+ bool isDiffA, isDiffB;
+ double m3ElDiff, m4ElDiff, cRes, sResXB, sResAX, sProton,
+ s1, s2, bMin, lambda12, lambda34, tLow, tUpp, tAux;
+
+};
+
+//**************************************************************************
+
+// A derived class for minumum bias events. Hardly does anything, since
+// the real action is taken care of by the MultipleInteractions class.
+
+class PhaseSpace2to2minbias : public PhaseSpace {
+
+public:
+
+ // Constructor.
+ PhaseSpace2to2minbias() {}
+
+ // Construct the trial or final event kinematics.
+ virtual bool setupSampling() {sigmaNw = sigmaProcessPtr->sigmaHat();
+ sigmaMx = sigmaNw; return true;}
+ virtual bool trialKin( bool , bool = false) {return true;}
+ virtual bool finalKin() {return true;}
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class with 2 -> 3 kinematics 1 + 2 -> 3 + 4 + 5 set up in
+// tau, y, pT2_4, pT2_5, phi_4, phi_5 and y_3 (partial cylindrical symmetry).
+
+class PhaseSpace2to3tauycyl : public PhaseSpace {
+
+public:
+
+ // Constructor.
+ PhaseSpace2to3tauycyl() {}
+
+ // Optimize subsequent kinematics selection.
+ virtual bool setupSampling() {if (!setupMasses()) return false;
+ setup3Body(); return setupSampling123(false, true);}
+
+ // Construct the trial kinematics.
+ virtual bool trialKin(bool inEvent = true, bool = false) {
+ if (!trialMasses()) return false;
+ return trialKin123(false, true, inEvent);}
+
+ // Construct the final event kinematics.
+ virtual bool finalKin();
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NITERNR;
+
+ // Set up for fixed or Breit-Wigner mass selection.
+ bool setupMasses();
+
+ // Select fixed or Breit-Wigner-distributed masses.
+ bool trialMasses();
+
+};
+
+//**************************************************************************
+
+// A derived class for Les Houches events.
+
+class PhaseSpaceLHA : public PhaseSpace {
+
+public:
+
+ // Constructor.
+ PhaseSpaceLHA() {idProcSave = 0;}
+
+ // Find maximal cross section for comparison with internal processes.
+ virtual bool setupSampling();
+
+ // Construct the next process, by interface to Les Houches class.
+ virtual bool trialKin( bool , bool repeatSame = false);
+
+ // Dummy, since kinematics available in Les Houches object.
+ virtual bool finalKin() {return true;}
+
+ // For Les Houches with negative event weight needs
+ virtual double sigmaSumSigned() const {return sigmaSgn;}
+
+private:
+
+ // Constants.
+ static const double CONVERTPB2MB;
+
+ // Local properties.
+ int strategy, stratAbs, nProc, idProcSave;
+ double xMaxAbsSum, xSecSgnSum, sigmaSgn;
+ vector<int> idProc;
+ vector<double> xMaxAbsProc;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_PhaseSpace_H
+
--- /dev/null
+// ProcessContainer.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the collected machinery of a process.
+// ProcessContainer: contains information on a particular process.
+// SetupContainers: administrates the selection/creation of processes.
+
+#ifndef Pythia8_ProcessContainer_H
+#define Pythia8_ProcessContainer_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Event.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PartonDistributions.h"
+#include "PhaseSpace.h"
+#include "PythiaStdlib.h"
+#include "ResonanceDecays.h"
+#include "Settings.h"
+#include "SigmaProcess.h"
+#include "SigmaTotal.h"
+#include "SusyLesHouches.h"
+#include "UserHooks.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ProcessContainer class combines pointers to matrix element and
+// phase space generator with general generation info.
+
+class ProcessContainer {
+
+public:
+
+ // Constructor.
+ ProcessContainer(SigmaProcess* sigmaProcessPtrIn = 0)
+ : sigmaProcessPtr(sigmaProcessPtrIn), phaseSpacePtr(0) {}
+
+ // Destructor.
+ ~ProcessContainer() {delete phaseSpacePtr; delete sigmaProcessPtr;}
+
+ // Initialize phase space and counters.
+ bool init(Info* infoPtrIn, BeamParticle* beamAPtr, BeamParticle* beamBPtr,
+ AlphaStrong* alphaSPtr, AlphaEM* alphaEMPtr, SigmaTotal* sigmaTotPtr,
+ ResonanceDecays* resDecaysPtrIn, SusyLesHouches* slhaPtr,
+ UserHooks* userHooksPtr);
+
+ // Store or replace Les Houches pointer.
+ void setLHAPtr( LHAup* lhaUpPtrIn) {lhaUpPtr = lhaUpPtrIn;
+ if (sigmaProcessPtr > 0) sigmaProcessPtr->setLHAPtr(lhaUpPtr);
+ if (phaseSpacePtr > 0) phaseSpacePtr->setLHAPtr(lhaUpPtr);}
+
+ // Update the CM energy of the event.
+ void newECM(double eCM) {phaseSpacePtr->newECM(eCM);}
+
+ // Generate a trial event; accepted or not.
+ bool trialProcess();
+
+ // Give the hard subprocess (with option for a second hard subprocess).
+ bool constructProcess( Event& process, bool isHardest = true);
+
+ // Do resonance decays.
+ bool decayResonances( Event& process);
+
+ // Accumulate statistics after user veto.
+ void accumulate() {++nAcc;}
+
+ // Reset statistics on events generated so far.
+ void reset();
+
+ // Process name and code, and the number of final-state particles.
+ string name() const {return sigmaProcessPtr->name();}
+ int code() const {return sigmaProcessPtr->code();}
+ int nFinal() const {return sigmaProcessPtr->nFinal();}
+
+ // Member functions for info on generation process.
+ bool newSigmaMax() const {return newSigmaMx;}
+ double sigmaMax() const {return sigmaMx;}
+ long nTried() const {return nTry;}
+ long nSelected() const {return nSel;}
+ long nAccepted() const {return nAcc;}
+ double sigmaSelMC() {if (nTry > nTryStat) sigmaDelta(); return sigmaAvg;}
+ double sigmaMC() {if (nTry > nTryStat) sigmaDelta(); return sigmaFin;}
+ double deltaMC() {if (nTry > nTryStat) sigmaDelta(); return deltaFin;}
+
+ // Some kinematics quantities.
+ int id1() const {return sigmaProcessPtr->id(1);}
+ int id2() const {return sigmaProcessPtr->id(2);}
+ double x1() const {return phaseSpacePtr->x1();}
+ double x2() const {return phaseSpacePtr->x2();}
+ double Q2Fac() const {return sigmaProcessPtr->Q2Fac();}
+
+ // Tell whether container is for Les Houches events.
+ bool isLHAContainer() const {return isLHA;}
+
+ // When two hard processes set or get info whether process is matched.
+ void isSame( bool isSameIn) { isSameSave = isSameIn;}
+ bool isSame() const {return isSameSave;}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int N12SAMPLE, N3SAMPLE;
+
+ // Pointer to the subprocess matrix element.
+ SigmaProcess* sigmaProcessPtr;
+
+ // Pointer to the phase space generator.
+ PhaseSpace* phaseSpacePtr;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointer to ResonanceDecays object for sequential resonance decays.
+ ResonanceDecays* resDecaysPtr;
+
+ // Pointer to LHAup for generating external events.
+ LHAup* lhaUpPtr;
+
+ // Info on process.
+ bool isMinBias, isResolved, isDiffA, isDiffB, isLHA, allowNegSig,
+ hasOctetOnium, isSameSave;
+ int lhaStrat, lhaStratAbs;
+
+ // Statistics on generation process. (Long integers just in case.)
+ int newSigmaMx;
+ long nTry, nSel, nAcc, nTryStat;
+ double sigmaMx, sigmaSgn, sigmaSum, sigma2Sum, sigmaNeg, sigmaAvg,
+ sigmaFin, deltaFin;
+
+ // Estimate integrated cross section and its uncertainty.
+ void sigmaDelta();
+
+};
+
+//**************************************************************************
+
+// The SetupContainers class turns the list of user-requested processes
+// into a vector of ProcessContainer objects, each with a process.
+
+class SetupContainers {
+
+public:
+
+ // Constructor.
+ SetupContainers() {}
+
+ // Initialization assuming all necessary data already read.
+ bool init(vector<ProcessContainer*>& containerPtrs);
+
+ // Initialization of a second hard process.
+ bool init2(vector<ProcessContainer*>& container2Ptrs);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_ProcessContainer_H
--- /dev/null
+// ProcessLevel.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the main class for process-level event generation.
+// ProcessLevel: administrates the selection of "hard" process.
+
+#ifndef Pythia8_ProcessLevel_H
+#define Pythia8_ProcessLevel_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Event.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PartonDistributions.h"
+#include "ProcessContainer.h"
+#include "PythiaStdlib.h"
+#include "ResonanceDecays.h"
+#include "Settings.h"
+#include "SigmaTotal.h"
+#include "SusyLesHouches.h"
+#include "UserHooks.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ProcessLevel class contains the top-level routines to generate
+// the characteristic "hard" process of an event.
+
+class ProcessLevel {
+
+public:
+
+ // Constructor.
+ ProcessLevel() : iLHACont(-1) {}
+
+ // Destructor to delete processes in containers.
+ ~ProcessLevel();
+
+ // Initialization.
+ bool init( Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn, SigmaTotal* sigmaTotPtrIn, bool doLHAin,
+ SusyLesHouches* slhaPtrIn, UserHooks* userHooksPtrIn,
+ vector<SigmaProcess*>& sigmaPtrs, ostream& os = cout);
+
+ // Store or replace Les Houches pointer.
+ void setLHAPtr( LHAup* lhaUpPtrIn) {lhaUpPtr = lhaUpPtrIn;
+ if (iLHACont >= 0) containerPtrs[iLHACont]->setLHAPtr(lhaUpPtr);}
+
+ // Generate the next "hard" process.
+ bool next( Event& process);
+
+ // Accumulate and update statistics (after possible user veto).
+ void accumulate();
+
+ // Print statistics on cross sections and number of events.
+ void statistics(bool reset = false, ostream& os = cout);
+
+ // Add any junctions to the process event record list.
+ void findJunctions( Event& junEvent);
+
+private:
+
+ // Generic info for process generation.
+ bool doSecondHard, allHardSame, noneHardSame, someHardSame, doResDecays;
+ int nImpact, startColTag2;
+ double sigmaND, sumImpactFac, sum2ImpactFac;
+
+ // Vector of containers of internally-generated processes.
+ vector<ProcessContainer*> containerPtrs;
+ int iContainer, iLHACont;
+ double sigmaMaxSum;
+
+ // Ditto for optional choice of a second hard process.
+ vector<ProcessContainer*> container2Ptrs;
+ int i2Container;
+ double sigma2MaxSum;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to the two incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Pointer to SigmaTotal object needed to handle soft QCD processes.
+ SigmaTotal* sigmaTotPtr;
+
+ // Pointer to SusyLesHouches object for interface to SUSY spectra.
+ SusyLesHouches* slhaPtr;
+
+ // Pointer to userHooks object for user interaction with program.
+ UserHooks* userHooksPtr;
+
+ // Pointer to LHAup for generating external events.
+ LHAup* lhaUpPtr;
+
+ // Common alphaStrong and alphaElectromagnetic calculation for SigmaProcess.
+ AlphaStrong alphaS;
+ AlphaEM alphaEM;
+
+ // Initialization routine for SUSY spectra.
+ bool initSLHA();
+
+ // ResonanceDecay object does sequential resonance decays.
+ ResonanceDecays resonanceDecays;
+
+ // Generate the next event with one interaction.
+ bool nextOne( Event& process);
+
+ // Generate the next event with two hard interactions.
+ bool nextTwo( Event& process);
+
+ // Append the second to the first process list.
+ void combineProcessRecords( Event& process, Event& process2);
+
+ // Check that colours match up.
+ bool checkColours( Event& process);
+
+ // Print statistics when two hard processes allowed.
+ void statistics2(bool reset, ostream& os = cout);
+
+ // Statistics for Les Houches event classification.
+ vector<int> codeLHA, nEvtLHA;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_ProcessLevel_H
--- /dev/null
+// Pythia.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the main class for event generation.
+// Pythia: provide the main user interface to everything else.
+
+#ifndef Pythia8_Pythia_H
+#define Pythia8_Pythia_H
+
+#include "Analysis.h"
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "BeamShape.h"
+#include "Event.h"
+#include "FragmentationFlavZpT.h"
+#include "HadronLevel.h"
+#include "Info.h"
+#include "LesHouches.h"
+#include "PartonLevel.h"
+#include "ParticleData.h"
+#include "PartonDistributions.h"
+#include "ProcessLevel.h"
+#include "PythiaStdlib.h"
+#include "ResonanceWidths.h"
+#include "Settings.h"
+#include "SigmaTotal.h"
+#include "SpaceShower.h"
+#include "SusyLesHouches.h"
+#include "TimeShower.h"
+#include "UserHooks.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The Pythia class contains the top-level routines to generate an event.
+
+class Pythia {
+
+public:
+
+ // Constructor. (See Pythia.cc file.)
+ Pythia(string xmlDir = "../xmldoc");
+
+ // Destructor. (See Pythia.cc file.)
+ ~Pythia();
+
+ // Read in one update for a setting or particle data from a single line.
+ bool readString(string, bool warn = true);
+
+ // Read in updates for settings or particle data from user-defined file.
+ bool readFile(string, bool warn = true, int subrun = SUBRUNDEFAULT);
+ bool readFile(string fileName, int subrun) {
+ return readFile(fileName, true, subrun);}
+
+ // Possibility to pass in pointers to PDF's.
+ bool setPDFPtr( PDF* pdfAPtrIn, PDF* pdfBPtrIn, PDF* pdfHardAPtrIn = 0,
+ PDF* pdfHardBPtrIn = 0);
+
+ // Possibility to pass in pointer for external handling of some decays.
+ bool setDecayPtr( DecayHandler* decayHandlePtrIn,
+ vector<int> handledParticlesIn) {decayHandlePtr = decayHandlePtrIn;
+ handledParticles.resize(0);
+ for(int i = 0; i < int(handledParticlesIn.size()); ++i)
+ handledParticles.push_back( handledParticlesIn[i] ); return true;}
+
+ // Possibility to pass in pointer for external random number generation.
+ bool setRndmEnginePtr( RndmEngine* rndmEnginePtrIn)
+ { return Rndm::rndmEnginePtr( rndmEnginePtrIn);}
+
+ // Possibility to pass in pointer for user hooks.
+ bool setUserHooksPtr( UserHooks* userHooksPtrIn)
+ { userHooksPtr = userHooksPtrIn; return true;}
+
+ // Possibility to pass in pointer for beam shape.
+ bool setBeamShapePtr( BeamShape* beamShapePtrIn)
+ { beamShapePtr = beamShapePtrIn; return true;}
+
+ // Possibility to pass in pointer(s) for external cross section.
+ bool setSigmaPtr( SigmaProcess* sigmaPtrIn)
+ { sigmaPtrs.push_back( sigmaPtrIn); return true;}
+
+ // Possibility to pass in pointer(s) for external resonance.
+ bool setResonancePtr( ResonanceWidths* resonancePtrIn)
+ { resonancePtrs.push_back( resonancePtrIn); return true;}
+
+ // Possibility to pass in pointer for external showers.
+ bool setShowerPtr( TimeShower* timesDecPtrIn,
+ TimeShower* timesPtrIn = 0, SpaceShower* spacePtrIn = 0)
+ { timesDecPtr = timesDecPtrIn; timesPtr = timesPtrIn;
+ spacePtr = spacePtrIn; return true;}
+
+ // Initialization in the CM frame.
+ bool init( int idAin, int idBin, double eCMin);
+
+ // Initialization with two collinear beams, including fixed target.
+ bool init( int idAin, int idBin, double eAin, double eBin);
+
+ // Initialization with two acollinear beams.
+ bool init( int idAin, int idBin, double pxAin, double pyAin,
+ double pzAin, double pxBin, double pyBin, double pzBin);
+
+ // Initialization by a Les Houches Event File.
+ bool init( string LesHouchesEventFile, bool skipInit = false);
+
+ // Initialization using the Main beam variables.
+ bool init();
+
+ // Initialization according to the Les Houches Accord.
+ bool init( LHAup* lhaUpPtrIn);
+
+ // Generate the next event.
+ bool next();
+
+ // Generate only the hadronization/decay stage.
+ bool forceHadronLevel();
+
+ // Special routine to allow more decays if on/off switches changed.
+ bool moreDecays() {return hadronLevel.moreDecays(event);}
+
+ // List the current Les Houches event.
+ void LHAeventList(ostream& os = cout) {lhaUpPtr->listEvent(os);}
+
+ // Main routine to provide final statistics on generation.
+ void statistics(bool all = false, bool reset = true);
+
+ // Read in settings values: shorthand, not new functionality.
+ bool flag(string key) {return settings.flag(key);}
+ int mode(string key) {return settings.mode(key);}
+ double parm(string key) {return settings.parm(key);}
+ string word(string key) {return settings.word(key);}
+
+ // The event record for the parton-level central process.
+ Event process;
+
+ // The event record for the complete event history.
+ Event event;
+
+ // Information on the generation: current subprocess and error statistics.
+ Info info;
+
+ // Settings - is static but declared here for ease of use.
+ Settings settings;
+
+ // ParticleDataTable - is static but declared here for ease of use.
+ ParticleDataTable particleData;
+
+ // SusyLesHouches - SLHA object for interface to SUSY spectra.
+ SusyLesHouches slha;
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRY, SUBRUNDEFAULT;
+
+ // Initialization data, extracted from database.
+ bool doProcessLevel, doPartonLevel, doHadronLevel, checkEvent;
+ int nErrList;
+ double epTolErr, epTolWarn;
+
+ // Initialization data, extracted from init(...) call.
+ bool isConstructed, isInit;
+ int idA, idB, frameType;
+ double mA, mB, pxA, pxB, pyA, pyB, pzA, pzB, eA, eB,
+ pzAcm, pzBcm, eCM, betaZ, gammaZ;
+ Vec4 pAinit, pBinit, pAnow, pBnow;
+ RotBstMatrix MfromCM, MtoCM;
+
+ // information for error checkout.
+ int nErrEvent;
+ vector<int> iErrId, iErrCol, iErrNan;
+
+ // Pointers to the parton distributions of the two incoming beams.
+ PDF* pdfAPtr;
+ PDF* pdfBPtr;
+
+ // Extra PDF pointers to be used in hard processes only.
+ PDF* pdfHardAPtr;
+ PDF* pdfHardBPtr;
+
+ // Keep track when "new" has been used and needs a "delete" for PDF's.
+ bool useNewPdfA, useNewPdfB, useNewPdfHard;
+
+ // The two incoming beams.
+ BeamParticle beamA;
+ BeamParticle beamB;
+
+ // LHAup object for generating external events.
+ bool doLHA, useNewLHA;
+ LHAup* lhaUpPtr;
+
+ // Pointer to external decay handler and list of particles it handles.
+ DecayHandler* decayHandlePtr;
+ vector<int> handledParticles;
+
+ // Pointer to UserHooks object for user interaction with program.
+ UserHooks* userHooksPtr;
+ bool hasUserHooks, doVetoProcess, doVetoPartons;
+
+ // Pointer to BeamShape object for beam momentum and interaction vertex.
+ BeamShape* beamShapePtr;
+ bool useNewBeamShape, doMomentumSpread, doVertexSpread;
+
+ // Pointers to external processes derived from the Pythia base classes.
+ vector<SigmaProcess*> sigmaPtrs;
+
+ // Pointers to external calculation of resonance widths.
+ vector<ResonanceWidths*> resonancePtrs;
+
+ // Pointers to timelike and spacelike showers.
+ TimeShower* timesDecPtr;
+ TimeShower* timesPtr;
+ SpaceShower* spacePtr;
+ bool useNewTimes, useNewSpace;
+
+ // The main generator class to define the core process of the event.
+ ProcessLevel processLevel;
+
+ // The main generator class to produce the parton level of the event.
+ PartonLevel partonLevel;
+
+ // The main generator class to produce the hadron level of the event.
+ HadronLevel hadronLevel;
+
+ // The total cross section class is used both on process and parton level.
+ SigmaTotal sigmaTot;
+
+ // Write the Pythia banner, with symbol and version information.
+ void banner(ostream& os = cout);
+
+ // Check for lines in file that mark the beginning of new subrun.
+ int readSubrun(string line, bool warn = true, ostream& os = cout);
+
+ // Initialization routine to set up the whole generation machinery.
+ bool initInternal();
+
+ // Calculate kinematics at initialization.
+ bool initKinematics();
+
+ // Initialize tunes to e+e- and pp/ppbar data.
+ void initTunes();
+
+ // Recalculate kinematics for each event when beam momentum has a spread.
+ void nextKinematics();
+
+ // Boost from CM frame to lab frame, or inverse. Set production vertex.
+ void boostAndVertex(bool toLab, bool setVertex);
+
+ // Check that the final event makes sense.
+ bool check(ostream& os = cout);
+
+ // Auxiliary to set parton densities among list of possibilities.
+ PDF* getPDFPtr(int idIn, int sequence = 1);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_Pythia_H
--- /dev/null
+// Pythia6Interface.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the Pythia 6.4 f77 external linkage to C++.
+// All required code is contained here, i.e. there is no matching .cc file.
+
+#ifndef Pythia8_Pythia6Interface_H
+#define Pythia8_Pythia6Interface_H
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Declare the f77 subroutines that may be used.
+
+extern "C" {
+
+ extern void pygive_(const char*, int);
+
+ extern void pyinit_(const char*, const char*, const char*, double&,
+ int, int, int);
+
+ extern void pyupin_();
+
+ extern void pyupev_();
+
+ extern void pylist_(int&);
+
+ extern void pystat_(int&);
+
+}
+
+//**************************************************************************
+
+// Interfaces to the above routines, to make the C++ calls similar to f77.
+
+class Pythia6Interface {
+
+public:
+
+ // Give in a command to change a setting.
+ static void pygive(const string cmnd) {
+ const char* cstring = cmnd.c_str(); int len = cmnd.length();
+ pygive_(cstring, len);
+ }
+
+ // Initialize the generation for the given beam confiuration.
+ static void pyinit(const string frame, const string beam,
+ const string target, double wIn) {
+ const char* cframe = frame.c_str(); int lenframe = frame.length();
+ const char* cbeam = beam.c_str(); int lenbeam = beam.length();
+ const char* ctarget = target.c_str(); int lentarget = target.length();
+ pyinit_(cframe, cbeam, ctarget, wIn, lenframe, lenbeam, lentarget);
+ }
+
+ // Fill the initialization information in the HEPRUP commonblock.
+ static void pyupin() {pyupin_();}
+
+ // Generate the next hard process and
+ // fill the event information in the HEPEUP commonblock
+ static void pyupev() {pyupev_();}
+
+ // List the event at the process level.
+ static void pylist(int mode) {pylist_(mode);}
+
+ // Print statistics on the event generation process.
+ static void pystat(int mode) {pystat_(mode);}
+
+};
+
+//**************************************************************************
+
+
+} // end namespace Pythia8
+
+#endif // Pythia8_Pythia6Interface_H
--- /dev/null
+// PythiaComplex.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for typedef'd double precision complex numbers.
+
+#ifndef Pythia8_PythiaComplex_H
+#define Pythia8_PythiaComplex_H
+
+// Stdlib header for complex numbers.
+# include <complex>
+
+namespace Pythia8 {
+
+// Convenient typedef for double precision complex numbers.
+typedef std::complex<double> complex;
+
+} // end namespace Pythia8
+
+#endif // Pythia8_PythiaComplex_H
--- /dev/null
+// PythiaStdlib.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for functionality pulled in from Stdlib,
+// plus a few useful utilities (small powers).
+
+#ifndef Pythia8_PythiaStdlib_H
+#define Pythia8_PythiaStdlib_H
+
+// Stdlib header files for mathematics.
+#include <cmath>
+#include <cstdlib>
+
+// Stdlib header files for strings and containers.
+#include <string>
+#include <vector>
+#include <map>
+
+// Stdlib header file for input and output.
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+
+// Define pi if not yet done.
+#ifndef M_PI
+#define M_PI 3.1415926535897932385
+#endif
+
+// By this declaration you do not need to use std:: qualifier everywhere.
+using namespace std;
+
+// Alternatively you can specify exactly which std:: methods will be used.
+/*
+namespace Pythia8 {
+// Generic utilities and mathematical functions.
+using std::swap;
+using std::max;
+using std::min;
+using std::abs;
+// Strings and containers.
+using std::string;
+using std::vector;
+using std::map;
+// Input/output streams.
+using std::cin;
+using std::cout;
+using std::cerr;
+using std::istream;
+using std::ostream;
+using std::ifstream;
+using std::ofstream;
+using std::istringstream;
+using std::ostringstream;
+// Input/output formatting.
+using std::endl;
+using std::fixed;
+using std::scientific;
+using std::left;
+using std::right;
+using std::setw;
+using std::setprecision;
+} // end namespace Pythia8
+*/
+
+namespace Pythia8 {
+
+// Powers of small integers - for balance speed/code clarity.
+inline double pow2(const double& x) {return x*x;}
+inline double pow3(const double& x) {return x*x*x;}
+inline double pow4(const double& x) {return x*x*x*x;}
+inline double pow5(const double& x) {return x*x*x*x*x;}
+inline double pow6(const double& x) {return x*x*x*x*x*x;}
+
+// Avoid problem with negative square root argument (from roundoff).
+inline double sqrtpos(const double& x) {return sqrt( max( 0., x));}
+
+} // end namespace Pythia8
+
+#endif // Pythia8_PythiaStdlib_H
--- /dev/null
+// ResonanceDecays.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the main class for performing resonance decays.
+// ResonanceDecays: handles the sequential decay of resonances in process.
+
+#ifndef Pythia8_ResonanceDecays_H
+#define Pythia8_ResonanceDecays_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "ResonanceWidths.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ResonanceDecays class handles the sequential decay of resonances
+// that are part of the hard process (t, W, Z, H, SUSY,...).
+
+class ResonanceDecays {
+
+public:
+
+ // Constructor.
+ ResonanceDecays() {}
+
+ // Store pointer to Info for error messages.
+ void init(Info* infoPtrIn) {infoPtr = infoPtrIn;}
+
+ // Generate the next decay sequence.
+ bool next( Event& process);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRYCHANNEL, NTRYMASSES;
+ static const double MSAFETY, WIDTHCUT, TINY, WTCORRECTION[11];
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Select masses of decay products.
+ bool pickMasses();
+
+ // Select colours of decay products.
+ bool pickColours(int iDec, Event& process);
+
+ // Select kinematics isotropic in phase space.
+ bool pickKinematics();
+
+ // Flavour, colour and momentum information.
+ int id0, mult;
+ double m0;
+ vector<int> idProd, cols, acols;
+ vector<double> mProd;
+ vector<Vec4> pProd;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_ResonanceDecays_H
--- /dev/null
+// ResonanceWidths.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for resonance properties: dynamical widths etc.
+// ResonanceWidths: base class for all resonances.
+// ResonanceGmZ, ...: derived classes for individual resonances.
+
+#ifndef Pythia8_ResonanceWidths_H
+#define Pythia8_ResonanceWidths_H
+
+#include "Basics.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+#include "StandardModel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Forward references to ParticleData and StandardModel classes.
+class DecayChannel;
+class DecayTable;
+class ParticleDataEntry;
+class AlphaStrong;
+class AlphaEM;
+
+//**************************************************************************
+
+// The ResonanceWidths is the base class. Also used for generic resonaces.
+
+class ResonanceWidths {
+
+public:
+
+ // Destructor.
+ virtual ~ResonanceWidths() {}
+
+ // Initialize static data members in base class.
+ static void initStatic(Info* infoPtrIn);
+
+ // Set up standard properties.
+ bool initBasic(int idResIn);
+
+ // Calculate and store partial and total widths at the nominal mass.
+ void init();
+
+ // Return identity of particle species.
+ int id() const {return idRes;}
+
+ // Calculate the total/open width for given mass, charge and instate.
+ double width(int idSgn, double mHatIn, int idInFlavIn = 0,
+ bool openOnly = false, bool setBR = false, int idOutFlav1 = 0,
+ int idOutFlav2 = 0);
+
+ // Special case to calculate open final-state width.
+ double widthOpen(int idSgn, double mHatIn, int idIn = 0) {
+ return width( idSgn, mHatIn, idIn, true, false);}
+
+ // Special case to store open final-state widths for channel selection.
+ double widthStore(int idSgn, double mHatIn, int idIn = 0) {
+ return width( idSgn, mHatIn, idIn, true, true);}
+
+ // Return fraction of width open for particle and antiparticle.
+ double openFrac(int idSgn) {return (idSgn > 0) ? openPos : openNeg;}
+
+ // Return forced rescaling factor of resonance width.
+ double widthRescaleFactor() {return forceFactor;}
+
+ // Special case to calculate one final-state width.
+ // Currently only used for Higgs -> qqbar, g g or gamma gamma.
+ double widthChan(double mHatIn, int idOutFlav1, int idOutFlav2) {
+ return width( 1, mHatIn, 0, false, false, idOutFlav1, idOutFlav2);}
+
+protected:
+
+ // Constructor.
+ ResonanceWidths() {}
+
+ // Static initialization data, normally only set once.
+ static int alphaSorder, alphaEMorder;
+ static double alphaSvalue, minWidth, minThreshold;
+
+ // Static alphaStrong and alphaElectromagnetic calculation.
+ static AlphaStrong alphaS;
+ static AlphaEM alphaEM;
+
+ // Constants: could only be changed in the code itself.
+ static const int NPOINT;
+ static const double MASSMARGIN;
+
+ // Pointer to various information on the generation.
+ static Info* infoPtr;
+
+ // Pointer to properties of the particle species.
+ ParticleDataEntry* particlePtr;
+
+ // Particle properties always locally present.
+ int idRes, hasAntiRes;
+ bool doForceWidth;
+ double mRes, GammaRes, m2Res, GamMRat, openPos, openNeg, forceFactor;
+
+ // Properties for currently studied decay channel(s).
+ int iChannel, onMode, meMode, mult, id1, id2, id3, id1Abs,
+ id2Abs, id3Abs, idInFlav;
+ double widNow, mHat, mf1, mf2, mf3, mr1, mr2, mr3, ps, kinFac,
+ alpEM, alpS, colQ, preFac;
+
+ // Initialize constants.
+ virtual void initConstants() {}
+
+ // Calculate various common prefactors for the current mass.
+ // Optional argument calledFromInit only used for Z0.
+ virtual void calcPreFac(bool = false) {}
+
+ // Calculate width for currently considered channel.
+ // Optional argument calledFromInit only used for Z0.
+ virtual void calcWidth(bool = false) {}
+
+ // Simple routines for matrix-element integration over Breit-Wigners.
+ double numInt1BW(double mHatIn, double m1, double Gamma1, double mMin1,
+ double m2, int psMode = 1);
+ double numInt2BW(double mHatIn, double m1, double Gamma1, double mMin1,
+ double m2, double Gamma2, double mMin2, int psMode = 1);
+
+};
+
+//**************************************************************************
+
+// The ResonanceGeneric class handles a generic resonance.
+// Only needs a constructor; for the rest uses defaults in base class.
+
+class ResonanceGeneric : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceGeneric(int idResIn) {initBasic(idResIn);}
+
+};
+
+//**************************************************************************
+
+// The ResonanceGmZ class handles the gamma*/Z0 resonance.
+
+class ResonanceGmZ : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceGmZ(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ int gmZmode;
+ double thetaWRat, ei2, eivi, vi2ai2, gamNorm, intNorm, resNorm;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool calledFromInit = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceW class handles the W+- resonance.
+
+class ResonanceW : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceW(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double thetaWRat, alpEM;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceTop class handles the top/antitop resonance.
+
+class ResonanceTop : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceTop(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double thetaWRat, m2W;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceFour class handles fourth-generation resonances.
+
+class ResonanceFour : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceFour(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double thetaWRat, m2W;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceH class handles the SM and BSM Higgs resonance.
+// higgsType = 0 : SM H; = 1: h^0/H_1; = 2 : H^0/H_2; = 3 : A^0/A_3.
+
+class ResonanceH : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceH(int higgsTypeIn, int idResIn) : higgsType(higgsTypeIn)
+ {initBasic(idResIn);}
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double MASSMIN, GAMMAMARGIN;
+
+ // Higgs type in current instance.
+ int higgsType;
+
+ // Locally stored properties and couplings.
+ bool useCubicWidth, useRunLoopMass;
+ double sin2tW, cos2tW, mT, mZ, mW, mHchg, GammaT, GammaZ, GammaW,
+ coup2d, coup2u, coup2l, coup2Z, coup2W, coup2Hchg, coup2H1H1,
+ coup2A3A3, coup2H1Z, coup2A3Z, coup2A3H1, coup2HchgW,
+ kinFacT[101], kinFacZ[101], kinFacW[101];
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+ // Sum up loop contributions in Higgs -> g + g.
+ double eta2gg();
+
+ // Sum up loop contributions in Higgs -> gamma + gamma.
+ double eta2gaga();
+
+ // Sum up loop contributions in Higgs -> gamma + Z0.
+ double eta2gaZ();
+
+};
+
+//**************************************************************************
+
+// The ResonanceHchg class handles the H+- resonance.
+
+class ResonanceHchg : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceHchg(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ bool useCubicWidth;
+ double thetaWRat, mW, tanBeta, tan2Beta, coup2H1W;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceZprime class handles the gamma*/Z0 /Z'^0 resonance.
+
+class ResonanceZprime : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceZprime(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ int gmZmode;
+ double sin2tW, cos2tW, thetaWRat, mZ, GammaZ, m2Z, GamMRatZ, afZp[20],
+ vfZp[20], coupZpWW, ei2, eivi, vai2, eivpi, vaivapi, vapi2,
+ gamNorm, gamZNorm, ZNorm, gamZpNorm, ZZpNorm, ZpNorm;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool calledFromInit = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceWprime class handles the W'+- resonance.
+
+class ResonanceWprime : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceWprime(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double thetaWRat, cos2tW, alpEM, aqWp, vqWp, alWp, vlWp, coupWpWZ;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceRhorizontal class handles the R^0 resonance.
+
+class ResonanceRhorizontal : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceRhorizontal(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double thetaWRat;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceExcited class handles excited-fermion resonances.
+
+class ResonanceExcited : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceExcited(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double Lambda, coupF, coupFprime, coupFcol, sin2tW, cos2tW;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceGraviton class handles the excited Graviton resonance.
+
+class ResonanceGraviton : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceGraviton(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double kappaMG;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceLeptoquark class handles the LQ/LQbar resonance.
+
+class ResonanceLeptoquark : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceLeptoquark(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double kCoup;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceNuRight class handles righthanded Majorana neutrinos.
+
+class ResonanceNuRight : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceNuRight(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double thetaWRat, mWR;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceZRight class handles the Z_R^0 resonance.
+
+class ResonanceZRight : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceZRight(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double sin2tW, thetaWRat;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceWRight class handles the W_R+- resonance.
+
+class ResonanceWRight : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceWRight(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double thetaWRat;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceHchgchgLeft class handles the H++/H-- (left) resonance.
+
+class ResonanceHchgchgLeft : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceHchgchgLeft(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ double yukawa[4][4], gL, vL, mW;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+// The ResonanceHchgchgRight class handles the H++/H-- (right) resonance.
+
+class ResonanceHchgchgRight : public ResonanceWidths {
+
+public:
+
+ // Constructor.
+ ResonanceHchgchgRight(int idResIn) {initBasic(idResIn);}
+
+private:
+
+ // Locally stored properties and couplings.
+ int idWR;
+ double yukawa[4][4], gR;
+
+ // Initialize constants.
+ virtual void initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ virtual void calcPreFac(bool = false);
+
+ // Caclulate width for currently considered channel.
+ virtual void calcWidth(bool = false);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_ResonanceWidths_H
--- /dev/null
+// Settings.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the settings database; and for error statistics.
+// Flag: helper class with bool flags.
+// Mode: helper class with int modes.
+// Parm: (short for parameter) helper class with double parameters.
+// Word: helper class with string words.
+// Settings: maps of flags, modes, parms and words with input/output.
+
+#ifndef Pythia8_Settings_H
+#define Pythia8_Settings_H
+
+#include "Info.h"
+#include "PythiaStdlib.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Class for bool flags.
+
+class Flag {
+
+public:
+
+ // Constructor
+ Flag(string nameIn = " ", bool defaultIn = false) : name(nameIn),
+ valNow(defaultIn) , valDefault(defaultIn) { }
+
+ // Data members.
+ string name;
+ bool valNow, valDefault;
+
+};
+
+//**************************************************************************
+
+// Class for integer modes.
+
+class Mode {
+
+public:
+
+ // Constructor
+ Mode(string nameIn = " ", int defaultIn = 0, bool hasMinIn = false,
+ bool hasMaxIn = false, int minIn = 0, int maxIn = 0) : name(nameIn),
+ valNow(defaultIn), valDefault(defaultIn), hasMin(hasMinIn),
+ hasMax(hasMaxIn), valMin(minIn), valMax(maxIn) { }
+
+ // Data members.
+ string name;
+ int valNow, valDefault;
+ bool hasMin, hasMax;
+ int valMin, valMax;
+
+};
+
+//**************************************************************************
+
+// Class for double parms (where parm is shorthand for parameter).
+
+class Parm {
+
+public:
+
+ // Constructor
+ Parm(string nameIn = " ", double defaultIn = 0.,
+ bool hasMinIn = false, bool hasMaxIn = false, double minIn = 0.,
+ double maxIn = 0.) : name(nameIn), valNow(defaultIn),
+ valDefault(defaultIn), hasMin(hasMinIn), hasMax(hasMaxIn),
+ valMin(minIn), valMax(maxIn) { }
+
+ // Data members.
+ string name;
+ double valNow, valDefault;
+ bool hasMin, hasMax;
+ double valMin, valMax;
+
+};
+
+//**************************************************************************
+
+// Class for string words.
+
+class Word {
+
+public:
+
+ // Constructor
+ Word(string nameIn = " ", string defaultIn = " ") : name(nameIn),
+ valNow(defaultIn) , valDefault(defaultIn) { }
+
+ // Data members.
+ string name, valNow, valDefault;
+
+};
+
+//**************************************************************************
+
+// This class holds info on flags (bool), modes (int),
+// parms (double) and words (string).
+
+class Settings {
+
+public:
+
+ // Constructor.
+ Settings() {}
+
+ // Initialize static pointer.
+ static void initPtr(Info* infoPtrIn) {infoPtr = infoPtrIn;}
+
+ // Read in database from specific file.
+ static bool init(string startFile = "../xmldoc/Index.xml",
+ bool append = false, ostream& os = cout) ;
+
+ // Overwrite existing database by reading from specific file.
+ static bool reInit(string startFile = "../xmldoc/Index.xml") ;
+
+ // Read in one update from a single line.
+ static bool readString(string line, bool warn = true,
+ ostream& os = cout) ;
+
+ // Write updates or everything to user-defined file.
+ static bool writeFile(ostream& os = cout, bool writeAll = false) ;
+ static bool writeFile(string toFile, bool writeAll = false) ;
+
+ // Print out table of database, either all or only changed ones,
+ // or ones containing a given string.
+ static void listAll(ostream& os = cout) {
+ list( true, false, " ", os); }
+ static void listChanged(ostream& os = cout) {
+ list (false, false, " ", os); }
+ static void list(string match, ostream& os = cout) {
+ list (false, true, match, os); }
+
+ // Reset all values to their defaults.
+ static void resetAll() ;
+
+ // Query existence of an entry.
+ static bool isFlag(string keyIn) {
+ return (flags.find(toLower(keyIn)) != flags.end()); }
+ static bool isMode(string keyIn) {
+ return (modes.find(toLower(keyIn)) != modes.end()); }
+ static bool isParm(string keyIn) {
+ return (parms.find(toLower(keyIn)) != parms.end()); }
+ static bool isWord(string keyIn) {
+ return (words.find(toLower(keyIn)) != words.end()); }
+
+ // Add new entry.
+ static void addFlag(string keyIn, bool defaultIn) {
+ flags[toLower(keyIn)] = Flag(keyIn, defaultIn); }
+ static void addMode(string keyIn, int defaultIn, bool hasMinIn,
+ bool hasMaxIn, int minIn, int maxIn) { modes[toLower(keyIn)]
+ = Mode(keyIn, defaultIn, hasMinIn, hasMaxIn, minIn, maxIn); }
+ static void addParm(string keyIn, double defaultIn, bool hasMinIn,
+ bool hasMaxIn, double minIn, double maxIn) { parms[toLower(keyIn)]
+ = Parm(keyIn, defaultIn, hasMinIn, hasMaxIn, minIn, maxIn); }
+ static void addWord(string keyIn, string defaultIn) {
+ words[toLower(keyIn)] = Word(keyIn, defaultIn); }
+
+ // Give back current value, with check that key exists.
+ static bool flag(string keyIn);
+ static int mode(string keyIn);
+ static double parm(string keyIn);
+ static string word(string keyIn);
+
+ // Change current value, respecting limits.
+ static void flag(string keyIn, bool nowIn);
+ static void mode(string keyIn, int nowIn);
+ static void parm(string keyIn, double nowIn);
+ static void word(string keyIn, string nowIn);
+
+ // Change current value, disregarding limits.
+ static void forceMode(string keyIn, int nowIn) {
+ if (isMode(keyIn)) modes[toLower(keyIn)].valNow = nowIn; }
+ static void forceParm(string keyIn, double nowIn) {
+ if (isParm(keyIn)) parms[toLower(keyIn)].valNow = nowIn; }
+
+ // Restore current value to default.
+ static void resetFlag(string keyIn) {
+ if (isFlag(keyIn)) flags[toLower(keyIn)].valNow
+ = flags[toLower(keyIn)].valDefault ; }
+ static void resetMode(string keyIn) {
+ if (isMode(keyIn)) modes[toLower(keyIn)].valNow
+ = modes[toLower(keyIn)].valDefault ; }
+ static void resetParm(string keyIn) {
+ if (isParm(keyIn)) parms[toLower(keyIn)].valNow
+ = parms[toLower(keyIn)].valDefault ; }
+ static void resetWord(string keyIn) {
+ if (isWord(keyIn)) words[toLower(keyIn)].valNow
+ = words[toLower(keyIn)].valDefault ; }
+
+private:
+
+ // Pointer to various information on the generation.
+ static Info* infoPtr;
+
+ // Map for bool flags.
+ static map<string, Flag> flags;
+
+ // Map for integer modes.
+ static map<string, Mode> modes;
+
+ // Map for double parms.
+ static map<string, Parm> parms;
+
+ // Map for string words.
+ static map<string, Word> words;
+
+ // Flag that initialization has been performed.
+ static bool isInit;
+
+ // Print out table of database, called from listAll and listChanged.
+ static void list(bool listAll, bool listString, string match,
+ ostream& os = cout) ;
+
+ // Useful functions for string handling.
+ static string toLower(const string& name);
+ static bool boolString(string tag);
+ static string attributeValue(string line, string attribute);
+ static bool boolAttributeValue(string line, string attribute);
+ static int intAttributeValue(string line, string attribute);
+ static double doubleAttributeValue(string line, string attribute);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_Settings_H
--- /dev/null
+// SigmaCompositeness.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for compositiness-process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma(1/2)Process.
+
+#ifndef Pythia8_SigmaCompositeness_H
+#define Pythia8_SigmaCompositeness_H
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for q g -> q^* (excited quark state).
+
+class Sigma1qg2qStar : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1qg2qStar(int idqIn) : idq(idqIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for q* decay angles (else inactive).
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qg";}
+ virtual int resonanceA() const {return idRes;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idq, idRes, codeSave;
+ string nameSave;
+ double mRes, GammaRes, m2Res, GamMRat, Lambda, coupFcol, widthIn, sigBW;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* qStarPtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for l gamma -> q^* (excited lepton state).
+
+class Sigma1lgm2lStar : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1lgm2lStar(int idlIn) : idl(idlIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for l* decay angles (else inactive).
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "fgm";}
+ virtual int resonanceA() const {return idRes;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idl, idRes, codeSave;
+ string nameSave;
+ double mRes, GammaRes, m2Res, GamMRat, Lambda, coupChg, widthIn, sigBW;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* qStarPtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for q q' -> q^* q' (excited quark state).
+
+class Sigma2qq2qStarq : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qq2qStarq(int idqIn) : idq(idqIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qq";}
+ virtual int id3Mass() const {return idRes;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idq, idRes, codeSave;
+ string nameSave;
+ double Lambda, preFac, openFracPos, openFracNeg, sigmaA, sigmaB;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> l^* lbar (excited lepton state).
+
+class Sigma2qqbar2lStarlbar : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2lStarlbar(int idlIn) : idl(idlIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return idRes;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idl, idRes, codeSave;
+ string nameSave;
+ double Lambda, preFac, openFracPos, openFracNeg, sigma;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaCompositeness_H
--- /dev/null
+// SigmaEW.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for electroweak process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma(1/2)Process.
+
+#ifndef Pythia8_SigmaEW_H
+#define Pythia8_SigmaEW_H
+
+#include "PythiaComplex.h"
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+
+//**************************************************************************
+
+// A derived class for q g -> q gamma (q = u, d, s, c, b).
+// Use massless approximation also for Q since no alternative.
+
+class Sigma2qg2qgamma : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2qgamma() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q g -> q gamma (udscb)";}
+ virtual int code() const {return 201;}
+ virtual string inFlux() const {return "qg";}
+
+private:
+
+ // Values stored for later use.
+ double mNew, m2New, sigUS, sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> g gamma.
+
+class Sigma2qqbar2ggamma : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2ggamma() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q qbar -> g gamma";}
+ virtual int code() const {return 202;}
+ virtual string inFlux() const {return "qqbarSame";}
+
+private:
+
+ // Values stored for later use.
+ double sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> g gamma.
+
+class Sigma2gg2ggamma : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2ggamma() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "g g -> g gamma";}
+ virtual int code() const {return 203;}
+ virtual string inFlux() const {return "gg";}
+
+private:
+
+ // Values stored for later use.
+ double chargeSum, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> gamma gamma.
+
+class Sigma2ffbar2gammagamma : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2gammagamma() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> gamma gamma";}
+ virtual int code() const {return 204;}
+ virtual string inFlux() const {return "ffbarSame";}
+
+private:
+
+ // Values stored for later use.
+ double sigTU, sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> gamma gamma.
+
+class Sigma2gg2gammagamma : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2gammagamma() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "g g -> gamma gamma";}
+ virtual int code() const {return 205;}
+ virtual string inFlux() const {return "gg";}
+
+private:
+
+ double charge2Sum, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for f f' -> f f' via t-channel gamma*/Z0 exchange.
+
+class Sigma2ff2fftgmZ : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ff2fftgmZ() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f f' -> f f' (t-channel gamma*/Z0)";}
+ virtual int code() const {return 211;}
+ virtual string inFlux() const {return "ff";}
+
+private:
+
+ // Z parameters for propagator.
+ int gmZmode;
+ double mZ, mZS, thetaWRat, sigmagmgm, sigmagmZ, sigmaZZ;
+
+};
+
+//**************************************************************************
+
+// A derived class for f_1 f_2 -> f_3 f_4 via t-channel W+- exchange.
+
+class Sigma2ff2fftW : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ff2fftW() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f_1 f_2 -> f_3 f_4 (t-channel W+-)";}
+ virtual int code() const {return 212;}
+ virtual string inFlux() const {return "ff";}
+
+private:
+
+ // W parameters for propagator.
+ double mW, mWS, thetaWRat, sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for q q' -> Q q" via t-channel W+- exchange.
+// Related to Sigma2ff2fftW class, but with massive matrix elements.
+
+class Sigma2qq2QqtW : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qq2QqtW(int idIn, int codeIn) : idNew(idIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angles in top decay (else inactive).
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ff";}
+ virtual int id3Mass() const {return idNew;}
+
+private:
+
+ // Values stored for process type. W parameters for propagator.
+ int idNew, codeSave;
+ string nameSave;
+ double mW, mWS, thetaWRat, sigma0, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> gamma*/Z0.
+
+class Sigma1ffbar2gmZ : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2gmZ() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for Z decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> gamma*/Z0";}
+ virtual int code() const {return 221;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int resonanceA() const {return 23;}
+
+private:
+
+ // Parameters set at initialization or for each new event.
+ int gmZmode;
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat,
+ gamSum, intSum, resSum, gamProp, intProp, resProp;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> W+-.
+
+class Sigma1ffbar2W : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2W() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar' -> W+-";}
+ virtual int code() const {return 222;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int resonanceA() const {return 24;}
+
+private:
+
+ // Parameters set at initialization.
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat, sigma0Pos, sigma0Neg;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> gamma* -> f' fbar', summed over light f'.
+// Allows pT-ordered evolution for multiple interactions.
+
+class Sigma2ffbar2ffbarsgm : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2ffbarsgm() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {
+ return "f fbar -> f' fbar' (s-channel gamma*)";}
+ virtual int code() const {return 223;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual bool isSChannel() const {return true;}
+
+private:
+
+ // Values stored for later use.
+ int idNew;
+ double sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> gamma*/Z0 -> F Fbar, for one heavy F.
+// Allows pT cuts as for other 2 -> 2 processes.
+
+class Sigma2ffbar2FFbarsgmZ : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2FFbarsgmZ(int idIn, int codeIn) : idNew(idIn),
+ codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angles in top decay (else inactive).
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual bool isSChannel() const {return true;}
+ virtual int id3Mass() const {return idNew;}
+ virtual int id4Mass() const {return idNew;}
+ virtual int resonanceA() const {return 23;}
+
+private:
+
+ // Values stored for process type. Z parameters for propagator.
+ int idNew, codeSave, gmZmode;
+ string nameSave;
+ bool isPhysical;
+ double ef, vf, af, mRes, GammaRes, m2Res, GamMRat, thetaWRat,
+ mr, betaf, cosThe, gamProp, intProp, resProp, openFracPair;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> W+- -> F fbar", for one or two heavy F.
+// Allows pT cuts as for other 2 -> 2 processes.
+
+class Sigma2ffbar2FfbarsW : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2FfbarsW(int idIn, int idIn2, int codeIn) : idNew(idIn),
+ idNew2(idIn2), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angles in top decay (else inactive).
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual bool isSChannel() const {return true;}
+ virtual int id3Mass() const {return idNew;}
+ virtual int id4Mass() const {return idPartner;}
+ virtual int resonanceA() const {return 24;}
+
+private:
+
+ // Values stored for process type. W parameters for propagator.
+ int idNew, idNew2, codeSave, idPartner;
+ string nameSave;
+ bool isPhysical;
+ double V2New, mRes, GammaRes, m2Res, GamMRat, thetaWRat, sigma0,
+ openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// An intermediate class for f fbar -> gamma*/Z0/W+- gamma*/Z0/W-+.
+
+class Sigma2ffbargmZWgmZW : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbargmZWgmZW() {}
+
+protected:
+
+ // Internal products.
+ Vec4 pRot[7];
+ complex hA[7][7];
+ complex hC[7][7];
+
+ // Calculate and store internal products.
+ void setupProd( Event& process, int i1, int i2, int i3, int i4,
+ int i5, int i6);
+
+ // Evaluate the F function of Gunion and Kunszt.
+ complex fGK(int i1, int i2, int i3, int i4, int i5, int i6);
+
+ // Evaluate the Xi function of Gunion and Kunszt.
+ double xiGK( double tHnow, double uHnow);
+
+ // Evaluate the Xj function of Gunion and Kunszt.
+ double xjGK( double tHnow, double uHnow);
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> gamma*/Z0 gamma*/Z0.
+
+class Sigma2ffbar2gmZgmZ : public Sigma2ffbargmZWgmZW {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2gmZgmZ() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for simultaneous flavour choices.
+ virtual double weightDecayFlav( Event& process);
+
+ // Evaluate weight for decay angles of the two gamma*/Z0.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> gamma*/Z0 gamma*/Z0";}
+ virtual int code() const {return 231;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int id3Mass() const {return 23;}
+ virtual int id4Mass() const {return 23;}
+
+private:
+
+ // Parameters set at initialization or for each new event.
+ int gmZmode, i1, i2, i3, i4, i5, i6;
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat, sigma0,
+ gamSum3, intSum3, resSum3, gamProp3, intProp3, resProp3,
+ gamSum4, intSum4, resSum4, gamProp4, intProp4, resProp4,
+ c3LL, c3LR, c3RL, c3RR, c4LL, c4LR, c4RL, c4RR, flavWt;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> Z0 W+-. (Here pure Z0, unfortunately.)
+
+class Sigma2ffbar2ZW : public Sigma2ffbargmZWgmZW {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2ZW() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for Z0 and W+- decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar' -> Z0 W+- (no gamma*!)";}
+ virtual int code() const {return 232;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int id3Mass() const {return 23;}
+ virtual int id4Mass() const {return 24;}
+ virtual int resonanceA() const {return 24;}
+
+private:
+
+ // Store W+- mass and width, and couplings.
+ double mW, widW, mWS, mwWS, sin2thetaW, cos2thetaW, thetaWRat,
+ thetaWpt, thetaWmm, lun, lde, sigma0, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> W+ W-.
+
+class Sigma2ffbar2WW : public Sigma2ffbargmZWgmZW {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2WW() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W+ and W- decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> W+ W-";}
+ virtual int code() const {return 233;}
+ virtual int id3Mass() const {return 24;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int id4Mass() const {return -24;}
+ virtual int resonanceA() const {return 23;}
+
+private:
+
+ // Store Z0 mass and width.
+ double mZ, widZ, mZS, mwZS, thetaWRat, sigma0, cgg, cgZ, cZZ, cfg,
+ cfZ, cff, gSS, gTT, gST, gUU, gSU, openFracPair;
+
+};
+
+//**************************************************************************
+
+// An intermediate class for f fbar -> gamma*/Z0 g/gamma and permutations.
+
+class Sigma2ffbargmZggm : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbargmZggm() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Evaluate weight for gamma&/Z0 decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+protected:
+
+ // Parameters set at initialization or for each new event.
+ int gmZmode;
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat,
+ gamSum, intSum, resSum, gamProp, intProp, resProp;
+
+ // Evaluate current sum of flavour couplings times phase space.
+ void flavSum();
+
+ // Evaluate current propagator terms of cross section.
+ void propTerm();
+
+private:
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> gamma*/Z0 g.
+
+class Sigma2qqbar2gmZg : public Sigma2ffbargmZggm {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2gmZg() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q qbar -> gamma*/Z0 g";}
+ virtual int code() const {return 241;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return 23;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> gamma*/Z0 q.
+
+class Sigma2qg2gmZq : public Sigma2ffbargmZggm {
+
+public:
+
+ // Constructor.
+ Sigma2qg2gmZq() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q g-> gamma*/Z0 q";}
+ virtual int code() const {return 242;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return 23;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> gamma*/Z0 gamma.
+
+class Sigma2ffbar2gmZgm : public Sigma2ffbargmZggm {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2gmZgm() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> gamma*/Z0 gamma";}
+ virtual int code() const {return 243;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int id3Mass() const {return 23;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for f gamma -> gamma*/Z0 f.
+
+class Sigma2fgm2gmZf : public Sigma2ffbargmZggm {
+
+public:
+
+ // Constructor.
+ Sigma2fgm2gmZf() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f gamma -> gamma*/Z0 f";}
+ virtual int code() const {return 244;}
+ virtual string inFlux() const {return "fgm";}
+ virtual int id3Mass() const {return 23;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0;
+
+};
+
+//**************************************************************************
+
+// An intermediate class for f fbar -> W+- g/gamma and permutations.
+
+class Sigma2ffbarWggm : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbarWggm() {}
+
+ // Evaluate weight for gamma&/Z0 decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar' -> W+- g.
+
+class Sigma2qqbar2Wg : public Sigma2ffbarWggm {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2Wg() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q qbar' -> W+- g";}
+ virtual int code() const {return 251;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int id3Mass() const {return 24;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> W+- q'.
+
+class Sigma2qg2Wq : public Sigma2ffbarWggm {
+
+public:
+
+ // Constructor.
+ Sigma2qg2Wq() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q g-> W+- q'";}
+ virtual int code() const {return 252;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return 24;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> W+- gamma.
+
+class Sigma2ffbar2Wgm : public Sigma2ffbarWggm {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2Wgm() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar' -> W+- gamma";}
+ virtual int code() const {return 253;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int id3Mass() const {return 24;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for f gamma -> W+- f'.
+
+class Sigma2fgm2Wf : public Sigma2ffbarWggm {
+
+public:
+
+ // Constructor.
+ Sigma2fgm2Wf() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f gamma -> W+- f'";}
+ virtual int code() const {return 254;}
+ virtual string inFlux() const {return "fgm";}
+ virtual int id3Mass() const {return 24;}
+
+private:
+
+ // Values stored for later use.
+ double sigma0, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaEW_H
--- /dev/null
+// SigmaExtraDim.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for extra-dimensional-process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma(1/2)Process.
+
+#ifndef Pythia8_SigmaExtraDim_H
+#define Pythia8_SigmaExtraDim_H
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for g g -> G^* (excited graviton state).
+
+class Sigma1gg2GravitonStar : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1gg2GravitonStar() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for G* decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "g g -> G*";}
+ virtual int code() const {return 5001;}
+ virtual string inFlux() const {return "gg";}
+ virtual int resonanceA() const {return idGstar;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idGstar;
+ double mRes, GammaRes, m2Res, GamMRat, kappaMG, sigma;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* gStarPtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> G^* (excited graviton state).
+
+class Sigma1ffbar2GravitonStar : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2GravitonStar() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return (abs(id1) < 9) ? sigma0 / 3. : sigma0;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for G* decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> G*";}
+ virtual int code() const {return 5002;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int resonanceA() const {return idGstar;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idGstar;
+ double mRes, GammaRes, m2Res, GamMRat, kappaMG, sigma0;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* gStarPtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> G^* g (excited graviton state).
+
+class Sigma2gg2GravitonStarg : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2GravitonStarg() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight: currently isotropic (except secondary top decay)..
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "g g -> G* g";}
+ virtual int code() const {return 5003;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return idGstar;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idGstar;
+ double mRes, GammaRes, m2Res, GamMRat, kappaMG, openFrac, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> G^* q (excited graviton state).
+
+class Sigma2qg2GravitonStarq : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2GravitonStarq() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight: currently isotropic (except secondary top decay)..
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "q g -> G* q";}
+ virtual int code() const {return 5004;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return idGstar;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idGstar;
+ double mRes, GammaRes, m2Res, GamMRat, kappaMG, openFrac, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> G^* g (excited graviton state).
+
+class Sigma2qqbar2GravitonStarg : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2GravitonStarg() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight: currently isotropic (except secondary top decay)..
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "q qbar -> G* g";}
+ virtual int code() const {return 5005;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return idGstar;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idGstar;
+ double mRes, GammaRes, m2Res, GamMRat, kappaMG, openFrac, sigma;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaExtraDim_H
--- /dev/null
+// SigmaHiggs.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// Part of code written by Marc Montull, CERN summer student 2007.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for Higgs process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma2Process.
+
+#ifndef Pythia8_SigmaHiggs_H
+#define Pythia8_SigmaHiggs_H
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for f fbar -> H0 (SM), H1, H2 or A3 (BSM).
+
+class Sigma1ffbar2H : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2H(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int resonanceA() const {return idRes;}
+
+private:
+
+ // An H0, H1, H2 or A3 resonance object provides coupling
+ // and propagator expressions.
+ ParticleDataEntry* HResPtr;
+ double mRes, GammaRes, m2Res, GamMRat, sigBW, widthOut;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for g g -> H0 (SM), H1, H2 or A3 (BSM).
+
+class Sigma1gg2H : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1gg2H(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave ;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gg";}
+ virtual int resonanceA() const {return idRes;}
+
+private:
+
+ // A H0, H1, H2 or A3 resonance object provides coupling
+ // and propagator expressions.
+ ParticleDataEntry* HResPtr;
+ double mRes, GammaRes, m2Res, GamMRat, sigma;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for gamma gamma -> H0 (SM Higgs), H1, H2 or A3 (BSM Higgs).
+
+class Sigma1gmgm2H : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1gmgm2H(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gmgm";}
+ virtual int resonanceA() const {return idRes;}
+
+private:
+
+ // A H0, H1, H2 or A3 resonance object provides coupling
+ // and propagator expressions.
+ ParticleDataEntry* HResPtr;
+ double mRes, GammaRes, m2Res, GamMRat, sigma;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> H Z0.
+// (H can be H0 SM or H1, H2, A3 from BSM).
+class Sigma2ffbar2HZ : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2HZ(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual bool isSChannel() const {return true;}
+ virtual int id3Mass() const {return idRes;}
+ virtual int id4Mass() const {return 23;}
+ virtual int resonanceA() const {return 23;}
+ virtual int gmZmode() const {return 2;}
+
+private:
+
+ // Store Z0 mass and width.
+ double mZ, widZ, mZS, mwZS, thetaWRat, sigma0, openFracPair, coup2Z;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> H W+- (Standard Model Higgs).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma2ffbar2HW : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2HW(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual bool isSChannel() const {return true;}
+ virtual int id3Mass() const {return idRes;}
+ virtual int id4Mass() const {return 24;}
+ virtual int resonanceA() const {return 24;}
+
+private:
+
+ // Store W+- mass and width, and couplings.
+ double mW, widW, mWS, mwWS, thetaWRat, sigma0, openFracPairPos,
+ openFracPairNeg, coup2W;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for f f' -> H f f' (Z0 Z0 fusion of SM or BSM Higgs).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma3ff2HfftZZ : public Sigma3Process {
+
+public:
+
+ // Constructor.
+ Sigma3ff2HfftZZ(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ff";}
+ virtual int id3Mass() const {return idRes;}
+
+ // Instructions for 3-body phase space with t-channel propagators.
+ virtual int idTchan1() const {return 23;}
+ virtual int idTchan2() const {return 23;}
+ virtual double tChanFracPow1() const {return 0.05;}
+ virtual double tChanFracPow2() const {return 0.9;}
+ virtual bool useMirrorWeight() const {return true;}
+
+private:
+
+ // Store standard factors.
+ double mZS, prefac, sigma1, sigma2, openFrac, coup2Z;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for f_1 f_2 -> H f_3 f_4 (W+ W- fusion of SM or BSM Higgs).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma3ff2HfftWW : public Sigma3Process {
+
+public:
+
+ // Constructor.
+ Sigma3ff2HfftWW(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ff";}
+ virtual int id3Mass() const {return idRes;}
+
+ // Instructions for 3-body phase space with t-channel propagators.
+ virtual int idTchan1() const {return 24;}
+ virtual int idTchan2() const {return 24;}
+ virtual double tChanFracPow1() const {return 0.05;}
+ virtual double tChanFracPow2() const {return 0.9;}
+ virtual bool useMirrorWeight() const {return true;}
+
+private:
+
+ // Store standard prefactor.
+ double mWS, prefac, sigma0, openFrac, coup2W;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for g g -> H Q Qbar (Q Qbar fusion of SM or BSM Higgs).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma3gg2HQQbar : public Sigma3Process {
+
+public:
+
+ // Constructor.
+ Sigma3gg2HQQbar(int idIn, int higgsTypeIn) : idNew(idIn),
+ higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return idRes;}
+ virtual int id4Mass() const {return idNew;}
+ virtual int id5Mass() const {return idNew;}
+
+ // Instructions for 3-body phase space with t-channel propagators.
+ virtual int idTchan1() const {return idNew;}
+ virtual int idTchan2() const {return idNew;}
+ virtual double tChanFracPow1() const {return 0.4;}
+ virtual double tChanFracPow2() const {return 0.2;}
+ virtual bool useMirrorWeight() const {return false;}
+
+private:
+
+ // Store flavour-specific process information and standard prefactor.
+ double prefac, sigma, openFracTriplet, coup2Q;
+ int idNew, higgsType, codeSave, idRes;
+ string nameSave;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> H Q Qbar (Q Qbar fusion of SM or BSM Higgs).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma3qqbar2HQQbar : public Sigma3Process {
+
+public:
+
+ // Constructor.
+ Sigma3qqbar2HQQbar(int idIn, int higgsTypeIn) : idNew(idIn),
+ higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return idRes;}
+ virtual int id4Mass() const {return idNew;}
+ virtual int id5Mass() const {return idNew;}
+
+ // Instructions for 3-body phase space with t-channel propagators.
+ virtual int idTchan1() const {return idNew;}
+ virtual int idTchan2() const {return idNew;}
+ virtual double tChanFracPow1() const {return 0.4;}
+ virtual double tChanFracPow2() const {return 0.2;}
+ virtual bool useMirrorWeight() const {return false;}
+
+private:
+
+ // Store flavour-specific process information and standard prefactor.
+ double prefac, sigma, openFracTriplet, coup2Q;
+ int idNew, higgsType, codeSave, idRes;
+ string nameSave;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> H q (SM or BSM Higgs).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma2qg2Hq : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2Hq(int idIn, int higgsTypeIn) : idNew(idIn),
+ higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return idRes;}
+ virtual int id4Mass() const {return idNew;}
+
+private:
+
+ // Store flavour-specific process information and standard prefactor.
+ double m2W, thetaWRat, sigma, openFrac;
+ int idNew, higgsType, codeSave, idRes;
+ string nameSave;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> H0 g (SM or BSM Higgs via heavy top loop).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma2gg2Hglt : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2Hglt(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return idRes;}
+
+private:
+
+ // Store standard prefactor.
+ double widHgg, sigma, openFrac;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for q g -> H q (SM or BSM Higgs via heavy top loop).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma2qg2Hqlt : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2Hqlt(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return idRes;}
+
+private:
+
+ // Store standard prefactor.
+ double widHgg, sigma, openFrac;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> H g (SM or BSM Higgs via heavy top loop).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+class Sigma2qqbar2Hglt : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2Hglt(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return idRes;}
+
+private:
+
+ // Store standard prefactor.
+ double widHgg, sigma, openFrac;
+ int higgsType, codeSave, idRes;
+ string nameSave;
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> H+-.
+
+class Sigma1ffbar2Hchg : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2Hchg() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar' -> H+-";}
+ virtual int code() const {return 961;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int resonanceA() const {return 37;}
+
+private:
+
+ // A H0 resonance object provides coupling and propagator expressions.
+ ParticleDataEntry* HResPtr;
+ double mRes, GammaRes, m2Res, GamMRat, m2W, thetaWRat, tan2Beta, sigBW,
+ widthOutPos, widthOutNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> H+- q'.
+
+class Sigma2qg2Hchgq : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2Hchgq(int idIn, int codeIn, string nameIn) : idNew(idIn),
+ codeSave(codeIn), nameSave(nameIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return 37;}
+ virtual int id4Mass() const {return idNew;}
+
+private:
+
+ // Store flavour-specific process information and standard prefactor.
+ int idNew, codeSave, idOld, idUp, idDn;
+ string nameSave;
+ double m2W, thetaWRat, tan2Beta, sigma, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> A0(H_3) h0(H_1) or A0(H_3) H0(H_2).
+
+class Sigma2ffbar2A3H12 : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2A3H12(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int id3Mass() const {return 36;}
+ virtual int id4Mass() const {return higgs12;}
+
+private:
+
+ // Store flavour-specific process information and standard prefactor.
+ int higgsType, higgs12, codeSave;
+ string nameSave;
+ double coupZA3H12, m2Z, mGammaZ, thetaWRat, openFrac, sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> H+- h0(H_1) or H+- H0(H_2).
+
+class Sigma2ffbar2HchgH12 : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2HchgH12(int higgsTypeIn) : higgsType(higgsTypeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int id3Mass() const {return 37;}
+ virtual int id4Mass() const {return higgs12;}
+
+private:
+
+ // Store flavour-specific process information and standard prefactor.
+ int higgsType, higgs12, codeSave;
+ string nameSave;
+ double coupWHchgH12, m2W, mGammaW, thetaWRat, openFracPos, openFracNeg,
+ sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> H+ H-.
+
+class Sigma2ffbar2HposHneg : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2HposHneg() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> H+ H-";}
+ virtual int code() const {return 1085;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int id3Mass() const {return 37;}
+ virtual int id4Mass() const {return 37;}
+
+private:
+
+ // Store flavour-specific process information and standard prefactor.
+ double m2Z, mGammaZ, thetaWRat, eH, lH, openFrac, gamSig, intSig, resSig;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaHiggs_H
--- /dev/null
+// SigmaLeftRightSym.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for left-rights-symmetry differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma(1/2/3)Process.
+
+#ifndef Pythia8_SigmaLeftRightSym_H
+#define Pythia8_SigmaLeftRightSym_H
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for f fbar -> Z_R^0 (righthanded gauge boson).
+
+class Sigma1ffbar2ZRight : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2ZRight() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for G* decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> Z_R^0";}
+ virtual int code() const {return 3101;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int resonanceA() const {return idZR;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idZR;
+ double mRes, GammaRes, m2Res, GamMRat, sin2tW, sigma0;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* ZRPtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> W_R^+- (righthanded gauge boson).
+
+class Sigma1ffbar2WRight : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2WRight() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar' -> W_R^+-";}
+ virtual int code() const {return 3102;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int resonanceA() const {return idWR;}
+
+private:
+
+ // Parameters set at initialization.
+ int idWR;
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat, sigma0Pos, sigma0Neg;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for l l -> H_L^++-- or H_R^++-- (doubly charged Higgs).
+
+class Sigma1ll2Hchgchg : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ll2Hchgchg(int leftRightIn ) : leftRight(leftRightIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ff";}
+ virtual int resonanceA() const {return idHLR;}
+
+private:
+
+ // Parameters set at initialization.
+ int leftRight, idHLR, codeSave;
+ string nameSave;
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat, yukawa[4][4];
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for l- gamma -> H_(L/R)^-- l+ (doubly charged Higgs).
+
+class Sigma2lgm2Hchgchgl : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2lgm2Hchgchgl(int leftRightIn, int idLepIn ) : leftRight(leftRightIn),
+ idLep(idLepIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "fgm";}
+ virtual int resonanceA() const {return idHLR;}
+
+private:
+
+ // Parameters set at initialization.
+ int leftRight, idHLR, idLep, codeSave;
+ string nameSave;
+ double yukawa[4], openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for f_1 f_2 -> H_(L/R)^++-- f_3 f_4 (W+- W+- fusion).
+
+class Sigma3ff2HchgchgfftWW : public Sigma3Process {
+
+public:
+
+ // Constructor.
+ Sigma3ff2HchgchgfftWW(int leftRightIn) : leftRight(leftRightIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for decay angles.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ff";}
+ virtual int id3Mass() const {return idHLR;}
+
+ // Instructions for 3-body phase space with t-channel propagators.
+ virtual int idTchan1() const {return 9900024;}
+ virtual int idTchan2() const {return 9900024;}
+ virtual double tChanFracPow1() const {return 0.05;}
+ virtual double tChanFracPow2() const {return 0.9;}
+ virtual bool useMirrorWeight() const {return true;}
+
+private:
+
+ // Store standard prefactor.
+ int leftRight, idHLR, codeSave;
+ string nameSave;
+ double mWS, prefac, sigma0TU, sigma0T, openFracPos, openFracNeg;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> H_(L/R)^++ H_(L/R)^-- (doubly charged Higgs).
+
+class Sigma2ffbar2HchgchgHchgchg : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2ffbar2HchgchgHchgchg(int leftRightIn) : leftRight(leftRightIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int id3Mass() const {return idHLR;}
+ virtual int id4Mass() const {return idHLR;}
+ virtual int resonanceA() const {return 23;}
+
+private:
+
+ // Parameters set at initialization.
+ int leftRight, idHLR, codeSave;
+ string nameSave;
+ double mRes, GammaRes, m2Res, GamMRat, sin2tW, preFac, yukawa[4][4],
+ openFrac;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaLeftRightSym_H
--- /dev/null
+// SigmaLeptoquark.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for leptoquark-process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma(1/2)Process.
+// Note: since leptoquark assumed scalar no need for decay-angles routines.
+
+#ifndef Pythia8_SigmaLeptoquark_H
+#define Pythia8_SigmaLeptoquark_H
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for q l -> LQ (leptoquark).
+
+class Sigma1ql2LeptoQuark : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ql2LeptoQuark() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q l -> LQ (leptoquark)";}
+ virtual int code() const {return 3201;}
+ virtual string inFlux() const {return "ff";}
+ virtual int resonanceA() const {return 42;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idQuark, idLepton;
+ double mRes, GammaRes, m2Res, GamMRat, kCoup, widthIn, sigBW;
+
+ // Pointer to properties of the particle species, to access decay channel.
+ ParticleDataEntry* LQPtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> LQ l (leptoquark).
+
+class Sigma2qg2LeptoQuarkl : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2LeptoQuarkl() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q g -> LQ l (leptoquark)";}
+ virtual int code() const {return 3202;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return 42;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idQuark, idLepton;
+ double mRes, GammaRes, m2Res, GamMRat, kCoup, openFracPos, openFracNeg,
+ sigma0;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> LQ LQbar (leptoquark).
+
+class Sigma2gg2LQLQbar : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2LQLQbar() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "g g -> LQ LQbar (leptoquark)";}
+ virtual int code() const {return 3203;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return 42;}
+ virtual int id4Mass() const {return 42;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ double mRes, GammaRes, m2Res, GamMRat, openFrac, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> LQ LQbar (leptoquark).
+
+class Sigma2qqbar2LQLQbar : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2LQLQbar() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat() {
+ return (abs(id1) == idQuark) ? sigmaSame : sigmaDiff;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q qbar -> LQ LQbar (leptoquark)";}
+ virtual int code() const {return 3204;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return 42;}
+ virtual int id4Mass() const {return 42;}
+
+private:
+
+ // Parameters set at initialization or for current kinematics.
+ int idQuark;
+ double mRes, GammaRes, m2Res, GamMRat, kCoup, openFrac, sigmaDiff,
+ sigmaSame;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaLeptoquark_H
--- /dev/null
+// SigmaNewGaugeBosons.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for new-gauge-boson-process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma1Process.
+
+#ifndef Pythia8_SigmaNewGaugeBosons_H
+#define Pythia8_SigmaNewGaugeBosons_H
+
+#include "PythiaComplex.h"
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// An intermediate class for f fbar -> Z'/W' -> WW/WZ -> 4 fermions.
+// Copied from SigmaEW for gauge-boson-pair production.
+
+class Sigma1ffbarZprimeWprime: public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbarZprimeWprime() {}
+
+protected:
+
+ // Internal products.
+ Vec4 pRot[7];
+ complex hA[7][7];
+ complex hC[7][7];
+
+ // Calculate and store internal products.
+ void setupProd( Event& process, int i1, int i2, int i3, int i4,
+ int i5, int i6);
+
+ // Evaluate the F function of Gunion and Kunszt.
+ complex fGK(int i1, int i2, int i3, int i4, int i5, int i6);
+
+ // Evaluate the Xi function of Gunion and Kunszt.
+ double xiGK( double tHnow, double uHnow, double s3now, double s4now);
+
+ // Evaluate the Xj function of Gunion and Kunszt.
+ double xjGK( double tHnow, double uHnow, double s3now, double s4now);
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar -> gamma*/Z0/Z'0.
+
+class Sigma1ffbar2gmZZprime : public Sigma1ffbarZprimeWprime {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2gmZZprime() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for Z' decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar -> gamma*/Z0/Zprime0";}
+ virtual int code() const {return 3001;}
+ virtual string inFlux() const {return "ffbarSame";}
+ virtual int resonanceA() const {return 23;}
+ virtual int resonanceB() const {return 32;}
+
+private:
+
+ // Parameters set at initialization or for each new event.
+ int gmZmode;
+ double mRes, GammaRes, m2Res, GamMRat, sin2tW, cos2tW, thetaWRat,
+ mZ, GammaZ, m2Z, GamMRatZ, afZp[20], vfZp[20], coupZpWW,
+ anglesZpWW, gamSum, gamZSum, ZSum, gamZpSum, ZZpSum, ZpSum,
+ gamNorm, gamZNorm, ZNorm, gamZpNorm, ZZpNorm, ZpNorm;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+// A derived class for f fbar' -> W'+-.
+
+class Sigma1ffbar2Wprime : public Sigma1ffbarZprimeWprime {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2Wprime() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angle.
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar' -> W'+-";}
+ virtual int code() const {return 3021;}
+ virtual string inFlux() const {return "ffbarChg";}
+ virtual int resonanceA() const {return 34;}
+
+private:
+
+ // Parameters set at initialization.
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat, sigma0Pos, sigma0Neg,
+ aqWp, vqWp, alWp, vlWp, coupWpWZ, anglesWpWZ;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+//**************************************************************************
+
+// A derived class for f fbar' -> R^0 (horizontal gauge boson).
+
+class Sigma1ffbar2Rhorizontal : public Sigma1Process {
+
+public:
+
+ // Constructor.
+ Sigma1ffbar2Rhorizontal() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate sigmaHat(sHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "f fbar' -> R^0";}
+ virtual int code() const {return 3041;}
+ virtual string inFlux() const {return "ffbar";}
+ virtual int resonanceA() const {return 41;}
+
+private:
+
+ // Parameters set at initialization.
+ double mRes, GammaRes, m2Res, GamMRat, thetaWRat, sigma0Pos, sigma0Neg;
+
+ // Pointer to properties of the particle species, to access decay channels.
+ ParticleDataEntry* particlePtr;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia_SigmaNewGaugeBosons_H
--- /dev/null
+// SigmaOnia.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for charmonia/bottomonia process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma2Process.
+
+#ifndef Pythia8_SigmaOnia_H
+#define Pythia8_SigmaOnia_H
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for g g -> QQbar[3S1(1)] g (Q = c or b).
+
+class Sigma2gg2QQbar3S11g : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2QQbar3S11g(int idIn, int codeIn) : idNew(idIn),
+ codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return idHad;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, idHad, codeSave;
+ string nameSave;
+ double oniumME, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> QQbar[3PJ(1)] g (Q = c or b, J = 0, 1 or 2).
+
+class Sigma2gg2QQbar3PJ1g : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2QQbar3PJ1g(int idIn, int jIn, int codeIn) : idNew(idIn),
+ jSave(jIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return idHad;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, idHad, jSave, codeSave;
+ string nameSave;
+ double oniumME, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> QQbar[3PJ(1)] q (Q = c or b, J = 0, 1 or 2).
+
+class Sigma2qg2QQbar3PJ1q : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2QQbar3PJ1q(int idIn, int jIn, int codeIn) : idNew(idIn),
+ jSave(jIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return idHad;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, idHad, jSave, codeSave;
+ string nameSave;
+ double oniumME, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> QQbar[3PJ(1)] g (Q = c or b, J = 0, 1 or 2).
+
+class Sigma2qqbar2QQbar3PJ1g : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2QQbar3PJ1g(int idIn, int jIn, int codeIn) : idNew(idIn),
+ jSave(jIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return idHad;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, idHad, jSave, codeSave;
+ string nameSave;
+ double oniumME, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> QQbar[X(8)] g (Q = c or b, X = 3S1, 1S0 or 3PJ).
+
+class Sigma2gg2QQbarX8g : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2QQbarX8g(int idIn, int stateIn, int codeIn) : idNew(idIn),
+ stateSave(stateIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return idHad;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, idHad, stateSave, codeSave;
+ string nameSave;
+ double oniumME, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> QQbar[X(8)] q (Q = c or b, X = 3S1, 1S0 or 3PJ).
+
+class Sigma2qg2QQbarX8q : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2QQbarX8q(int idIn, int stateIn, int codeIn) : idNew(idIn),
+ stateSave(stateIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qg";}
+ virtual int id3Mass() const {return idHad;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, idHad, stateSave, codeSave;
+ string nameSave;
+ double oniumME, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> QQbar[X(8)] g (Q = c or b,
+// X = 3S1, 1S0 or 3PJ).
+
+class Sigma2qqbar2QQbarX8g : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2QQbarX8g(int idIn, int stateIn, int codeIn) : idNew(idIn),
+ stateSave(stateIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return idHad;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, idHad, stateSave, codeSave;
+ string nameSave;
+ double oniumME, sigma;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaOnia_H
--- /dev/null
+// SigmaProcess.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for hard-process differential cross sections.
+// SigmaProcess: base class for cross sections.
+// Sigma0Process: base class for unresolved processes, derived from above.
+// Sigma1Process: base class for 2 -> 1 processes, derived from above.
+// Sigma2Process: base class for 2 -> 2 processes, derived from above.
+// Sigma3Process: base class for 2 -> 3 processes, derived from above.
+// SigmaLHAProcess: wrapper class for Les Houches Accord external input.
+// Actual physics processes are found in separate files:
+// SigmaQCD for QCD processes;
+// SigmaEW for electroweak processes (including photon production);
+// SigmaOnia for charmonium and bottomonium processes;
+// SigmaHiggs for Higgs processes;
+// SigmaSUSY for supersymmetric production;
+// SigmaLeftRightSym for processes in left-right-symmetric scenarios;
+// SigmaLeptoquark for leptoquark production.
+// SigmaExtraDim for processes in scenarios for extra dimensions.
+
+#ifndef Pythia8_SigmaProcess_H
+#define Pythia8_SigmaProcess_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Event.h"
+#include "Info.h"
+#include "LesHouches.h"
+#include "ParticleData.h"
+#include "PartonDistributions.h"
+#include "PythiaStdlib.h"
+#include "ResonanceWidths.h"
+#include "Settings.h"
+#include "SigmaTotal.h"
+#include "StandardModel.h"
+#include "SusyLesHouches.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// InBeam is a simple helper class for partons and their flux in a beam.
+
+class InBeam {
+
+public:
+
+ // Constructor.
+ InBeam( int idIn = 0) : id(idIn), pdf(0.) {}
+
+ // Values.
+ int id;
+ double pdf;
+
+};
+
+//**************************************************************************
+
+// InPair is a simple helper class for colliding parton pairs and their flux.
+
+class InPair {
+
+public:
+
+ // Constructor.
+ InPair( int idAIn = 0, int idBIn = 0) : idA(idAIn), idB(idBIn),
+ pdfA(0.), pdfB(0.), pdfSigma(0.) {}
+
+ // Values.
+ int idA, idB;
+ double pdfA, pdfB, pdfSigma;
+
+};
+
+//**************************************************************************
+
+// SigmaProcess is the base class for cross section calculations.
+
+class SigmaProcess {
+
+public:
+
+ // Destructor.
+ virtual ~SigmaProcess() {}
+
+ // Perform simple initialization and store pointers.
+ void init(Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn, AlphaStrong* alphaSPtrIn,
+ AlphaEM* alphaEMPtrIn, SigmaTotal* sigmaTotPtrIn,
+ SusyLesHouches* slhaPtrIn);
+
+ // Store or replace Les Houches pointer.
+ void setLHAPtr( LHAup* lhaUpPtrIn) {lhaUpPtr = lhaUpPtrIn;}
+
+ // Initialize process. Only used for some processes.
+ virtual void initProc() {}
+
+ // Set up allowed flux of incoming partons. Default is no flux.
+ virtual bool initFlux();
+
+ // Input and complement kinematics for resolved 2 -> 1 process.
+ // Usage: set1Kin( x1in, x2in, sHin).
+ virtual void set1Kin( double , double , double ) {}
+
+ // Input and complement kinematics for resolved 2 -> 2 process.
+ // Usage: set2Kin( x1in, x2in, sHin, tHin, m3in, m4in, runBW3in, runBW4in).
+ virtual void set2Kin( double , double , double , double , double ,
+ double, double, double ) {}
+
+ // Ditto, but for Multiple Interactions applications, so different input.
+ // Usage: set2KinMI( x1in, x2in, sHin, tHin, uHin,
+ // alpSin, alpEMin, needMasses, m3in, m4in)
+ virtual void set2KinMI( double , double , double , double ,
+ double , double , double , bool , double , double ) {}
+
+ // Input and complement kinematics for resolved 2 -> 3 process.
+ // Usage: set3Kin( x1in, x2in, sHin, p3prel, p4prel, p5prel,
+ // m3in, m4in, m5in, runBW3in, runBW4in, runBW5in);
+ virtual void set3Kin( double , double , double , Vec4 , Vec4 , Vec4 ,
+ double , double , double , double , double , double ) {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin() {}
+
+ // Evaluate sigma for unresolved, sigmaHat(sHat) for 2 -> 1 processes,
+ // d(sigmaHat)/d(tHat) for (resolved) 2 -> 2 processes, and |M|^2 for
+ // 2 -> 3 processes. Answer in "native" units, either mb or GeV^-2.
+ virtual double sigmaHat() {return 0.;}
+
+ // Wrapper to sigmaHat, to (a) store current incoming flavours and
+ // (b) convert from GeV^-2 to mb where required.
+ double sigmaHatWrap(int id1in = 0, int id2in = 0) {
+ id1 = id1in; id2 = id2in;
+ return ( convert2mb() ? CONVERT2MB * sigmaHat() : sigmaHat() ); }
+
+ // Convolute above with parton flux and K factor. Sum over open channels.
+ virtual double sigmaPDF();
+
+ // Select incoming parton channel and extract parton densities (resolved).
+ void pickInState(int id1in = 0, int id2in = 0);
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol() {}
+
+ // Perform kinematics for a Multiple Interaction, in its rest frame.
+ virtual bool final2KinMI() {return true;}
+
+ // Evaluate weight for simultaneous flavours (only gamma*/Z0 gamma*/Z0).
+ // Usage: weightDecayFlav( process).
+ virtual double weightDecayFlav( Event&) {return 1.;}
+
+ // Evaluate weight for decay angular configuration.
+ // Usage: weightDecay( process, iResBeg, iResEnd), where
+ // iResBeg <= i < iResEnd is range of sister partons to test decays of.
+ virtual double weightDecay( Event&, int, int) {return 1.;}
+
+ // Process name and code, and the number of final-state particles.
+ virtual string name() const {return "unnamed process";}
+ virtual int code() const {return 0;}
+ virtual int nFinal() const {return 2;}
+
+ // Need to know which incoming partons to set up interaction for.
+ virtual string inFlux() const {return "unknown";}
+
+ // Need to know whether to convert cross section answer from GeV^-2 to mb.
+ virtual bool convert2mb() const {return true;}
+
+ // Special treatment needed for Les Houches processes.
+ virtual bool isLHA() const {return false;}
+
+ // Special treatment needed for elastic and diffractive processes.
+ virtual bool isMinBias() const {return false;}
+ virtual bool isResolved() const {return true;}
+ virtual bool isDiffA() const {return false;}
+ virtual bool isDiffB() const {return false;}
+
+ // Special treatment needed if negative cross sections allowed.
+ virtual bool allowNegativeSigma() const {return false;}
+
+ // Flavours in 2 -> 2/3 processes where masses needed from beginning.
+ // (For a light quark masses will be used in the final kinematics,
+ // but not at the matrix-element level. For a gluon no masses at all.)
+ virtual int id3Mass() const {return 0;}
+ virtual int id4Mass() const {return 0;}
+ virtual int id5Mass() const {return 0;}
+
+ // Special treatment needed if process contains an s-channel resonance.
+ virtual int resonanceA() const {return 0;}
+ virtual int resonanceB() const {return 0;}
+
+ // 2 -> 2 and 2 -> 3 processes only through s-channel exchange.
+ virtual bool isSChannel() const {return false;}
+
+ // Special treatment in 2 -> 3 with two massive propagators.
+ virtual int idTchan1() const {return 0;}
+ virtual int idTchan2() const {return 0;}
+ virtual double tChanFracPow1() const {return 0.3;}
+ virtual double tChanFracPow2() const {return 0.3;}
+ virtual bool useMirrorWeight() const {return false;}
+
+ // Special process-specific gamma*/Z0 choice if >=0 (e.g. f fbar -> H0 Z0).
+ virtual int gmZmode() const {return -1;}
+
+ // Tell whether tHat and uHat are swapped (= same as swap 3 and 4).
+ bool swappedTU() const {return swapTU;}
+
+ // Give back particle properties: flavours, colours, masses, or all.
+ int id(int i) const {return idSave[i];}
+ int col(int i) const {return colSave[i];}
+ int acol(int i) const {return acolSave[i];}
+ double m(int i) const {return mSave[i];}
+ Particle getParton(int i) const {return parton[i];}
+
+ // Give back couplings and parton densities. Not all known for minbias.
+ double Q2Ren() const {return Q2RenSave;}
+ double alphaEMRen() const {return alpEM;}
+ double alphaSRen() const {return alpS;}
+ double Q2Fac() const {return Q2FacSave;}
+ double pdf1() const {return pdf1Save;}
+ double pdf2() const {return pdf2Save;}
+
+ // Give back angles; relevant only for multipe-interactions processes.
+ double thetaMI() const {return atan2( sinTheta, cosTheta);}
+ double phiMI() const {return phi;}
+ double sHBetaMI() const {return sHBeta;}
+ double pT2MI() const {return pT2Mass;}
+
+protected:
+
+ // Constructor.
+ SigmaProcess() {for (int i = 0; i < 6; ++i) mSave[i] = 0.;}
+
+ // Constants: could only be changed in the code itself.
+ static const double CONVERT2MB, MASSMARGIN;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Pointers to alphaStrong and alphaElectromagnetic calculation.
+ AlphaStrong* alphaSPtr;
+ AlphaEM* alphaEMPtr;
+
+ // Pointer to the total/elastic/diffractive cross section object.
+ SigmaTotal* sigmaTotPtr;
+
+ // Pointer to LHAup for generating external events.
+ LHAup* lhaUpPtr;
+
+ // Pointer to the SLHA object.
+ SusyLesHouches* slhaPtr;
+
+ // Initialization data, normally only set once.
+ int nQuarkIn, renormScale1, renormScale2, renormScale3, renormScale3VV,
+ factorScale1, factorScale2, factorScale3, factorScale3VV;
+ double Kfactor, renormMultFac, renormFixScale, factorMultFac,
+ factorFixScale;
+
+ // CP violation parameters for Higgs sector, normally only set once.
+ int higgsH1parity, higgsH2parity, higgsA3parity;
+ double higgsH1eta, higgsH2eta, higgsA3eta;
+
+ // Information on incoming beams.
+ int idA, idB;
+ double mA, mB;
+ bool isLeptonA, isLeptonB, hasLeptonBeams;
+
+ // Partons in beams, with PDF's.
+ vector<InBeam> inBeamA;
+ vector<InBeam> inBeamB;
+ void addBeamA(int idIn) {inBeamA.push_back(InBeam(idIn));}
+ void addBeamB(int idIn) {inBeamB.push_back(InBeam(idIn));}
+ int sizeBeamA() const {return inBeamA.size();}
+ int sizeBeamB() const {return inBeamB.size();}
+
+ // Allowed colliding parton pairs, with pdf's.
+ vector<InPair> inPair;
+ void addPair(int idAIn, int idBIn) {
+ inPair.push_back(InPair(idAIn, idBIn));}
+ int sizePair() const {return inPair.size();}
+
+ // Store Q2 renormalization and factorization scales, and related values.
+ double Q2RenSave, alpEM, alpS, Q2FacSave, x1Save, x2Save, pdf1Save,
+ pdf2Save, sigmaSumSave;
+
+ // Store flavour, colour, anticolour, mass, angles and the whole particle.
+ int id1, id2, id3, id4, id5;
+ int idSave[6], colSave[6], acolSave[6];
+ double mSave[6], cosTheta, sinTheta, phi, sHMass, sHBeta, pT2Mass;
+ Particle parton[6];
+
+ // Store whether tHat and uHat are swapped (= same as swap 3 and 4).
+ bool swapTU;
+
+ // Set flavour, colour and anticolour.
+ void setId( int id1in = 0, int id2in = 0, int id3in = 0, int id4in = 0,
+ int id5in = 0) {idSave[1] = id1in; idSave[2] = id2in; idSave[3] = id3in;
+ idSave[4] = id4in; idSave[5] = id5in;}
+ void setColAcol( int col1 = 0, int acol1 = 0,
+ int col2 = 0, int acol2 = 0, int col3 = 0, int acol3 = 0,
+ int col4 = 0, int acol4 = 0, int col5 = 0, int acol5 = 0) {
+ colSave[1] = col1; acolSave[1] = acol1; colSave[2] = col2;
+ acolSave[2] = acol2; colSave[3] = col3; acolSave[3] = acol3;
+ colSave[4] = col4; acolSave[4] = acol4; colSave[5] = col5;
+ acolSave[5] = acol5; }
+ void swapColAcol() { swap(colSave[1], acolSave[1]);
+ swap(colSave[2], acolSave[2]); swap(colSave[3], acolSave[3]);
+ swap(colSave[4], acolSave[4]); swap(colSave[5], acolSave[5]);}
+ void swapCol1234() { swap(colSave[1], colSave[2]);
+ swap(colSave[3], colSave[4]); swap(acolSave[1], acolSave[2]);
+ swap(acolSave[3], acolSave[4]);}
+ void swapCol12() { swap(colSave[1], colSave[2]);
+ swap(acolSave[1], acolSave[2]);}
+ void swapCol34() { swap(colSave[3], colSave[4]);
+ swap(acolSave[3], acolSave[4]);}
+
+ // Common code for top and Higgs secondary decay angular weights.
+ double weightTopDecay( Event& process, int iResBeg, int iResEnd);
+ double weightHiggsDecay( Event& process, int iResBeg, int iResEnd);
+
+};
+
+//**************************************************************************
+
+// Sigma0Process is the base class for unresolved and minimum-bias processes.
+// It is derived from SigmaProcess.
+
+class Sigma0Process : public SigmaProcess {
+
+public:
+
+ // Destructor.
+ virtual ~Sigma0Process() {}
+
+ // Number of final-state particles.
+ virtual int nFinal() const {return 2;};
+
+ // No partonic flux to be set up.
+ virtual bool initFlux() {return true;}
+
+ // Evaluate sigma for unresolved processes.
+ virtual double sigmaHat() {return 0.;}
+
+ // Since no PDF's there is no difference from above.
+ virtual double sigmaPDF() {return sigmaHat();}
+
+ // Answer for these processes already in mb, so do not convert.
+ virtual bool convert2mb() const {return false;}
+
+protected:
+
+ // Constructor.
+ Sigma0Process() {}
+
+};
+
+//**************************************************************************
+
+// Sigma1Process is the base class for 2 -> 1 processes.
+// It is derived from SigmaProcess.
+
+class Sigma1Process : public SigmaProcess {
+
+public:
+
+ // Destructor.
+ virtual ~Sigma1Process() {}
+
+ // Number of final-state particles.
+ virtual int nFinal() const {return 1;};
+
+ // Input and complement kinematics for resolved 2 -> 1 process.
+ virtual void set1Kin( double x1in, double x2in, double sHin) {
+ store1Kin( x1in, x2in, sHin); sigmaKin();}
+
+ // Evaluate sigmaHat(sHat) for resolved 2 -> 1 processes.
+ virtual double sigmaHat() {return 0.;}
+
+protected:
+
+ // Constructor.
+ Sigma1Process() {}
+
+ // Store kinematics and set scales for resolved 2 -> 1 process.
+ virtual void store1Kin( double x1in, double x2in, double sHin);
+
+ // Store subprocess kinematics quantities.
+ double mH, sH, sH2;
+
+};
+
+//**************************************************************************
+
+// Sigma2Process is the base class for 2 -> 2 processes.
+// It is derived from SigmaProcess.
+
+class Sigma2Process : public SigmaProcess {
+
+public:
+
+ // Destructor.
+ virtual ~Sigma2Process() {}
+
+ // Number of final-state particles.
+ virtual int nFinal() const {return 2;};
+
+ // Input and complement kinematics for resolved 2 -> 2 process.
+ virtual void set2Kin( double x1in, double x2in, double sHin,
+ double tHin, double m3in, double m4in, double runBW3in,
+ double runBW4in) { store2Kin( x1in, x2in, sHin, tHin, m3in, m4in,
+ runBW3in, runBW4in); sigmaKin();}
+
+ // Ditto, but for Multiple Interactions applications, so different input.
+ virtual void set2KinMI( double x1in, double x2in, double sHin,
+ double tHin, double uHin, double alpSin, double alpEMin,
+ bool needMasses, double m3in, double m4in) {
+ store2KinMI( x1in, x2in, sHin, tHin, uHin, alpSin, alpEMin,
+ needMasses, m3in, m4in); sigmaKin();}
+
+ // Evaluate d(sigmaHat)/d(tHat) for resolved 2 -> 2 processes.
+ virtual double sigmaHat() {return 0.;}
+
+ // Perform kinematics for a Multiple Interaction, in its rest frame.
+ virtual bool final2KinMI();
+
+protected:
+
+ // Constructor.
+ Sigma2Process() {}
+
+ // Store kinematics and set scales for resolved 2 -> 2 process.
+ virtual void store2Kin( double x1in, double x2in, double sHin,
+ double tHin, double m3in, double m4in, double runBW3in,
+ double runBW4in);
+ virtual void store2KinMI( double x1in, double x2in, double sHin,
+ double tHin, double uHin, double alpSin, double alpEMin,
+ bool needMasses, double m3in, double m4in);
+
+ // Store subprocess kinematics quantities.
+ double mH, sH, tH, uH, sH2, tH2, uH2, m3, s3, m4, s4, pT2, runBW3, runBW4;
+
+};
+
+//**************************************************************************
+
+// Sigma3Process is the base class for 2 -> 3 processes.
+// It is derived from SigmaProcess.
+
+class Sigma3Process : public SigmaProcess {
+
+public:
+
+ // Destructor.
+ virtual ~Sigma3Process() {}
+
+ // Number of final-state particles.
+ virtual int nFinal() const {return 3;};
+
+ // Input and complement kinematics for resolved 2 -> 3 process.
+ virtual void set3Kin( double x1in, double x2in, double sHin,
+ Vec4 p3cmIn, Vec4 p4cmIn, Vec4 p5cmIn, double m3in, double m4in,
+ double m5in, double runBW3in, double runBW4in, double runBW5in) {
+ store3Kin( x1in, x2in, sHin, p3cmIn, p4cmIn, p5cmIn, m3in, m4in, m5in,
+ runBW3in, runBW4in, runBW5in); sigmaKin();}
+
+ // Evaluate d(sigmaHat)/d(tHat) for resolved 2 -> 3 processes.
+ virtual double sigmaHat() {return 0.;}
+
+protected:
+
+ // Constructor.
+ Sigma3Process() {}
+
+ // Store kinematics and set scales for resolved 2 -> 3 process.
+ virtual void store3Kin( double x1in, double x2in, double sHin,
+ Vec4 p3cmIn, Vec4 p4cmIn, Vec4 p5cmIn, double m3in, double m4in,
+ double m5in, double runBW3in, double runBW4in, double runBW5in);
+
+ // Store subprocess kinematics quantities.
+ double mH, sH, m3, s3, m4, s4, m5, s5, runBW3, runBW4, runBW5;
+ Vec4 p3cm, p4cm, p5cm;
+
+};
+
+//**************************************************************************
+
+// SigmaLHAProcess is a wrapper class for Les Houches Accord external input.
+// It is derived from SigmaProcess.
+
+class SigmaLHAProcess : public SigmaProcess {
+
+public:
+
+ // Constructor.
+ SigmaLHAProcess() {}
+
+ // Destructor.
+ virtual ~SigmaLHAProcess() {}
+
+ // No partonic flux to be set up.
+ virtual bool initFlux() {return true;}
+
+ // Dummy function: action is put in PhaseSpaceLHA.
+ virtual double sigmaPDF() {return 1.;}
+
+ // Info on the subprocess.
+ virtual string name() const {return "Les Houches User Process(es)";}
+ virtual int code() const {return 9999;}
+
+ // Number of final-state particles depends on current process choice.
+ virtual int nFinal() const;
+
+ // Answer for these processes not in GeV^-2, so do not do this conversion.
+ virtual bool convert2mb() const {return false;}
+
+ // Ensure special treatment of Les Houches processes.
+ virtual bool isLHA() const {return true;}
+
+ // Special treatment needed if negative cross sections allowed.
+ virtual bool allowNegativeSigma() const {
+ return (lhaUpPtr->strategy() < 0);}
+
+private:
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaProcess_H
+
--- /dev/null
+// SigmaQCD.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for QCD process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma(0/2)Process.
+
+#ifndef Pythia8_SigmaQCD_H
+#define Pythia8_SigmaQCD_H
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for minimum-bias (inelastic, nondiffractive) events.
+
+class Sigma0minBias : public Sigma0Process {
+
+public:
+
+ // Constructor.
+ Sigma0minBias() {}
+
+ // Evaluate sigma.
+ virtual double sigmaHat() {return sigmaTotPtr->sigmaND();}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol() {}
+
+ // Info on the subprocess.
+ virtual string name() const {return "minimum bias";}
+ virtual int code() const {return 101;}
+ virtual bool isMinBias() const {return true;}
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for elastic scattering A B -> A B.
+
+class Sigma0AB2AB : public Sigma0Process {
+
+public:
+
+ // Constructor.
+ Sigma0AB2AB() {}
+
+ // Evaluate sigma.
+ virtual double sigmaHat() {return sigmaTotPtr->sigmaEl();}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "A B -> A B elastic";}
+ virtual int code() const {return 102;}
+ virtual bool isResolved() const {return false;}
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for single diffractive scattering A B -> X B.
+
+class Sigma0AB2XB : public Sigma0Process {
+
+public:
+
+ // Constructor.
+ Sigma0AB2XB() {}
+
+ // Evaluate sigma.
+ virtual double sigmaHat() {return sigmaTotPtr->sigmaXB();}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "A B -> X B single diffractive";}
+ virtual int code() const {return 103;}
+ virtual bool isResolved() const {return false;}
+ virtual bool isDiffA() const {return true;};
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for single diffractive scattering A B -> A X.
+
+class Sigma0AB2AX : public Sigma0Process {
+
+public:
+
+ // Constructor.
+ Sigma0AB2AX() {}
+
+ // Evaluate sigma.
+ virtual double sigmaHat() {return sigmaTotPtr->sigmaAX();}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "A B -> A X single diffractive";}
+ virtual int code() const {return 104;}
+ virtual bool isResolved() const {return false;}
+ virtual bool isDiffB() const {return true;};
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for double diffractive scattering A B -> X X.
+
+class Sigma0AB2XX : public Sigma0Process {
+
+public:
+
+ // Constructor.
+ Sigma0AB2XX() {}
+
+ // Evaluate sigma.
+ virtual double sigmaHat() {return sigmaTotPtr->sigmaXX();}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "A B -> X X double diffractive";}
+ virtual int code() const {return 105;}
+ virtual bool isResolved() const {return false;}
+ virtual bool isDiffA() const {return true;};
+ virtual bool isDiffB() const {return true;};
+
+private:
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> g g.
+
+class Sigma2gg2gg : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2gg() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "g g -> g g";}
+ virtual int code() const {return 111;}
+ virtual string inFlux() const {return "gg";}
+
+private:
+
+ // Values stored for colour flow selection.
+ double sigTS, sigUS, sigTU, sigSum, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> q qbar (q = u, d, s, i.e. almost massless).
+
+class Sigma2gg2qqbar : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2qqbar() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "g g -> q qbar (uds)";}
+ virtual int code() const {return 112;}
+ virtual string inFlux() const {return "gg";}
+
+private:
+
+ // Number of quarks to be considered in massless approximation.
+ int nQuarkNew;
+
+ // Values stored for colour flow selection.
+ int idNew;
+ double mNew, m2New, sigTS, sigUS, sigSum, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q g -> q g (q = u, d, s, c, b).
+// Use massless approximation also for Q since no alternative.
+
+class Sigma2qg2qg : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qg2qg() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q g -> q g";}
+ virtual int code() const {return 113;}
+ virtual string inFlux() const {return "qg";}
+
+private:
+
+ // Values stored for colour flow selection.
+ double mNew, m2New, sigTS, sigTU, sigSum, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar' -> q qbar' or q q' -> q q'
+// (qbar qbar' -> qbar qbar'), q' may be same as q.
+
+class Sigma2qq2qq : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qq2qq() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q q(bar)' -> q q(bar)'";}
+ virtual int code() const {return 114;}
+ virtual string inFlux() const {return "qq";}
+
+ private:
+
+ // Values stored for colour flow selection.
+ double sigT, sigU, sigTU, sigST, sigSum;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> g g.
+
+class Sigma2qqbar2gg : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2gg() {}
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q qbar -> g g";}
+ virtual int code() const {return 115;}
+ virtual string inFlux() const {return "qqbarSame";}
+
+ private:
+
+ // Values stored for colour flow selection.
+ double sigTS, sigUS, sigSum, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> q' qbar'.
+
+class Sigma2qqbar2qqbarNew : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2qqbarNew() {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return "q qbar -> q' qbar' (uds)";}
+ virtual int code() const {return 116;}
+ virtual string inFlux() const {return "qqbarSame";}
+
+ private:
+
+ // Number of quarks to be considered in massless approximation.
+ int nQuarkNew;
+
+ // Values stored for colour flow selection.
+ int idNew;
+ double mNew, m2New, sigS, sigma;
+
+};
+
+//**************************************************************************
+
+// A derived class for g g -> Q Qbar (Q = c, b or t).
+
+class Sigma2gg2QQbar : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2gg2QQbar(int idIn, int codeIn) : idNew(idIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angles in top decay (else inactive).
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "gg";}
+ virtual int id3Mass() const {return idNew;}
+ virtual int id4Mass() const {return idNew;}
+
+ private:
+
+ // Values stored for process type and colour flow selection.
+ int idNew, codeSave;
+ string nameSave;
+ double sigTS, sigUS, sigSum, sigma, openFracPair;
+
+};
+
+//**************************************************************************
+
+// A derived class for q qbar -> Q Qbar (Q = c, b or t).
+
+class Sigma2qqbar2QQbar : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2QQbar(int idIn, int codeIn) : idNew(idIn), codeSave(codeIn) {}
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat() {return sigma;}
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Evaluate weight for W decay angles in top decay (else inactive).
+ virtual double weightDecay( Event& process, int iResBeg, int iResEnd);
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qqbarSame";}
+ virtual int id3Mass() const {return idNew;}
+ virtual int id4Mass() const {return idNew;}
+
+ private:
+
+ // Values stored for process type.
+ int idNew, codeSave;
+ string nameSave;
+ double sigma, openFracPair;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaQCD_H
--- /dev/null
+// SigmaSUSY.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for Supersymmetric process differential cross sections.
+// Contains classes derived from SigmaProcess via Sigma2Process.
+
+#ifndef Pythia8_SigmaSUSY_H
+#define Pythia8_SigmaSUSY_H
+
+#include "PythiaComplex.h"
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// A derived class for q qbar -> gaugino_i gaugino_j.
+
+class Sigma2qqbar2gauginogaugino : public Sigma2Process {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2gauginogaugino() { }
+
+ // Initialize process.
+ virtual void initProc();
+
+ // Calculate flavour-independent parts of cross section.
+ virtual void sigmaKin();
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+ // Select flavour, colour and anticolour.
+ virtual void setIdColAcol();
+
+ // Info on the subprocess.
+ virtual string name() const {return nameSave;}
+ virtual int code() const {return codeSave;}
+ virtual string inFlux() const {return "qq";}
+ virtual int id3Mass() const {return id3;}
+ virtual int id4Mass() const {return id4;}
+
+ protected:
+
+ // Values stored for later use.
+ int id3chi, id4chi, codeSave;
+ string nameSave;
+ double sigma0, ui, uj, ti, tj, sz, d;
+ complex propZ;
+
+ // Couplings.
+ // Shorthand for sin2thetaW, mZ, and GammaZ.
+ double sin2W, mZpole, wZpole;
+ // qqZ couplings.
+ double LqqZ[10], RqqZ[10];
+ // qsqchi_i couplings.
+ complex LsqXi[10][10], RsqXi[10][10];
+ complex LsqCi[10][10], RsqCi[10][10];
+ // qsqchi_j couplings.
+ complex LsqXj[10][10], RsqXj[10][10];
+ complex LsqCj[10][10], RsqCj[10][10];
+ // W/Z chi chi couplings
+ complex OL, OR, OLp, ORp, OLpp, ORpp;
+
+ // Code to say whether it is chi0chi0, chi+chi0, or chi+chi+
+ int nCharged;
+
+};
+
+class Sigma2qqbar2chi0chi0 : public Sigma2qqbar2gauginogaugino {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2chi0chi0(int id3chiIn, int id4chiIn, int codeIn) {
+
+ // Save ordering indices and process code
+ id3chi=id3chiIn;
+ id4chi=id4chiIn;
+ codeSave=codeIn;
+
+ // Construct id codes from ordering indices.
+ id3 = 1000022;
+ if (id3chi == 2) id3 = 1000023;
+ if (id3chi == 3) id3 = 1000025;
+ if (id3chi == 4) id3 = 1000035;
+ if (id3chi == 5) id3 = 1000045;
+ id4 = 1000022;
+ if (id4chi == 2) id4 = 1000023;
+ if (id4chi == 3) id4 = 1000025;
+ if (id4chi == 4) id4 = 1000035;
+ if (id4chi == 5) id4 = 1000045;
+
+ }
+
+};
+
+// A derived class for q qbar -> neutralino_i chargino_j.
+
+class Sigma2qqbar2chi0char : public Sigma2qqbar2gauginogaugino {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2chi0char(int id3chiIn, int id4chiIn, int codeIn) {
+
+ // Save ordering indices and process code
+ id3chi=id3chiIn;
+ id4chi=id4chiIn;
+ codeSave=codeIn;
+
+ // Construct id codes from ordering indices.
+ id3 = 1000022;
+ if (id3chi == 2) id3 = 1000023;
+ if (id3chi == 3) id3 = 1000025;
+ if (id3chi == 4) id3 = 1000035;
+ if (id3chi == 5) id3 = 1000045;
+ id4 = 1000024;
+ if (id4chi == 2) id4 = 1000037;
+
+ }
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+};
+
+// A derived class for q qbar -> chargino_i chargino_j.
+
+class Sigma2qqbar2charchar : public Sigma2qqbar2gauginogaugino {
+
+public:
+
+ // Constructor.
+ Sigma2qqbar2charchar(int id3chiIn, int id4chiIn, int codeIn) {
+
+ // Save ordering indices and process code
+ id3chi=id3chiIn;
+ id4chi=id4chiIn;
+ codeSave=codeIn;
+
+ // Construct id codes from ordering indices.
+ id3 = -1000024;
+ if (id3chi == 2) id3 = -1000037;
+ id4 = 1000024;
+ if (id4chi == 2) id4 = 1000037;
+
+ }
+
+ // Evaluate d(sigmaHat)/d(tHat).
+ virtual double sigmaHat();
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaSUSY_H
+
--- /dev/null
+// SigmaTotal.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the class for cross section parametrizations.
+// SigmaTotal: total and partial cross section in hadron-hadron collisions.
+
+#ifndef Pythia8_SigmaTotal_H
+#define Pythia8_SigmaTotal_H
+
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The SigmaTotal class contains parametrizations of total, elastic and
+// diffractive cross sections, and of the respective slope parameter.
+
+class SigmaTotal {
+
+public:
+
+ // Constructor.
+ SigmaTotal() : isCalc(false) {};
+
+ // Storee pointer to Info and initialize data members.
+ void init(Info* infoPtrIn);
+
+ // Calculate, or recalculate for new beams or new energy.
+ bool calc(int idA, int idB, double eCM);
+
+ // Confirm that initialization worked.
+ bool hasSigmaTot() const {return isCalc;}
+
+ // Read out total and partial cross sections.
+ double sigmaTot() const {return sigTot;}
+ double sigmaEl() const {return sigEl;}
+ double sigmaXB() const {return sigXB;}
+ double sigmaAX() const {return sigAX;}
+ double sigmaXX() const {return sigXX;}
+ double sigmaND() const {return sigND;}
+
+ // Read out slope b in exp(b*t) dependence.
+ double bSlopeEl() const {return bEl;}
+ double bSlopeXB(double sX) const { return 2.*bB + alP2 * log(s/sX) ;}
+ double bSlopeAX(double sX) const { return 2.*bA + alP2 * log(s/sX) ;}
+ double bSlopeXX(double sX1, double sX2) const {
+ return alP2 * log( exp(4.) + s * s0 / (sX1 * sX2) ) ;}
+
+ // Read out parameters of diffractive mass spectra.
+ double mMinXB() const {return mMinXBsave;}
+ double mMinAX() const {return mMinAXsave;}
+ double cRes() const {return CRES;}
+ double mResXB() const {return mResXBsave;}
+ double mResAX() const {return mResAXsave;}
+ double sProton() const {return SPROTON;}
+
+ // Read out parameters of trial t spectra.
+ double bMinSlopeXB() const { return max(2., 2. * bB);}
+ double bMinSlopeAX() const { return max(2., 2. * bA);}
+ double bMinSlopeXX() const { return alP2 * 4.;}
+
+private:
+
+ // Initialization data, normally only set once.
+ bool isCalc, setTotal, setElastic;
+ double sigTotOwn, sigElOwn, sigXBOwn, sigAXOwn, sigXXOwn,
+ bSlope, rho, lambda, tAbsMin, alphaEM0;
+
+ // Constants: could only be changed in the code itself.
+ static const int IHADATABLE[], IHADBTABLE[], ISDTABLE[], IDDTABLE[];
+ static const double MMIN, EPSILON, ETA, X[], Y[], BETA0[], BHAD[],
+ ALPHAPRIME, CONVERTEL, CONVERTSD, CONVERTDD, MMIN0,
+ CRES, MRES0, CSD[10][8], CDD[10][9], SPROTON;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Store values found by calc.
+ double sigTot, sigEl, sigXB, sigAX, sigXX, sigND, bEl, s, bA, bB,
+ alP2, s0, exp4, mMinXBsave, mMinAXsave, mResXBsave, mResAXsave;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SigmaTotal_H
--- /dev/null
+// SpaceShower.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the spacelike initial-state showers.
+// SpaceDipoleEnd: radiating dipole end in ISR.
+// SpaceSystem: info on one interaction (among multiple ones).
+// SpaceShower: handles the showering description.
+
+#ifndef Pythia8_SpaceShower_H
+#define Pythia8_SpaceShower_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Event.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+#include "StandardModel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Data on radiating dipole ends, only used inside SpaceSystem and SpaceShower.
+
+class SpaceDipoleEnd {
+
+public:
+
+ // Constructor.
+ SpaceDipoleEnd( int systemIn = 0, int sideIn = 0, int iRadiatorIn = 0,
+ int iRecoilerIn = 0, double pTmaxIn = 0., int colTypeIn = 0,
+ int chgTypeIn = 0, int MEtypeIn = 0) : system(systemIn), side(sideIn),
+ iRadiator(iRadiatorIn), iRecoiler(iRecoilerIn), pTmax(pTmaxIn),
+ colType(colTypeIn), chgType(chgTypeIn), MEtype(MEtypeIn), nBranch(0) { }
+
+ // Store values for trial emission.
+ void store( int idDaughterIn, int idMotherIn, int idSisterIn,
+ double x1In, double x2In, double m2DipIn, double pT2In, double zIn,
+ double Q2In, double mSisterIn, double m2SisterIn, double pT2corrIn,
+ double phiIn) {idDaughter = idDaughterIn; idMother = idMotherIn;
+ idSister = idSisterIn; x1 = x1In; x2 = x2In; m2Dip = m2DipIn;
+ pT2 = pT2In; z = zIn; Q2 = Q2In; mSister = mSisterIn;
+ m2Sister = m2SisterIn; pT2corr = pT2corrIn; phi = phiIn;}
+
+ // Basic properties related to evolution and matrix element corrections.
+ int system, side, iRadiator, iRecoiler;
+ double pTmax;
+ int colType, chgType, MEtype;
+
+ // Properties specific to current trial emission.
+ int idDaughter, idMother, idSister, nBranch;
+ double x1, x2, m2Dip, pT2, z, Q2, mSister, m2Sister, pT2corr, phi,
+ pT2Old, zOld;
+
+} ;
+
+//**************************************************************************
+
+// The SpaceShower class does spacelike showers.
+
+class SpaceShower {
+
+public:
+
+ // Constructor.
+ SpaceShower() {}
+
+ // Destructor.
+ virtual ~SpaceShower() {}
+
+ // Initialize pointer to Info for error messages.
+ // (Separated from rest of init since not virtual.)
+ void initPtr(Info* infoPtrIn) {infoPtr = infoPtrIn;}
+
+ // Initialize generation. Possibility to force re-initialization by hand.
+ virtual void init(BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn);
+
+ // Find whether to limit maximum scale of emissions.
+ virtual bool limitPTmax( Event& event, double Q2Fac = 0.,
+ double Q2Ren = 0.);
+
+ // Potential enhancement factor of pTmax scale for hardest emission.
+ virtual double enhancePTmax() {return pTmaxFudge;}
+
+ // Prepare system for evolution; identify ME.
+ virtual void prepare( int iSys, Event& event, bool limitPTmaxIn = true);
+
+ // Update dipole list after each FSR emission. Currently superfluous.
+ // Usage: update( iSys, event).
+ virtual void update( int , Event& ) {}
+
+ // Select next pT in downwards evolution.
+ virtual double pTnext( Event& event, double pTbegAll, double pTendAll,
+ int nRadIn = -1);
+
+ // ME corrections and kinematics that may give failure,
+ virtual bool branch( Event& event);
+
+ // Tell which system was the last processed one.
+ int system() const {return iSysSel;}
+
+ // Print dipole list; for debug mainly.
+ virtual void list(ostream& os = cout);
+
+protected:
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to the two incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Store index of last processed system.
+ int iSysSel;
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int MAXLOOPTINYPDF;
+ static const double CTHRESHOLD, BTHRESHOLD, EVALPDFSTEP, TINYPDF,
+ TINYKERNELPDF, TINYPT2, HEAVYPT2EVOL, HEAVYXEVOL, EXTRASPACEQ,
+ LAMBDA3MARGIN, LEPTONXMIN, LEPTONXMAX, LEPTONPT2MIN, LEPTONFUDGE;
+
+ // Initialization data, normally only set once.
+ bool doQCDshower, doQEDshowerByQ, doQEDshowerByL, useSamePTasMI,
+ doMEcorrections, doPhiPolAsym, doRapidityOrder;
+ int pTmaxMatch, pTdampMatch, alphaSorder, alphaEMorder, nQuarkIn;
+ double pTmaxFudge, pTdampFudge, mc, mb, m2c, m2b, alphaSvalue, alphaS2pi,
+ Lambda3flav, Lambda4flav, Lambda5flav, Lambda3flav2, Lambda4flav2,
+ Lambda5flav2, pT0Ref, ecmRef, ecmPow, pTmin, sCM, eCM, pT0,
+ pTminChgQ, pTminChgL, pT20, pT2min, pT2minChgQ, pT2minChgL;
+
+ // alphaStrong and alphaEM calculations.
+ AlphaStrong alphaS;
+ AlphaEM alphaEM;
+
+ // Some current values.
+ bool dopTdamp;
+ int iNow, iRec, idDaughter, nRad;
+ double xDaughter, x1Now, x2Now, m2Dip, pT2damp;
+
+ // All dipole ends
+ vector<SpaceDipoleEnd> dipEnd;
+
+ // Pointers to the current and hardest (so far) dipole ends.
+ int iDipNow, iSysNow;
+ SpaceDipoleEnd* dipEndNow;
+ int iDipSel;
+ SpaceDipoleEnd* dipEndSel;
+
+ // Evolve a QCD dipole end.
+ void pT2nextQCD( double pT2begDip, double pT2endDip);
+
+ // Evolve a QCD dipole end near heavy quark threshold region.
+ void pT2nearQCDthreshold( BeamParticle& beam, double m2Massive,
+ double m2Threshold, double zMinAbs, double zMaxMassive);
+
+ // Evolve a QED dipole end.
+ void pT2nextQED( double pT2begDip, double pT2endDip);
+
+ // Find class of ME correction.
+ int findMEtype( int iSys, Event& event);
+
+ // Provide maximum of expected ME weight; for preweighting of evolution.
+ double calcMEmax( int MEtype, int idMother, int idDaughterIn);
+
+ // Provide actual ME weight for current branching.
+ double calcMEcorr(int MEtype, int idMother, int idDaughterIn, double M2,
+ double z, double Q2);
+
+ // Find coefficient of azimuthal asymmetry from gluon polarization.
+ // void findAsymPol(DipoleEnd*);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_SpaceShower_H
--- /dev/null
+// StandardModel.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file gives access to some Standard Model parameters.
+// AlphaStrong: fix or first- or second-order running alpha_strong.
+
+#ifndef Pythia8_StandardModel_H
+#define Pythia8_StandardModel_H
+
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The AlphaStrong class calculates the alpha_strong value at an arbitrary
+// scale, given the value at m_Z, to zeroth, first or second order.
+
+class AlphaStrong {
+
+public:
+
+ // Constructors.
+ AlphaStrong() : isInit(false) {}
+ AlphaStrong(double valueIn, int orderIn = 1) {
+ init( valueIn, orderIn) ;}
+
+ // Initialization for given value at M_Z and given order.
+ void init(double valueIn = 0.12, int orderIn = 1);
+
+ // alpha_S value and Lambda values.
+ double alphaS(double scale2);
+ double alphaS1Ord(double scale2);
+ double alphaS2OrdCorr(double scale2);
+ double Lambda3() const { return Lambda3Save; }
+ double Lambda4() const { return Lambda4Save; }
+ double Lambda5() const { return Lambda5Save; }
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NITER;
+ static const double SAFETYMARGIN1, SAFETYMARGIN2;
+
+ // Data members.
+ bool isInit, lastCallToFull;
+ int order;
+ double valueRef, valueNow, scale2Now, scale2Min, Lambda3Save,
+ Lambda4Save, Lambda5Save, Lambda3Save2, Lambda4Save2,
+ Lambda5Save2, mc, mb, mZ, mc2, mb2;
+
+};
+
+//**************************************************************************
+
+// The AlphaEM class calculates the alpha_electromagnetic value at an
+// arbitrary scale, given the value at 0 and m_Z, to zeroth or first order.
+
+class AlphaEM {
+
+public:
+
+ // Constructors.
+ AlphaEM(int orderIn = 1) {init(orderIn);}
+
+ // First-order initialization for given value at M_Z.
+ static void initStatic();
+
+ // Initialization for a given order.
+ void init(int orderIn = 1) {order = orderIn;}
+
+ // alpha_EM value.
+ double alphaEM(double scale2);
+
+private:
+
+ // Static data members, mostly for first-order matching.
+ static double alpEM0, alpEMmZ, mZ2, Q2step[5], bRun[5], alpEMstep[5];
+
+ // Data members.
+ int order;
+
+};
+
+//**************************************************************************
+
+// The CoupEW class stores and returns electroweak couplings.
+
+class CoupEW {
+
+public:
+
+ // Constructor.
+ CoupEW() {}
+
+ // Initialize, normally from Pythia::init().
+ static void initStatic();
+
+ // Return electroweak mixing angle.
+ static double sin2thetaW() {return s2tW;}
+ static double cos2thetaW() {return c2tW;}
+ static double sin2thetaWbar() {return s2tWbar;}
+
+ // Return electroweak couplings of quarks and leptons.
+ static double ef(int idAbs) {return efSave[idAbs];}
+ static double vf(int idAbs) {return vfSave[idAbs];}
+ static double af(int idAbs) {return afSave[idAbs];}
+ static double t3f(int idAbs) {return 0.5*afSave[idAbs];}
+ static double lf(int idAbs) {return lfSave[idAbs];}
+ static double rf(int idAbs) {return rfSave[idAbs];}
+
+ // Return some squared couplings and other combinations.
+ static double ef2(int idAbs) {return ef2Save[idAbs];}
+ static double vf2(int idAbs) {return vf2Save[idAbs];}
+ static double af2(int idAbs) {return af2Save[idAbs];}
+ static double efvf(int idAbs) {return efvfSave[idAbs];}
+ static double vf2af2(int idAbs) {return vf2af2Save[idAbs];}
+
+private:
+
+ // Store couplings.
+ static double s2tW, c2tW, s2tWbar, efSave[20], vfSave[20], afSave[20],
+ lfSave[20], rfSave[20], ef2Save[20], vf2Save[20],
+ af2Save[20], efvfSave[20], vf2af2Save[20];
+
+};
+
+//**************************************************************************
+
+// The VCKM class stores and returns Cabibbo-Kobayashi-Maskawa
+
+class VCKM {
+
+public:
+
+ // Constructor.
+ VCKM() {}
+
+ // Initialize, normally from Pythia::init().
+ static void initStatic();
+
+ // Return value or square: first index 1/2/3/4 = u/c/t/t',
+ // second 1/2/3/4 = d/s/b/b'.
+ static double Vgen(int genU, int genD) {return Vsave[genU][genD];}
+ static double V2gen(int genU, int genD) {return V2save[genU][genD];}
+
+ // Return value or square for incoming flavours (sign irrelevant).
+ static double Vid(int id1, int id2);
+ static double V2id(int id1, int id2);
+
+ // Return sum of squares for given inflavour, or random outflavour.
+ static double V2sum(int id) {return V2out[abs(id)];}
+ static int V2pick(int id);
+
+private:
+
+ // Store VCKM matrix (index 0 not used) and sum of squares.
+ static double Vsave[5][5], V2save[5][5], V2out[20];
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_StandardModel_H
--- /dev/null
+// StringFragmentation.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// This file contains the classes for string fragmentation.
+// StringEnd: keeps track of the fragmentation step.
+// StringFragmentation: is the top-level class.
+
+#ifndef Pythia8_StringFragmentation_H
+#define Pythia8_StringFragmentation_H
+
+#include "Basics.h"
+#include "Event.h"
+#include "Info.h"
+#include "FragmentationFlavZpT.h"
+#include "FragmentationSystems.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The StringEnd class contains the information related to
+// one of the current endpoints of the string system.
+// Only to be used inside StringFragmentation, so no private members.
+
+class StringEnd {
+
+public:
+
+ // Constructor.
+ StringEnd() {}
+
+ // Save pointers.
+ void init(StringFlav* flavSelPtrIn, StringPT* pTSelPtrIn,
+ StringZ* zSelPtrIn) {flavSelPtr = flavSelPtrIn;
+ pTSelPtr = pTSelPtrIn; zSelPtr = zSelPtrIn;}
+
+ // Set up initial endpoint values from input.
+ void setUp(bool fromPosIn, int iEndIn, int idOldIn, int iMaxIn,
+ double pxIn, double pyIn, double GammaIn, double xPosIn, double xNegIn);
+
+ // Fragment off one hadron from the string system, in flavour and pT.
+ void newHadron();
+
+ // Fragment off one hadron from the string system, in momentum space,
+ // by taking steps either from positive or from negative end.
+ Vec4 kinematicsHadron(StringSystem& system);
+
+ // Update string end information after a hadron has been removed.
+ void update();
+
+ // Constants: could only be changed in the code itself.
+ static const double TINY, PT2SAME;
+
+ // Pointers to classes for flavour, pT and z generation.
+ StringFlav* flavSelPtr;
+ StringPT* pTSelPtr;
+ StringZ* zSelPtr;
+
+ // Data members.
+ bool fromPos;
+ int iEnd, iMax, idHad, iPosOld, iNegOld, iPosNew, iNegNew;
+ double pxOld, pyOld, pxNew, pyNew, pxHad, pyHad, mHad, mT2Had, zHad,
+ GammaOld, GammaNew, xPosOld, xPosNew, xPosHad, xNegOld, xNegNew,
+ xNegHad;
+ FlavContainer flavOld, flavNew;
+ Vec4 pHad, pSoFar;
+
+};
+
+//**************************************************************************
+
+// The StringFragmentation class contains the top-level routines
+// to fragment a colour singlet partonic system.
+
+class StringFragmentation {
+
+public:
+
+ // Constructor.
+ StringFragmentation() {}
+
+ // Initialize and save pointers.
+ void init(Info* infoPtrIn, StringFlav* flavSelPtrIn,
+ StringPT* pTSelPtrIn, StringZ* zSelPtrIn);
+
+ // Do the fragmentation: driver routine.
+ bool fragment( int iSub, ColConfig& colConfig, Event& event);
+
+ // Find the boost matrix to the rest frame of a junction.
+ RotBstMatrix junctionRestFrame(Vec4& p0, Vec4& p1, Vec4& p2);
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const int NTRYFLAV, NTRYJOIN, NSTOPMASS, NTRYJNREST,
+ NTRYJNMATCH, NTRYJRFEQ;
+ static const double FACSTOPMASS, CLOSEDM2MAX, CLOSEDM2FRAC, EXPMAX,
+ MATCHPOSNEG, EJNWEIGHTMAX, CONVJNREST, M2MAXJRF,
+ CONVJRFEQ;
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to classes for flavour, pT and z generation.
+ StringFlav* flavSelPtr;
+ StringPT* pTSelPtr;
+ StringZ* zSelPtr;
+
+ // Initialization data, read from Settings.
+ double stopMass, stopNewFlav, stopSmear, eNormJunction,
+ eBothLeftJunction, eMaxLeftJunction, eMinLeftJunction, bLund;
+
+ // Data members.
+ bool hasJunction, isClosed;
+ int iPos, iNeg;
+ double w2Rem, stopMassNow;
+ Vec4 pSum, pRem, pJunctionHadrons;
+
+ // List of partons in string system.
+ vector<int> iParton;
+
+ // Temporary event record for the produced particles.
+ Event hadrons;
+
+ // Information on the system of string regions.
+ StringSystem system, systemMin, systemMid;
+
+ // Information on the two current endpoints of the fragmenting system.
+ StringEnd posEnd, negEnd;
+
+ // Find region where to put first string break for closed gluon loop.
+ vector<int> findFirstRegion(vector<int>& iPartonIn, Event& event);
+
+ // Set flavours and momentum position for initial string endpoints.
+ void setStartEnds(int idPos, int idNeg, StringSystem systemNow);
+
+ // Check remaining energy-momentum whether it is OK to continue.
+ bool energyUsedUp(bool fromPos);
+
+ // Produce the final two partons to complete the system.
+ bool finalTwo(bool fromPos);
+
+ // Construct a special joining region for the final two hadrons.
+ StringRegion finalRegion();
+
+ // Store the hadrons in the normal event record, ordered from one end.
+ void store(Event& event);
+
+ // Fragment off two of the string legs in to a junction.
+ bool fragmentToJunction(Event& event);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_StringFragmentation_H
--- /dev/null
+// SusyLesHouches.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Peter Skands, Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+#ifndef SLHA_H
+#define SLHA_H
+
+// Stdlib header files for string and character manipulation.
+#include <string>
+#include <cctype>
+// Stdlib header files for containers.
+#include <vector>
+#include <map>
+// Stdlib header files for input/output.
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+// Stdlib header files for mathematics.
+#include <cmath>
+
+// Stdlib namespace
+using namespace std;
+
+class SusyLesHouches {
+
+public:
+
+ //Constructor, with and without filename.
+ SusyLesHouches(int verboseIn=1) : verbose(verboseIn),
+ headerPrinted(false), footerPrinted(false),
+ slhaRead(false), lhefRead(false), lhefSlha(false) {};
+ SusyLesHouches(string filename, int verboseIn=1) : verbose(verboseIn),
+ headerPrinted(false), footerPrinted(false),
+ slhaRead(true), lhefRead(false), lhefSlha(false) {readFile(filename);};
+
+ //***************************** SLHA FILE I/O *****************************//
+ int readFile(string slhaFile="slha.spc"); // read in SLHA file
+ //int writeFile(string filename): write SLHA file on filename
+ int checkSpectrum();
+
+ //Output utilities
+ void printHeader(); // print Header
+ void printFooter(); // print Footer
+ void printSpectrum(); // print Spectrum
+
+ // Class for SLHA data entry
+ class Entry {
+
+ public:
+ //Constructor.
+ Entry() : isIntP(false), isDoubleP(false),
+ isStringP(false), n(0), d(0.0), s(""), commentP("") {}
+
+ // Generic functions to inquire whether an int, double, or string
+ bool isInt(){return isIntP;}
+ bool isDouble(){return isDoubleP;}
+ bool isString(){return isStringP;}
+
+ // = Overloading: Set entry to int, double, or string
+ Entry& operator=(double& val) {
+ d=val;isIntP=false;isDoubleP=true;isStringP=false;
+ return *this;
+ };
+ Entry& operator=(int& val) {
+ n=val;isIntP=true;isDoubleP=false;isStringP=false;
+ return *this;
+ };
+ Entry& operator=(string& val) {
+ s=val;isIntP=false;isDoubleP=false;isStringP=true;
+ return *this;
+ };
+
+ // Set and Get comment
+ void setComment(string comment) {commentP=comment;}
+ void getComment(string comment) {comment=commentP;}
+
+ // Generic functions to get value
+ bool get(int& val) {val=n; return isIntP;}
+ bool get(double& val) {val=d; return isDoubleP;}
+ bool get(string& val) {val=s; return isStringP;}
+
+ private:
+ bool isIntP, isDoubleP, isStringP;
+ int n;
+ double d;
+ string s;
+ string commentP;
+
+ };
+
+ //***************************** SLHA CLASSES *****************************//
+
+
+ //class block: the generic SLHA block (see below for matrices)
+ //Explicit typing required, e.g. block<double> minpar;
+ template <class T> class block {
+
+ public:
+
+ //Constructor.
+ block<T>() : idnow(0) { } ;
+
+ //Does block exist?
+ bool exists() { return entry.size() == 0 ? false : true ; };
+ //Clear block
+ void clear() { entry.clear(); };
+
+ //set: set block entry values.
+ //Possible return values from set:
+ // 0: normal return. Entry did not previously exist and has been created.
+ // 1: normal return. Entry did previously exist and has been overwritten.
+ //-1: failure.
+ int set(int iIn,T valIn) {
+ int alreadyexisting=exists(iIn)?1:0;
+ entry[iIn]=valIn;
+ return alreadyexisting;
+ };
+ // Read index and value from SLHA data line
+ int set(istringstream& linestream) {
+ linestream >> i >> val;
+ return linestream ? set(i,val) : -1;
+ };
+ // With i already given, read value from remaining SLHA data line
+ int set(int iIn,istringstream& linestream) {
+ linestream >> val;
+ return linestream ? set(iIn,val) : -1;
+ };
+ // Shorthand for entry[0]. Used e.g. for block ALPHA.
+ void set(T valIn) { entry[0]=valIn; };
+
+ // Does entry i already exist in this block?
+ bool exists(int iIn) {return entry.find(iIn) != entry.end()
+ ? true : false;};
+
+ // Indexing with (). Output only.
+ T operator()(int iIn=0) {
+ if (exists(iIn)) {return entry[iIn];} else {T dummy(0); return dummy;};
+ };
+
+ // Size of map
+ int size() {return entry.size();};
+
+ // First and next key code
+ int first() { idnow = entry.begin()->first; return idnow; };
+ int next() {
+ typename map<int,T>::iterator itnow;
+ itnow = ++entry.find(idnow);
+ if ( itnow == entry.end() ) itnow=entry.begin();
+ return idnow = itnow->first;
+ };
+
+ // Simple print utility
+ void print() {
+ bool finished=false;
+ int ibegin=first();
+ i=ibegin;
+ while (!finished) {
+ cout << " "<< i << " " << entry[i] <<endl;
+ i=next();
+ if (i == ibegin) finished=true;
+ };
+ };
+
+ // Special for DRbar running blocks.
+ void setq(double qIn) { qDRbar=qIn; }
+ double q() { return qDRbar; }
+
+ private:
+ map<int,T> entry;
+ int idnow;
+ double qDRbar;
+ //Auxiliary vars
+ int i;
+ T val;
+ };
+
+ // class matrixblock: the generic SLHA matrix
+ // Explicit sizing required, e.g. matrixblock<4> nmix;
+ template <int size> class matrixblock {
+ public:
+ //Constructor. Set uninitialized and explicitly zero.
+ matrixblock<size>() : i(0), j(0), val(0) {
+ initialized=false;
+ for (i=1;i<=size;i++) {
+ for (j=1;j<=size;j++) {
+ entry[i][j]=0.0;
+ };
+ };
+ };
+
+ // Assignment
+ matrixblock& operator=(const matrixblock& m) {
+ if (this != &m) {
+ for (i=0;i<size;i++) for (j=0;j<=size;j++) entry[i][j] = m(i,j);
+ qDRbar = m.qDRbar;
+ initialized = m.initialized;
+ }
+ return *this; };
+
+ // Does this matrix contain any entries?
+ bool exists() { return initialized; };
+ // Clear initialized flag
+ void clear() { initialized=false; };
+
+ // Set matrix entry
+ int set(int iIn,int jIn, double valIn) {
+ if (iIn>0 && jIn>0 && iIn<=size && jIn<=size) {
+ entry[iIn][jIn]=valIn;
+ initialized=true;
+ return 0;
+ } else {
+ return -1;
+ };
+ };
+
+ // Set entry from linestream (used during file read)
+ int set(istringstream& linestream) {
+ linestream >> i >> j >> val;
+ return linestream ? set(i,j,val) : -1;
+ };
+
+ // () Overloading: Get entry
+ double operator()(int iIn, int jIn) const {
+ return (iIn <= size && jIn <= size && iIn > 0 && jIn > 0) ?
+ entry[iIn][jIn] : 0.0;
+ };
+
+ // Set and get scale for DRbar running blocks.
+ void setq(double qIn) { qDRbar=qIn; }
+ double q() { return qDRbar; }
+
+ // Simple print utility, to be elaborated on.
+ void print() {
+ for (i=1;i<=size;i++) {
+ cout << " "<<i << " " ;
+ for (j=1;j<=size;j++) cout << entry[i][j] << " ";
+ cout << endl;
+ };
+ };
+
+ private:
+ bool initialized;
+ double entry[size+1][size+1];
+ double qDRbar;
+ //Auxiliary vars
+ int i,j;
+ double val;
+ };
+
+ // class tensorblock: the generic SLHA tensor
+ // Explicit sizing required, e.g. tensorblock<3> rvlam;
+ template <int size> class tensor3block {
+ public:
+ //Constructor. Set uninitialized and explicitly zero.
+ tensor3block<size>() {
+ initialized=false;
+ for (i=1;i<=size;i++) {
+ for (j=1;j<=size;j++) {
+ for (k=1;k<=size;k++) {
+ entry[i][j][k]=0.0;
+ };
+ };
+ };
+ };
+
+ // Assignment
+ tensor3block& operator=(const tensor3block& m) {
+ if (this != &m) {
+ for (i=0;i<size;i++) for (j=0;j<=size;j++) for (k=0;k<=size;k++)
+ entry[i][j][k] = m(i,j,k);
+ qDRbar = m.qDRbar;
+ initialized = m.initialized;
+ }
+ return *this; };
+
+ // Does this matrix contain any entries?
+ bool exists() { return initialized; };
+ // Clear initialized flag
+ void clear() { initialized=false; };
+
+ // Set matrix entry
+ int set(int iIn,int jIn, int kIn, double valIn) {
+ if (iIn>0 && jIn>0 && kIn>0 && iIn<=size && jIn<=size && kIn<=size) {
+ entry[iIn][jIn][kIn]=valIn;
+ initialized=true;
+ return 0;
+ } else {
+ return -1;
+ };
+ };
+
+ // Set entry from linestream (used during file read)
+ int set(istringstream& linestream) {
+ linestream >> i >> j >> k >> val;
+ return linestream ? set(i,j,k,val) : -1;
+ };
+
+ // () Overloading: Get entry
+ double operator()(int iIn, int jIn, int kIn) const {
+ return (iIn <= size && jIn <= size && kIn <= size && iIn > 0
+ && jIn > 0 && kIn > 0) ? entry[iIn][jIn][kIn] : 0.0;
+ };
+
+ // Set and get scale for DRbar running blocks.
+ void setq(double qIn) { qDRbar=qIn; }
+ double q() { return qDRbar; }
+
+ // Simple print utility, to be elaborated on.
+ void print() {
+ for (i=1;i<=size;i++) {
+ for (j=1;j<=size;j++) {
+ cout << " "<<i << " "<<j << " " ;
+ for (k=1;k<=size;k++) {
+ cout << entry[i][j][k] << " ";
+ cout << endl;
+ };
+ };
+ };
+ };
+
+ private:
+ bool initialized;
+ double entry[size+1][size+1][size+1];
+ double qDRbar;
+ //Auxiliary vars
+ int i,j,k;
+ double val;
+ };
+
+ //*************************** THE SLHA1 BLOCKS ***************************//
+ //blocks for model definition:
+ block<int> modsel;
+ block<int> modsel21;
+ block<double> modsel12;
+ block<double> minpar;
+ block<double> extpar;
+ block<double> sminputs;
+ //blocks for RGE program specific output
+ block<string> spinfo;
+ block<string> spinfo3;
+ block<string> spinfo4;
+ //blocks for DCY program specific output
+ block<string> dcinfo;
+ block<string> dcinfo3;
+ block<string> dcinfo4;
+ //blocks for mass and coupling spectrum
+ block<double> mass;
+ matrixblock<4> nmix;
+ matrixblock<2> umix;
+ matrixblock<2> vmix;
+ matrixblock<2> stopmix;
+ matrixblock<2> sbotmix;
+ matrixblock<2> staumix;
+ block<double> alpha;
+ block<double> hmix;
+ block<double> gauge;
+ block<double> msoft;
+ matrixblock<3> au;
+ matrixblock<3> ad;
+ matrixblock<3> ae;
+ matrixblock<3> yu;
+ matrixblock<3> yd;
+ matrixblock<3> ye;
+
+ //*************************** THE SLHA2 BLOCKS ***************************//
+ //Additions to SLHA1
+ block<double> qextpar;
+
+ //FLV Input
+ block<double> vckmin; // The input CKM Wolfenstein parms.
+ block<double> upmnsin; // The input PMNS PDG parms.
+ matrixblock<3> msq2in; // The input upper off-diagonal msq2
+ matrixblock<3> msu2in; // The input upper off-diagonal msu2
+ matrixblock<3> msd2in; // The input upper off-diagonal msd2
+ matrixblock<3> msl2in; // The input upper off-diagonal msl2
+ matrixblock<3> mse2in; // The input upper off-diagonal mse2
+ matrixblock<3> tuin; // The input upper off-diagonal TU
+ matrixblock<3> tdin; // The input upper off-diagonal TD
+ matrixblock<3> tein; // The input upper off-diagonal TE
+ //FLV Output
+ matrixblock<3> vckm; // The output DRbar running Re{VCKM} at Q
+ matrixblock<3> upmns; // The output DRbar running Re{UPMNS} at Q
+ matrixblock<3> msq2; // The output DRbar running msq2 at Q
+ matrixblock<3> msu2; // The output DRbar running msu2 at Q
+ matrixblock<3> msd2; // The output DRbar running msd2 at Q
+ matrixblock<3> msl2; // The output DRbar running msl2 at Q
+ matrixblock<3> mse2; // The output DRbar running mse2 at Q
+ matrixblock<3> tu; // The output DRbar running TU at Q
+ matrixblock<3> td; // The output DRbar running TD at Q
+ matrixblock<3> te; // The output DRbar running TE at Q
+ matrixblock<6> usqmix; // The Re{} up squark mixing matrix
+ matrixblock<6> dsqmix; // The Re{} down squark mixing matrix
+ matrixblock<6> selmix; // The Re{} selectron mixing matrix
+ matrixblock<3> snumix; // The Re{} sneutrino mixing matrix
+ matrixblock<3> snsmix; // The scalar sneutrino mixing matrix
+ matrixblock<3> snamix; // The pseudoscalar neutrino mixing matrix
+
+ //RPV Input
+ tensor3block<3> rvlamllein; // The input LNV lambda couplings
+ tensor3block<3> rvlamlqdin; // The input LNV lambda' couplings
+ tensor3block<3> rvlamuddin; // The input BNV lambda'' couplings
+ tensor3block<3> rvtllein; // The input LNV T couplings
+ tensor3block<3> rvtlqdin; // The input LNV T' couplings
+ tensor3block<3> rvtuddin; // The input BNV T'' couplings
+ block<double> rvkappain; // The input LNV kappa couplings
+ block<double> rvdin; // The input LNV D terms
+ block<double> rvm2lh1in; // The input LNV m2LH1 couplings
+ block<double> rvsnvevin; // The input LNV sneutrino vevs
+ //RPV Output
+ tensor3block<3> rvlamlle; // The output LNV lambda couplings
+ tensor3block<3> rvlamlqd; // The output LNV lambda' couplings
+ tensor3block<3> rvlamudd; // The output BNV lambda'' couplings
+ tensor3block<3> rvtlle; // The output LNV T couplings
+ tensor3block<3> rvtlqd; // The output LNV T' couplings
+ tensor3block<3> rvtudd; // The output BNV T'' couplings
+ block<double> rvkappa; // The output LNV kappa couplings
+ block<double> rvd; // The output LNV D terms
+ block<double> rvm2lh1; // The output LNV m2LH1 couplings
+ block<double> rvsnvev; // The output LNV sneutrino vevs
+ matrixblock<7> rvnmix; // The RPV neutralino mixing matrix
+ matrixblock<5> rvumix; // The RPV chargino L mixing matrix
+ matrixblock<5> rvvmix; // The RPV chargino R mixing matrix
+ matrixblock<5> rvhmix; // The RPV neutral scalar mixing matrix
+ matrixblock<5> rvamix; // The RPV neutral pseudoscalar mixing matrix
+ matrixblock<7> rvlmix; // The RPV charged fermion mixing matrix
+
+ //CPV Input
+ block<double> imminpar;
+ block<double> imextpar;
+ //CPV Output
+ matrixblock<4> cvhmix; // The CPV Higgs mixing matrix
+ matrixblock<4> imcvhmix; // Optional: imaginary components
+ matrixblock<3> imau,imad,imae; // Im{} of AU, AD, AE
+
+ //CPV + FLV Input
+ matrixblock<3> immsq2in; // The Im{} input upper off-diagonal msq2
+ matrixblock<3> immsu2in; // The Im{} input upper off-diagonal msu2
+ matrixblock<3> immsd2in; // The Im{} input upper off-diagonal msd2
+ matrixblock<3> immsl2in; // The Im{} input upper off-diagonal msl2
+ matrixblock<3> immse2in; // The Im{} input upper off-diagonal mse2
+ matrixblock<3> imtuin,imtdin,imtein; // The Im{} input upper off-diagonal T
+ //CPV + FLV Output
+ matrixblock<3> imvckm; // The output DRbar running Im{VCKM} at Q
+ matrixblock<3> imupmns; // The output DRbar running Im{UPMNS} at Q
+ matrixblock<3> immsq2; // The output DRbar running msq2 at Q
+ matrixblock<3> immsu2; // The output DRbar running msu2 at Q
+ matrixblock<3> immsd2; // The output DRbar running msd2 at Q
+ matrixblock<3> immsl2; // The output DRbar running msl2 at Q
+ matrixblock<3> immse2; // The output DRbar running mse2 at Q
+ matrixblock<3> imtu,imtd,imte; // Im{} of TU, TD, TE
+ matrixblock<6> imusqmix;// The Im{} up squark mixing matrix
+ matrixblock<6> imdsqmix; // The Im{} down squark mixing matrix
+ matrixblock<6> imselmix; // The Im{} selectron mixing matrix
+ matrixblock<3> imsnumix; // The Im{} sneutrino mixing matrix
+ matrixblock<4> imnmix; // The Im{} neutralino mixing matrix
+ matrixblock<4> imumix; // The Im{} chargino L mixing matrix
+ matrixblock<4> imvmix; // The Im{} chargino R mixing matrix
+
+ //NMSSM Input
+ // All input is in EXTPAR
+ //NMSSM Output
+ block<double> nmssmrun; // The block of NMSSM running parameters
+ matrixblock<3> nmhmix; // The NMSSM scalar Higgs mixing
+ matrixblock<3> nmamix; // The NMSSM pseudoscalar Higgs mixing
+ matrixblock<5> nmnmix; // The NMSSM neutralino mixing
+ matrixblock<5> imnmnmix; // Im{} (for future use)
+
+ //*************************** SET BLOCK VALUE ****************************//
+ template <class T> int set(string,T);
+ template <class T> int set(string,int,T);
+ template <class T> int set(string,int,int,T);
+ template <class T> int set(string,int,int,int,T);
+
+ //***************************** SLHA PRIVATE *****************************//
+private:
+ //SLHA I/O
+ string spectrumFile;
+ void message(int, string,string ,int line=0);
+ int verbose;
+ bool headerPrinted, footerPrinted;
+ bool slhaRead, lhefRead, lhefSlha;
+
+};
+
+#endif
+
+
--- /dev/null
+// TimeShower.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file for the timelike final-state showers.
+// TimeDipoleEnd: data on a radiating dipole end.
+// TimeShower: handles the showering description.
+
+#ifndef Pythia8_TimeShower_H
+#define Pythia8_TimeShower_H
+
+#include "Basics.h"
+#include "BeamParticle.h"
+#include "Event.h"
+#include "Info.h"
+#include "ParticleData.h"
+#include "PythiaStdlib.h"
+#include "Settings.h"
+#include "StandardModel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Data on radiating dipole ends; only used inside TimeShower class.
+
+class TimeDipoleEnd {
+
+public:
+
+ // Constructors.
+ TimeDipoleEnd() : iRadiator(-1), iRecoiler(-1), pTmax(0.), colType(0),
+ chgType(0), gamType(0), isrType(0), system(0), MEtype(0),
+ iMEpartner(-1), isOctetOnium(false), MEmix(0.), MEorder(true),
+ MEsplit(true), MEgluinoRec(false) { }
+ TimeDipoleEnd(int iRadiatorIn, int iRecoilerIn, double pTmaxIn = 0.,
+ int colIn = 0, int chgIn = 0, int gamIn = 0, int isrIn = 0,
+ int systemIn = 0, int MEtypeIn = 0, int iMEpartnerIn = -1,
+ bool isOctetOniumIn = false, double MEmixIn = 0., bool MEorderIn = true,
+ bool MEsplitIn = true, bool MEgluinoRecIn = false) :
+ iRadiator(iRadiatorIn), iRecoiler(iRecoilerIn), pTmax(pTmaxIn),
+ colType(colIn), chgType(chgIn), gamType(gamIn), isrType(isrIn),
+ system(systemIn), MEtype(MEtypeIn), iMEpartner(iMEpartnerIn),
+ isOctetOnium(isOctetOniumIn), MEmix(MEmixIn), MEorder (MEorderIn),
+ MEsplit(MEsplitIn), MEgluinoRec(MEgluinoRecIn) { }
+
+ // Basic properties related to dipole and matrix element corrections.
+ int iRadiator, iRecoiler;
+ double pTmax;
+ int colType, chgType, gamType, isrType, system, MEtype, iMEpartner;
+ bool isOctetOnium;
+ double MEmix;
+ bool MEorder, MEsplit, MEgluinoRec;
+
+ // Properties specific to current trial emission.
+ int flavour, iAunt;
+ double mRad, m2Rad, mRec, m2Rec, mDip, m2Dip, m2DipCorr,
+ pT2, m2, z, mFlavour, asymPol;
+
+} ;
+
+//**************************************************************************
+
+// The TimeShower class does timelike showers.
+
+class TimeShower {
+
+public:
+
+ // Constructor.
+ TimeShower() {}
+
+ // Destructor.
+ virtual ~TimeShower() {}
+
+ // Initialize pointer to Info for error messages.
+ // (Separated from rest of init since not virtual.)
+ void initPtr(Info* infoPtrIn) {infoPtr = infoPtrIn;}
+
+ // Initialize alphaStrong and related pTmin parameters.
+ virtual void init( BeamParticle* beamAPtrIn = 0,
+ BeamParticle* beamBPtrIn = 0);
+
+ // Potential enhancement factor of pTmax scale for hardest emission.
+ virtual double enhancePTmax() {return pTmaxFudge;}
+
+ // Top-level routine to do a full time-like shower in resonance decay.
+ virtual int shower( int iBeg, int iEnd, Event& event, double pTmax);
+
+ // Prepare system for evolution after each new interaction; identify ME.
+ virtual void prepare( int iSys, Event& event);
+
+ // Update dipole list after each ISR emission.
+ virtual void update( int iSys, Event& event);
+
+ // Select next pT in downwards evolution.
+ virtual double pTnext( Event& event, double pTbegAll, double pTendAll);
+
+ // ME corrections and kinematics that may give failure,
+ virtual bool branch( Event& event);
+
+ // Tell which system was the last processed one.
+ int system() const {return iSysSel;};
+
+ // Print dipole list; for debug mainly.
+ virtual void list( ostream& os = cout);
+
+protected:
+
+ // Pointer to various information on the generation.
+ Info* infoPtr;
+
+ // Pointers to the two incoming beams.
+ BeamParticle* beamAPtr;
+ BeamParticle* beamBPtr;
+
+ // Store index of last processed system.
+ int iSysSel;
+
+private:
+
+ // Constants: could only be changed in the code itself.
+ static const double SIMPLIFYROOT, XMARGIN, XMARGINCOMB, TINYPDF, LARGEM2,
+ THRESHM2, LAMBDA3MARGIN;
+
+ // Initialization data, normally only set once.
+ bool doQCDshower, doQEDshowerByQ, doQEDshowerByL, doQEDshowerByGamma,
+ doMEcorrections, doPhiPolAsym, allowBeamRecoil;
+ int alphaSorder, nGluonToQuark, alphaEMorder, nGammaToQuark,
+ nGammaToLepton;
+ double pTmaxFudge, mc, mb, m2c, m2b, alphaSvalue, alphaS2pi,
+ Lambda3flav, Lambda4flav, Lambda5flav, Lambda3flav2, Lambda4flav2,
+ Lambda5flav2, pTcolCutMin, pTcolCut, pT2colCut, pTchgQCut,
+ pT2chgQCut, pTchgLCut, pT2chgLCut, mMaxGamma, m2MaxGamma,
+ octetOniumFraction, octetOniumColFac, mZ, gammaZ, thetaWRat;
+
+ // alphaStrong and alphaEM calculations.
+ AlphaStrong alphaS;
+ AlphaEM alphaEM;
+
+ // All dipole ends and a pointer to the selected hardest dipole end.
+ vector<TimeDipoleEnd> dipEnd;
+ TimeDipoleEnd* dipSel;
+
+ // Setup a dipole end, either QCD or QED/photon one.
+ void setupQCDdip( int iSys, int i, int colTag, int colSign, Event& event,
+ bool isOctetOnium = false);
+ void setupQEDdip( int iSys, int i, int chgType, int gamType, Event& event);
+
+ // Evolve a QCD dipole end.
+ void pT2nextQCD( double pT2begDip, double pT2sel, TimeDipoleEnd& dip,
+ Event& event);
+
+ // Evolve a QED dipole end (except photon).
+ void pT2nextQED( double pT2begDip, double pT2sel, TimeDipoleEnd& dip,
+ Event& event);
+
+ // Find kind of QCD ME correction.
+ void findMEtype( Event& event, TimeDipoleEnd& dip);
+
+ // Find type of particle; used by findMEtype.
+ int findMEparticle( int id);
+
+ // Find mixture of V and A in gamma/Z: energy- and flavour-dependent.
+ double gammaZmix( Event& event, int iRes, int iDau1, int iDau2);
+
+ // Set up to calculate QCD ME correction with calcMEcorr.
+ double findMEcorr(TimeDipoleEnd* dip, Particle& rad, Particle& partner,
+ Particle& emt);
+
+ // Calculate value of QCD ME correction.
+ double calcMEcorr( int kind, int combiIn, double mixIn, double x1,
+ double x2, double r1, double r2);
+
+ // Find coefficient of azimuthal asymmetry from gluon polarization.
+ void findAsymPol( Event& event, TimeDipoleEnd* dip);
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_TimeShower_H
--- /dev/null
+// UserHooks.h is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Header file to allow user access to program at different stages.
+// UserHooks: almost empty base class, with user to write the rela code.
+// MyUserHooks: derived class, only intended as an example.
+
+#ifndef Pythia8_UserHooks_H
+#define Pythia8_UserHooks_H
+
+#include "Event.h"
+#include "PhaseSpace.h"
+#include "PythiaStdlib.h"
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Forward reference to the PhaseSpace class.
+class PhaseSpace;
+
+//**************************************************************************
+
+// UserHooks is base class for user access to program execution.
+
+class UserHooks {
+
+public:
+
+ // Destructor.
+ virtual ~UserHooks() {}
+
+ // Possibility to modify cross section of process.
+ virtual bool canModifySigma() {return false;}
+
+ // Multiplicative factor modifying the cross section of a hard process.
+ virtual double multiplySigmaBy(const SigmaProcess* sigmaProcessPtr,
+ const PhaseSpace* phaseSpacePtr, bool inEvent);
+
+ // Possibility to veto event after process-level selection.
+ virtual bool canVetoProcessLevel() {return false;}
+
+ // Decide whether to veto current process or not, based on process record.
+ // Usage: doVetoProcessLevel( process).
+ virtual bool doVetoProcessLevel( const Event& ) {return false;}
+
+ // Possibility to veto MI + ISR + FSR evolution and kill event,
+ // making decision at a fixed pT scale. Useful for MLM-style matching.
+ virtual bool canVetoPT() {return false;}
+
+ // Transverse-momentum scale for veto test.
+ virtual double scaleVetoPT() {return 0.;}
+
+ // Decide whether to veto current event or not, based on event record.
+ // Usage: doVetoPT( iPos, event), where iPos = 0: no emissions so far;
+ // iPos = 1/2/3 joint evolution, latest step was MI/ISR/FSR;
+ // iPos = 4: FSR only afterwards; iPos = 5: FSR in resonance decay.
+ virtual bool doVetoPT( int , const Event& ) {return false;}
+
+ // Possibility to veto MI + ISR + FSR evolution and kill event,
+ // making decision after fixed number of ISR or FSR steps.
+ virtual bool canVetoStep() {return false;}
+
+ // Up to how many steps should be checked.
+ virtual int numberVetoStep() {return 1;}
+
+ // Decide whether to veto current event or not, based on event record.
+ // Usage: doVetoStep( iPos, nISR, nFSR, event), where iPos as above,
+ // nISR and nFSR number of emissions so far for hard interaction only.
+ virtual bool doVetoStep( int , int , int , const Event& ) {return false;}
+
+ // Possibility to veto event after parton-level selection.
+ virtual bool canVetoPartonLevel() {return false;}
+
+ // Decide whether to veto current partons or not, based on event record.
+ // Usage: doVetoPartonLevel( event).
+ virtual bool doVetoPartonLevel( const Event& ) {return false;}
+
+protected:
+
+ // Constructor.
+ UserHooks() {}
+
+ // subEvent extracts currently resolved partons in the hard process.
+ void subEvent(const Event& event, bool isHardest = true);
+
+ // Have one event object around as work area.
+ Event workEvent;
+
+};
+
+//**************************************************************************
+
+// SuppressSmallPT is a derived class for user access to program execution.
+// It is a simple example, illustrating how to suppress the cross section
+// of 2 -> 2 processes by a factor pT^4 / (pT0^2 + pT^2)^2, with pT0 input,
+// and also modify alpha_strong scale similarly.
+
+class SuppressSmallPT : public UserHooks {
+
+public:
+
+ // Constructor.
+ SuppressSmallPT( double pT0timesMIIn = 1., int numberAlphaSIn = 0,
+ bool useSameAlphaSasMIIn = true) {isInit = false;
+ pT0timesMI = pT0timesMIIn; numberAlphaS = numberAlphaSIn;
+ useSameAlphaSasMI = useSameAlphaSasMIIn;}
+
+ // Possibility to modify cross section of process.
+ virtual bool canModifySigma() {return true;}
+
+ // Multiplicative factor modifying the cross section of a hard process.
+ // Usage: inEvent is true for event generation, false for initialization.
+ virtual double multiplySigmaBy(const SigmaProcess* sigmaProcessPtr,
+ const PhaseSpace* phaseSpacePtr, bool );
+
+private:
+
+ // Save input properties and the squared pT0 scale.
+ bool isInit, useSameAlphaSasMI;
+ int numberAlphaS;
+ double pT0timesMI, pT20;
+
+ // Alpha_strong calculation.
+ AlphaStrong alphaS;
+
+};
+
+//**************************************************************************
+
+// VetoEvolution is a derived class for user access to program execution.
+// It is a simple example, to kill events with > nMax partons at scale
+// pTcheck in the combined evolution, but only counting partons in the
+// hardest interaction and its associated ISR + FSR activity.
+
+class VetoEvolution : public UserHooks {
+
+public:
+
+ // Constructor.
+ VetoEvolution( int nMaxIn, double pTcheckIn) : nMax(nMaxIn),
+ pTcheck (pTcheckIn){}
+
+ // Possibility to veto combined MI + ISR + FSR evolution and
+ // kill event, e.g. for MLM-style matching of matrix elements.
+ virtual bool canVetoEvolution() {return true;}
+
+ // Transverse-momentum scale for veto test.
+ virtual double scaleVetoEvolution() {return pTcheck;}
+
+ // Decide whether to veto current event or not.
+ virtual bool doVetoEvolution(const Event& event) {
+ subEvent( event); return (workEvent.size() > nMax);}
+
+private:
+
+ // Saved values from constructor.
+ int nMax;
+ double pTcheck;
+
+};
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
+#endif // Pythia8_UserHooks_H
--- /dev/null
+// Analysis.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// Sphericity, Thrust, ClusJet and CellJet classes.
+
+#include "Analysis.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sphericity class.
+// This class finds sphericity-related properties of an event.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Minimum number of particles to perform study.
+const int Sphericity::NSTUDYMIN = 2;
+
+// Maximum number of times that an error warning will be printed.
+const int Sphericity::TIMESTOPRINT = 1;
+
+// Assign mimimum squared momentum in weight to avoid division by zero.
+const double Sphericity::P2MIN = 1e-20;
+
+// Second eigenvalue not too low or not possible to find eigenvectors.
+const double Sphericity::EIGENVALUEMIN = 1e-10;
+
+//*********
+
+// Analyze event.
+
+bool Sphericity::analyze(const Event& event, ostream& os) {
+
+ // Initial values, tensor and counters zero.
+ eVal1 = eVal2 = eVal3 = 0.;
+ eVec1 = eVec2 = eVec3 = 0.;
+ double tt[4][4];
+ for (int j = 1; j < 4; ++j)
+ for (int k = j; k < 4; ++k) tt[j][k] = 0.;
+ int nStudy = 0;
+ double denom = 0.;
+
+ // Loop over desired particles in the event.
+ for (int i = 0; i < event.size(); ++i)
+ if (event[i].isFinal()) {
+ if (select > 2 && event[i].isNeutral() ) continue;
+ if (select == 2 && !event[i].isVisible() ) continue;
+ ++nStudy;
+
+ // Calculate matrix to be diagonalized. Special cases for speed.
+ double pNow[4];
+ pNow[1] = event[i].px();
+ pNow[2] = event[i].py();
+ pNow[3] = event[i].pz();
+ double p2Now = pNow[1]*pNow[1] + pNow[2]*pNow[2] + pNow[3]*pNow[3];
+ double pWeight = 1.;
+ if (powerInt == 1) pWeight = 1. / sqrt(max(P2MIN, p2Now));
+ else if (powerInt == 0) pWeight = pow( max(P2MIN, p2Now), powerMod);
+ for (int j = 1; j < 4; ++j)
+ for (int k = j; k < 4; ++k) tt[j][k] += pWeight * pNow[j] * pNow[k];
+ denom += pWeight * p2Now;
+ }
+
+ // Very low multiplicities (0 or 1) not considered.
+ if (nStudy < NSTUDYMIN) {
+ if (nFew < TIMESTOPRINT) os << " PYTHIA Error in " <<
+ "Sphericity::analyze: too few particles" << endl;
+ ++nFew;
+ return false;
+ }
+
+ // Normalize tensor to trace = 1.
+ for (int j = 1; j < 4; ++j)
+ for (int k = j; k < 4; ++k) tt[j][k] /= denom;
+
+ // Find eigenvalues to matrix (third degree equation).
+ double qCoef = ( tt[1][1] * tt[2][2] + tt[1][1] * tt[3][3]
+ + tt[2][2] * tt[3][3] - pow2(tt[1][2]) - pow2(tt[1][3])
+ - pow2(tt[2][3]) ) / 3. - 1./9.;
+ double qCoefRt = sqrt( -qCoef);
+ double rCoef = -0.5 * ( qCoef + 1./9. + tt[1][1] * pow2(tt[2][3])
+ + tt[2][2] * pow2(tt[1][3]) + tt[3][3] * pow2(tt[1][2])
+ - tt[1][1] * tt[2][2] * tt[3][3] )
+ + tt[1][2] * tt[1][3] * tt[2][3] + 1./27.;
+ double pTemp = max( min( rCoef / pow3(qCoefRt), 1.), -1.);
+ double pCoef = cos( acos(pTemp) / 3.);
+ double pCoefRt = sqrt( 3. * (1. - pow2(pCoef)) );
+ eVal1 = 1./3. + qCoefRt * max( 2. * pCoef, pCoefRt - pCoef);
+ eVal3 = 1./3. + qCoefRt * min( 2. * pCoef, -pCoefRt - pCoef);
+ eVal2 = 1. - eVal1 - eVal3;
+
+ // Begin find first and last eigenvector.
+ for (int iVal = 0; iVal < 2; ++iVal) {
+ double eVal = (iVal == 0) ? eVal1 : eVal3;
+
+ // If all particles are back-to-back then only first axis meaningful.
+ if (iVal > 1 && eVal2 < EIGENVALUEMIN) {
+ if (nBack < TIMESTOPRINT) os << " PYTHIA Error in "
+ "Sphericity::analyze: particles too back-to-back" << endl;
+ ++nBack;
+ return false;
+ }
+
+ // Set up matrix to diagonalize.
+ double dd[4][4];
+ for (int j = 1; j < 4; ++j) {
+ dd[j][j] = tt[j][j] - eVal;
+ for (int k = j + 1; k < 4; ++k) {
+ dd[j][k] = tt[j][k];
+ dd[k][j] = tt[j][k];
+ }
+ }
+
+ // Find largest = pivotal element in matrix.
+ int jMax = 0;
+ int kMax = 0;
+ double ddMax = 0.;
+ for (int j = 1; j < 4; ++j)
+ for (int k = 1; k < 4; ++k)
+ if (abs(dd[j][k]) > ddMax) {
+ jMax = j;
+ kMax = k;
+ ddMax = abs(dd[j][k]);
+ }
+
+ // Subtract one row from the other two; find new largest element.
+ int jMax2 = 0;
+ ddMax = 0.;
+ for (int j = 1; j < 4; ++j)
+ if ( j != jMax) {
+ double pivot = dd[j][kMax] / dd[jMax][kMax];
+ for (int k = 1; k < 4; ++k) {
+ dd[j][k] -= pivot * dd[jMax][k];
+ if (abs(dd[j][k]) > ddMax) {
+ jMax2 = j;
+ ddMax = abs(dd[j][k]);
+ }
+ }
+ }
+
+ // Construct eigenvector. Normalize to unit length. Random sign.
+ int k1 = kMax + 1; if (k1 > 3) k1 -= 3;
+ int k2 = kMax + 2; if (k2 > 3) k2 -= 3;
+ double eVec[4];
+ eVec[k1] = -dd[jMax2][k2];
+ eVec[k2] = dd[jMax2][k1];
+ eVec[kMax] = (dd[jMax][k1] * dd[jMax2][k2]
+ - dd[jMax][k2] * dd[jMax2][k1]) / dd[jMax][kMax];
+ double length = sqrt( pow2(eVec[1]) + pow2(eVec[2])
+ + pow2(eVec[3]) );
+ if (Rndm::flat() > 0.5) length = -length;
+
+ // Store eigenvectors.
+ if (iVal == 0) eVec1 = Vec4( eVec[1] / length,
+ eVec[2] / length, eVec[3] / length, 0.);
+ else eVec3 = Vec4( eVec[1] / length,
+ eVec[2] / length, eVec[3] / length, 0.);
+ }
+
+ // Middle eigenvector is orthogonal to the other two.
+ eVec2 = cross3( eVec1, eVec3);
+ if (Rndm::flat() > 0.5) eVec2 = -eVec2;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Provide a listing of the info.
+
+void Sphericity::list(ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA Sphericity Listing -------- \n";
+ if (powerInt !=2) os << " Nonstandard momentum power = "
+ << fixed << setprecision(3) << setw(6) << power << "\n";
+ os << "\n no lambda e_x e_y e_z \n";
+
+ // The three eigenvalues and eigenvectors.
+ os << setprecision(5);
+ os << " 1" << setw(11) << eVal1 << setw(11) << eVec1.px()
+ << setw(10) << eVec1.py() << setw(10) << eVec1.pz() << "\n";
+ os << " 2" << setw(11) << eVal2 << setw(11) << eVec2.px()
+ << setw(10) << eVec2.py() << setw(10) << eVec2.pz() << "\n";
+ os << " 3" << setw(11) << eVal3 << setw(11) << eVec3.px()
+ << setw(10) << eVec3.py() << setw(10) << eVec3.pz() << "\n";
+
+ // Listing finished.
+ os << "\n -------- End PYTHIA Sphericity Listing ----" << endl;
+
+}
+
+
+//**************************************************************************
+
+// Thrust class.
+// This class finds thrust-related properties of an event.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Minimum number of particles to perform study.
+const int Thrust::NSTUDYMIN = 2;
+
+// Maximum number of times that an error warning will be printed.
+const int Thrust::TIMESTOPRINT = 1;
+
+// Major not too low or not possible to find major axis.
+const double Thrust::MAJORMIN = 1e-10;
+
+//*********
+
+// Analyze event.
+
+bool Thrust::analyze(const Event& event, ostream& os) {
+
+ // Initial values and counters zero.
+ eVal1 = eVal2 = eVal3 = 0.;
+ eVec1 = eVec2 = eVec3 = 0.;
+ int nStudy = 0;
+ vector<Vec4> pOrder;
+ Vec4 pSum, nRef, pPart, pFull, pMax;
+
+ // Loop over desired particles in the event.
+ for (int i = 0; i < event.size(); ++i)
+ if (event[i].isFinal()) {
+ if (select > 2 && event[i].isNeutral() ) continue;
+ if (select == 2 && !event[i].isVisible() ) continue;
+ ++nStudy;
+
+ // Store momenta. Use energy component for absolute momentum.
+ Vec4 pNow = event[i].p();
+ pNow.e(pNow.pAbs());
+ pSum += pNow;
+ pOrder.push_back(pNow);
+ }
+
+ // Very low multiplicities (0 or 1) not considered.
+ if (nStudy < NSTUDYMIN) {
+ if (nFew < TIMESTOPRINT) os << " PYTHIA Error in " <<
+ "Thrust::analyze: too few particles" << endl;
+ ++nFew;
+ return false;
+ }
+
+ // Try all combinations of reference vector orthogonal to two particles.
+ for (int i1 = 0; i1 < nStudy - 1; ++i1)
+ for (int i2 = i1 + 1; i2 < nStudy; ++i2) {
+ nRef = cross3( pOrder[i1], pOrder[i2]);
+ nRef /= nRef.pAbs();
+ pPart = 0.;
+
+ // Add all momenta with sign; two choices for each reference particle.
+ for (int i = 0; i < nStudy; ++i) if (i != i1 && i != i2) {
+ if (dot3(pOrder[i], nRef) > 0.) pPart += pOrder[i];
+ else pPart -= pOrder[i];
+ }
+ for (int j = 0; j < 4; ++j) {
+ if (j == 0) pFull = pPart + pOrder[i1] + pOrder[i2];
+ else if (j == 1) pFull = pPart + pOrder[i1] - pOrder[i2];
+ else if (j == 2) pFull = pPart - pOrder[i1] + pOrder[i2];
+ else pFull = pPart - pOrder[i1] - pOrder[i2];
+ pFull.e(pFull.pAbs());
+ if (pFull.e() > pMax.e()) pMax = pFull;
+ }
+ }
+
+ // Maximum gives thrust axis and value.
+ eVal1 = pMax.e() / pSum.e();
+ eVec1 = pMax / pMax.e();
+ eVec1.e(0.);
+
+ // Subtract momentum along thrust axis.
+ double pAbsSum = 0.;
+ for (int i = 0; i < nStudy; ++i) {
+ pOrder[i] -= dot3( eVec1, pOrder[i]) * eVec1;
+ pOrder[i].e(pOrder[i].pAbs());
+ pAbsSum += pOrder[i].e();
+ }
+
+ // Simpleminded major and minor axes if too little transverse left.
+ if (pAbsSum < MAJORMIN * pSum.e()) {
+ if ( abs(eVec1.pz()) > 0.5) eVec2 = Vec4( 1., 0., 0., 0.);
+ else eVec2 = Vec4( 0., 0., 1., 0.);
+ eVec2 -= dot3( eVec1, eVec2) * eVec1;
+ eVec2 /= eVec2.pAbs();
+ eVec3 = cross3( eVec1, eVec2);
+ return true;
+ }
+
+ // Try all reference vectors orthogonal to one particles.
+ pMax = 0.;
+ for (int i1 = 0; i1 < nStudy; ++i1) {
+ nRef = cross3( pOrder[i1], eVec1);
+ nRef /= nRef.pAbs();
+ pPart = 0.;
+
+ // Add all momenta with sign; two choices for each reference particle.
+ for (int i = 0; i < nStudy; ++i) if (i != i1) {
+ if (dot3(pOrder[i], nRef) > 0.) pPart += pOrder[i];
+ else pPart -= pOrder[i];
+ }
+ pFull = pPart + pOrder[i1];
+ pFull.e(pFull.pAbs());
+ if (pFull.e() > pMax.e()) pMax = pFull;
+ pFull = pPart - pOrder[i1];
+ pFull.e(pFull.pAbs());
+ if (pFull.e() > pMax.e()) pMax = pFull;
+ }
+
+ // Maximum gives major axis and value.
+ eVal2 = pMax.e() / pSum.e();
+ eVec2 = pMax / pMax.e();
+ eVec2.e(0.);
+
+ // Orthogonal direction gives minor axis, and from there value.
+ eVec3 = cross3( eVec1, eVec2);
+ pAbsSum = 0.;
+ for (int i = 0; i < nStudy; ++i)
+ pAbsSum += abs( dot3(eVec3, pOrder[i]) );
+ eVal3 = pAbsSum / pSum.e();
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Provide a listing of the info.
+
+void Thrust::list(ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA Thrust Listing ------------ \n"
+ << "\n value e_x e_y e_z \n";
+
+ // The thrust, major and minor values and related event axes.
+ os << setprecision(5);
+ os << " Thr" << setw(11) << eVal1 << setw(11) << eVec1.px()
+ << setw(10) << eVec1.py() << setw(10) << eVec1.pz() << "\n";
+ os << " Maj" << setw(11) << eVal2 << setw(11) << eVec2.px()
+ << setw(10) << eVec2.py() << setw(10) << eVec2.pz() << "\n";
+ os << " Min" << setw(11) << eVal3 << setw(11) << eVec3.px()
+ << setw(10) << eVec3.py() << setw(10) << eVec3.pz() << "\n";
+
+ // Listing finished.
+ os << "\n -------- End PYTHIA Thrust Listing --------" << endl;
+
+}
+
+//**************************************************************************
+
+// SingleClusterJet class.
+// Simple helper class to ClusterJet for a jet and its contents.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Assign minimal pAbs to avoid division by zero.
+const double SingleClusterJet::PABSMIN = 1e-10;
+
+//*********
+
+// Distance measures between two SingleClusterJet objects.
+
+double dist2Fun(int measure, const SingleClusterJet& j1,
+ const SingleClusterJet& j2) {
+
+ // JADE distance.
+ if (measure == 2) return 2. * j1.pJet.e() * j2.pJet.e()
+ * (1. - dot3( j1.pJet, j2.pJet) / (j1.pAbs * j2.pAbs) );
+
+ // Durham distance.
+ if (measure == 3) return 2. * pow2( min( j1.pJet.e(), j2.pJet.e() ) )
+ * (1. - dot3( j1.pJet, j2.pJet) / (j1.pAbs * j2.pAbs) );
+
+ // Lund distance; "default".
+ return (j1.pAbs * j2.pAbs - dot3( j1.pJet, j2.pJet))
+ * 2. * j1.pAbs * j2.pAbs / pow2(j1.pAbs + j2.pAbs);
+
+}
+
+//**************************************************************************
+
+// ClusterJet class.
+// This class performs a jet clustering according to different
+// distance measures: Lund, JADE or Durham.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maximum number of times that an error warning will be printed.
+const int ClusterJet::TIMESTOPRINT = 1;
+
+// Assign minimal pAbs to avoid division by zero.
+const double ClusterJet::PABSMIN = 1e-10;
+
+// Initial pT/m preclustering scale as fraction of clustering one.
+const double ClusterJet::PRECLUSTERFRAC = 0.1;
+
+// Step with which pT/m is reduced if preclustering gives too few jets.
+const double ClusterJet::PRECLUSTERSTEP = 0.8;
+
+//*********
+
+// Analyze event.
+
+bool ClusterJet::analyze(const Event& event, double yScaleIn,
+ double pTscaleIn, int nJetMinIn, int nJetMaxIn, ostream& os) {
+
+ // Input values. Initial values zero.
+ yScale = yScaleIn;
+ pTscale = pTscaleIn;
+ nJetMin = nJetMinIn;
+ nJetMax = nJetMaxIn;
+ particles.resize(0);
+ jets.resize(0);
+ Vec4 pSum;
+
+ // Loop over desired particles in the event.
+ for (int i = 0; i < event.size(); ++i)
+ if (event[i].isFinal()) {
+ if (select > 2 && event[i].isNeutral() ) continue;
+ if (select == 2 && !event[i].isVisible() ) continue;
+
+ // Store them, possibly with modified mass => new energy.
+ Vec4 pTemp = event[i].p();
+ if (massSet == 0 || massSet == 1) {
+ double mTemp = (massSet == 0 || event[i].id() == 22)
+ ? 0. : piMass;
+ double eTemp = sqrt(pTemp.pAbs2() + pow2(mTemp));
+ pTemp.e(eTemp);
+ }
+ particles.push_back( SingleClusterJet(pTemp, i) );
+ pSum += pTemp;
+ }
+
+ // Very low multiplicities not considered.
+ nParticles = particles.size();
+ if (nParticles < nJetMin) {
+ if (nFew < TIMESTOPRINT) os << " PYTHIA Error in " <<
+ "ClusterJet::analyze: too few particles" << endl;
+ ++nFew;
+ return false;
+ }
+
+ // Squared maximum distance in GeV^2 for joining.
+ double p2Sum = pSum.m2Calc();
+ dist2Join = max( yScale * p2Sum, pow2(pTscale));
+ dist2BigMin = 2. * max( dist2Join, p2Sum);
+
+ // Do preclustering if desired and possible.
+ if (doPrecluster && nParticles > nJetMin + 2) {
+ precluster();
+ if (doReassign) reassign();
+ }
+
+ // If no preclustering: each particle is a starting jet.
+ else for (int i = 0; i < nParticles; ++i) {
+ jets.push_back( SingleClusterJet(particles[i]) );
+ particles[i].daughter = i;
+ }
+
+ // Begin iteration towards fewer jets.
+ for ( ; ; ) {
+
+ // Find the two closest jets.
+ double dist2Min = dist2BigMin;
+ int jMin = 0;
+ int kMin = 0;
+ for (int j = 0; j < int(jets.size()) - 1; ++j)
+ for (int k = j + 1; k < int(jets.size()); ++k) {
+ double dist2 = dist2Fun( measure, jets[j], jets[k]);
+ if (dist2 < dist2Min) {
+ dist2Min = dist2;
+ jMin = j;
+ kMin = k;
+ }
+ }
+
+ // Stop if no pair below cut and not more jets than allowed.
+ if ( dist2Min > dist2Join
+ && (nJetMax < nJetMin || int(jets.size()) <= nJetMax) ) break;
+
+ // Join two closest jets.
+ jets[jMin].pJet += jets[kMin].pJet;
+ jets[jMin].pAbs = max( PABSMIN, jets[jMin].pJet.pAbs());
+ jets[jMin].multiplicity += jets[kMin].multiplicity;
+ for (int i = 0; i < nParticles; ++i)
+ if (particles[i].daughter == kMin) particles[i].daughter = jMin;
+
+ // Move up last jet to empty slot to shrink list.
+ jets[kMin] = jets.back();
+ jets.pop_back();
+ int iEnd = jets.size();
+ for (int i = 0; i < nParticles; ++i)
+ if (particles[i].daughter == iEnd) particles[i].daughter = kMin;
+
+ // Do reassignments of particles to nearest jet if desired.
+ if (doReassign) reassign();
+
+ // Stop if reached minimum allowed number of jets. Else continue.
+ if (int(jets.size()) <= nJetMin) break;
+ }
+
+ // Order jets in decreasing energy.
+ for (int j = 0; j < int(jets.size()) - 1; ++j)
+ for (int k = int(jets.size()) - 1; k > j; --k)
+ if (jets[k].pJet.e() > jets[k-1].pJet.e()) {
+ swap( jets[k], jets[k-1]);
+ for (int i = 0; i < nParticles; ++i) {
+ if (particles[i].daughter == k) particles[i].daughter = k-1;
+ else if (particles[i].daughter == k-1) particles[i].daughter = k;
+ }
+ }
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Precluster nearby particles to save computer time.
+
+void ClusterJet::precluster() {
+
+ // Begin iteration over preclustering scale.
+ distPre = PRECLUSTERFRAC * sqrt(dist2Join) / PRECLUSTERSTEP;
+ for ( ; ;) {
+ distPre *= PRECLUSTERSTEP;
+ dist2Pre = pow2(distPre);
+ for (int i = 0; i < nParticles; ++i) {
+ particles[i].daughter = -1;
+ particles[i].isAssigned = false;
+ }
+
+ // Sum up low-momentum region. Jet if enough momentum.
+ Vec4 pCentral;
+ int multCentral = 0;
+ for (int i = 0; i < nParticles; ++i)
+ if (particles[i].pAbs < 2. * distPre) {
+ pCentral += particles[i].pJet;
+ multCentral += particles[i].multiplicity;
+ particles[i].isAssigned = true;
+ }
+ if (pCentral.pAbs() > 2. * distPre) {
+ jets.push_back( SingleClusterJet(pCentral) );
+ jets.back().multiplicity = multCentral;
+ for (int i = 0; i < nParticles; ++i)
+ if (particles[i].isAssigned) particles[i].daughter = 0;
+ }
+
+ // Find fastest remaining particle until none left.
+ for ( ; ;) {
+ int iMax = -1;
+ double pMax = 0.;
+ for (int i = 0; i < nParticles; ++i)
+ if ( !particles[i].isAssigned && particles[i].pAbs > pMax) {
+ iMax = i;
+ pMax = particles[i].pAbs;
+ }
+ if (iMax == -1) break;
+
+ // Sum up precluster around it according to distance function.
+ Vec4 pPre;
+ int multPre = 0;
+ int nRemain = 0;
+ for (int i = 0; i < nParticles; ++i)
+ if ( !particles[i].isAssigned) {
+ double dist2 = dist2Fun( measure, particles[iMax],
+ particles[i]);
+ if (dist2 < dist2Pre) {
+ pPre += particles[i].pJet;
+ ++multPre;
+ particles[i].isAssigned = true;
+ particles[i].daughter = jets.size();
+ } else ++nRemain;
+ }
+ jets.push_back( SingleClusterJet(pPre) );
+ jets.back().multiplicity = multPre;
+
+ // Decide whether sensible starting configuration or iterate.
+ if (int(jets.size()) + nRemain < nJetMin) break;
+ }
+ if (int(jets.size()) >= nJetMin) break;
+ }
+
+}
+
+//*********
+
+// Reassign particles to nearest jet to correct misclustering.
+
+void ClusterJet::reassign() {
+
+ // Reset clustered momenta.
+ for (int j = 0; j < int(jets.size()); ++j) {
+ jets[j].pTemp = 0.;
+ jets[j].multiplicity = 0;
+ }
+
+ // Loop through particles to find closest jet.
+ for (int i = 0; i < nParticles; ++i) {
+ particles[i].daughter = -1;
+ double dist2Min = dist2BigMin;
+ int jMin = 0;
+ for (int j = 0; j < int(jets.size()); ++j) {
+ double dist2 = dist2Fun( measure, particles[i], jets[j]);
+ if (dist2 < dist2Min) {
+ dist2Min = dist2;
+ jMin = j;
+ }
+ }
+ jets[jMin].pTemp += particles[i].pJet;
+ ++jets[jMin].multiplicity;
+ particles[i].daughter = jMin;
+ }
+
+ // Replace old by new jet momenta.
+ for (int j = 0; j < int(jets.size()); ++j) {
+ jets[j].pJet = jets[j].pTemp;
+ jets[j].pAbs = max( PABSMIN, jets[j].pJet.pAbs());
+ }
+
+ // Check that no empty clusters after reassignments.
+ for ( ; ; ) {
+
+ // If no empty jets then done.
+ int jEmpty = -1;
+ for (int j = 0; j < int(jets.size()); ++j)
+ if (jets[j].multiplicity == 0) jEmpty = j;
+ if (jEmpty == -1) return;
+
+ // Find particle assigned to jet with largest distance to it.
+ int iSplit = -1;
+ double dist2Max = 0.;
+ for (int i = 0; i < nParticles; ++i) {
+ int j = particles[i].daughter;
+ double dist2 = dist2Fun( measure, particles[i], jets[j]);
+ if (dist2 > dist2Max) {
+ iSplit = i;
+ dist2Max = dist2;
+ }
+ }
+
+ // Let this particle form new jet and subtract off from existing.
+ int jSplit = particles[iSplit].daughter;
+ jets[jEmpty] = SingleClusterJet( particles[iSplit].pJet );
+ jets[jSplit].pJet -= particles[iSplit].pJet;
+ jets[jSplit].pAbs = max( PABSMIN,jets[jSplit].pJet.pAbs());
+ particles[iSplit].daughter = jEmpty;
+ --jets[jSplit].multiplicity;
+ }
+
+}
+
+//*********
+
+// Provide a listing of the info.
+
+void ClusterJet::list(ostream& os) {
+
+ // Header.
+ string method = (measure == 1) ? "Lund pT"
+ : ( (measure == 2) ? "JADE m" : "Durham kT" ) ;
+ os << "\n -------- PYTHIA ClusterJet Listing, " << setw(9) << method
+ << " =" << fixed << setprecision(3) << setw(7) << sqrt(dist2Join)
+ << " GeV --- \n \n no mult p_x p_y p_z "
+ << " e m \n";
+
+ // The jets.
+ for (int i = 0; i < int(jets.size()); ++i) {
+ os << setw(4) << i << setw(6) << jets[i].multiplicity << setw(11)
+ << jets[i].pJet.px() << setw(11) << jets[i].pJet.py()
+ << setw(11) << jets[i].pJet.pz() << setw(11)
+ << jets[i].pJet.e() << setw(11) << jets[i].pJet.mCalc()
+ << "\n";
+ }
+
+ // Listing finished.
+ os << "\n -------- End PYTHIA ClusterJet Listing ---------------"
+ << "--------" << endl;
+}
+
+//**************************************************************************
+
+// CellJet class.
+// This class performs a cone jet search in (eta, phi, E_T) space.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Minimum number of particles to perform study.
+const int CellJet::TIMESTOPRINT = 1;
+
+//*********
+
+// Analyze event.
+
+bool CellJet::analyze(const Event& event, double eTjetMinIn,
+ double coneRadiusIn, double eTseedIn, ostream& ) {
+
+ // Input values. Initial values zero.
+ eTjetMin = eTjetMinIn;
+ coneRadius = coneRadiusIn;
+ eTseed = eTseedIn;
+ jets.resize(0);
+ vector<SingleCell> cells;
+
+ // Loop over desired particles in the event.
+ for (int i = 0; i < event.size(); ++i)
+ if (event[i].isFinal()) {
+ if (select > 2 && event[i].isNeutral() ) continue;
+ if (select == 2 && !event[i].isVisible() ) continue;
+
+ // Find particle position in (eta, phi, pT) space.
+ double etaNow = event[i].eta();
+ if (abs(etaNow) > etaMax) continue;
+ double phiNow = event[i].phi();
+ double pTnow = event[i].pT();
+ int iEtaNow = max(1, min( nEta, 1 + int(nEta * 0.5
+ * (1. + etaNow / etaMax) ) ) );
+ int iPhiNow = max(1, min( nPhi, 1 + int(nPhi * 0.5
+ * (1. + phiNow / M_PI) ) ) );
+ int iCell = nPhi * iEtaNow + iPhiNow;
+
+ // Add pT to cell already hit or book a new cell.
+ bool found = false;
+ for (int j = 0; j < int(cells.size()); ++j) {
+ if (iCell == cells[j].iCell) {
+ found = true;
+ ++cells[j].multiplicity;
+ cells[j].eTcell += pTnow;
+ continue;
+ }
+ }
+ if (!found) {
+ double etaCell = (etaMax / nEta) * (2 * iEtaNow - 1 - nEta);
+ double phiCell = (M_PI / nPhi) * (2 * iPhiNow - 1 - nPhi);
+ cells.push_back( SingleCell( iCell, etaCell, phiCell, pTnow, 1) );
+ }
+ }
+
+ // Smear true bin content by calorimeter resolution.
+ if (smear > 0)
+ for (int j = 0; j < int(cells.size()); ++j) {
+ double eTeConv = (smear < 2) ? 1. : cosh( cells[j].etaCell );
+ double eBef = cells[j].eTcell * eTeConv;
+ double eAft = 0.;
+ do eAft = eBef + resolution * sqrt(eBef) * Rndm::gauss();
+ while (eAft < 0 || eAft > upperCut * eBef);
+ cells[j].eTcell = eAft / eTeConv;
+ }
+
+ // Remove cells below threshold for seed or for use at all.
+ for (int j = 0; j < int(cells.size()); ++j) {
+ if (cells[j].eTcell < eTseed) cells[j].canBeSeed = false;
+ if (cells[j].eTcell < threshold) cells[j].isUsed = true;
+ }
+
+ // Find seed cell: the one with highest pT of not yet probed ones.
+ for ( ; ; ) {
+ int jMax = 0;
+ double eTmax = 0.;
+ for (int j = 0; j < int(cells.size()); ++j)
+ if (cells[j].canBeSeed && cells[j].eTcell > eTmax) {
+ jMax = j;
+ eTmax = cells[j].eTcell;
+ }
+
+ // If too small cell eT then done, else start new trial jet.
+ if (eTmax < eTseed) break;
+ double etaCenterNow = cells[jMax].etaCell;
+ double phiCenterNow = cells[jMax].phiCell;
+ double eTjetNow = 0.;
+
+ // Sum up unused cells within required distance of seed.
+ for (int j = 0; j < int(cells.size()); ++j) {
+ if (cells[j].isUsed) continue;
+ double dEta = abs( cells[j].etaCell - etaCenterNow );
+ if (dEta > coneRadius) continue;
+ double dPhi = abs( cells[j].phiCell - phiCenterNow );
+ if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
+ if (dPhi > coneRadius) continue;
+ if (pow2(dEta) + pow2(dPhi) > pow2(coneRadius)) continue;
+ cells[j].isAssigned = true;
+ eTjetNow += cells[j].eTcell;
+ }
+
+ // Reject cluster below minimum ET.
+ if (eTjetNow < eTjetMin) {
+ cells[jMax].canBeSeed = false;
+ for (int j = 0; j < int(cells.size()); ++j)
+ cells[j].isAssigned = false;
+
+ // Else find new jet properties.
+ } else {
+ double etaWeightedNow = 0.;
+ double phiWeightedNow = 0.;
+ int multiplicityNow = 0;
+ Vec4 pMassiveNow;
+ for (int j = 0; j < int(cells.size()); ++j)
+ if (cells[j].isAssigned) {
+ cells[j].canBeSeed = false;
+ cells[j].isUsed = true;
+ cells[j].isAssigned = false;
+ etaWeightedNow += cells[j].eTcell * cells[j].etaCell;
+ double phiCell = cells[j].phiCell;
+ if (abs(phiCell - phiCenterNow) > M_PI)
+ phiCell += (phiCenterNow > 0.) ? 2. * M_PI : -2. * M_PI;
+ phiWeightedNow += cells[j].eTcell * phiCell;
+ multiplicityNow += cells[j].multiplicity;
+ pMassiveNow += cells[j].eTcell * Vec4(
+ cos(cells[j].phiCell), sin(cells[j].phiCell),
+ sinh(cells[j].etaCell), cosh(cells[j].etaCell) );
+ }
+ etaWeightedNow /= eTjetNow;
+ phiWeightedNow /= eTjetNow;
+
+ // Bookkeep new jet, in decreasing ET order.
+ jets.push_back( SingleCellJet( eTjetNow, etaCenterNow, phiCenterNow,
+ etaWeightedNow, phiWeightedNow, multiplicityNow, pMassiveNow) );
+ for (int i = int(jets.size()) - 1; i > 0; --i) {
+ if (jets[i-1].eTjet > jets[i].eTjet) break;
+ swap( jets[i-1], jets[i]);
+ }
+ }
+ }
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Provide a listing of the info.
+
+void CellJet::list(ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA CellJet Listing, eTjetMin = "
+ << fixed << setprecision(3) << setw(8) << eTjetMin
+ << ", coneRadius = " << setw(5) << coneRadius
+ << " ------------------------------ \n \n no "
+ << " eTjet etaCtr phiCtr etaWt phiWt mult p_x"
+ << " p_y p_z e m \n";
+
+ // The jets.
+ for (int i = 0; i < int(jets.size()); ++i) {
+ os << setw(4) << i << setw(10) << jets[i].eTjet << setw(8)
+ << jets[i].etaCenter << setw(8) << jets[i].phiCenter << setw(8)
+ << jets[i].etaWeighted << setw(8) << jets[i].phiWeighted
+ << setw(5) << jets[i].multiplicity << setw(11)
+ << jets[i].pMassive.px() << setw(11) << jets[i].pMassive.py()
+ << setw(11) << jets[i].pMassive.pz() << setw(11)
+ << jets[i].pMassive.e() << setw(11)
+ << jets[i].pMassive.mCalc() << "\n";
+ }
+
+ // Listing finished.
+ os << "\n -------- End PYTHIA CellJet Listing ------------------"
+ << "-------------------------------------------------"
+ << endl;
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// Basics.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the Rndm, Vec4,
+// RotBstMatrix and Hist classes, and some related global functions.
+
+#include "Basics.h"
+
+// Access time information.
+#include <ctime>
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Rndm class.
+// This class handles random number generation according to the
+// Marsaglia-Zaman-Tsang algorithm
+
+//*********
+
+// Definitions of static variables.
+
+bool Rndm::initRndm = false;
+bool Rndm::saveGauss = false;
+int Rndm::i97, Rndm::j97;
+int Rndm::defaultSeed = 19780503;
+double Rndm::u[97], Rndm::c, Rndm::cd, Rndm::cm, Rndm::save;
+bool Rndm::useExternalRndm = false;
+RndmEngine* Rndm::rndmPtr = 0;
+
+//*********
+
+// Method to pass in pointer for external random number generation.
+
+bool Rndm::rndmEnginePtr( RndmEngine* rndmPtrIn) {
+
+ // Save pointer.
+ if (rndmPtrIn == 0) return false;
+ rndmPtr = rndmPtrIn;
+ useExternalRndm = true;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Initialize, normally at construction or in first call.
+
+void Rndm::init(int seedIn) {
+
+ // Pick seed in convenient way. Assure it to be non-negative.
+ int seed = seedIn;
+ if (seedIn < 0) seed = defaultSeed;
+ else if (seedIn == 0) seed = int(time(0));
+ if (seed < 0) seed = -seed;
+
+ // Unpack seed.
+ int ij = (seed/30082) % 31329;
+ int kl = seed % 30082;
+ int i = (ij/177) % 177 + 2;
+ int j = ij % 177 + 2;
+ int k = (kl/169) % 178 + 1;
+ int l = kl % 169;
+
+ // Initialize random number array.
+ for (int ii = 0; ii < 97; ++ii) {
+ double s = 0.;
+ double t = 0.5;
+ for (int jj = 0; jj < 48; ++jj) {
+ int m = (( (i*j)%179 )*k) % 179;
+ i = j;
+ j = k;
+ k = m;
+ l = (53*l+1) % 169;
+ if ( (l*m) % 64 >= 32) s += t;
+ t *= 0.5;
+ }
+ u[ii] = s;
+ }
+
+ // Initialize other variables.
+ double twom24 = 1.;
+ for (int i24 = 0; i24 < 24; ++i24) twom24 *= 0.5;
+ c = 362436. * twom24;
+ cd = 7654321. * twom24;
+ cm = 16777213. * twom24;
+ i97 = 96;
+ j97 = 32;
+
+ // Finished.
+ initRndm = true;
+
+}
+
+//*********
+
+// Generate next random number uniformly between 0 and 1.
+
+double Rndm::flat() {
+
+ // Use external random number generator if such has been linked.
+ if(useExternalRndm) return rndmPtr->flat();
+
+ // Ensure that already initialized.
+ if (!initRndm) init(defaultSeed);
+
+ // Find next random number and update saved state.
+ double uni;
+ do {
+ uni = u[i97] - u[j97];
+ if (uni < 0.) uni += 1.;
+ u[i97] = uni;
+ if (--i97 < 0) i97 = 96;
+ if (--j97 < 0) j97 = 96;
+ c -= cd;
+ if (c < 0.) c += cm;
+ uni -= c;
+ if(uni < 0.) uni += 1.;
+ } while (uni <= 0. || uni >= 1.);
+ return uni;
+
+}
+
+//*********
+
+// Generate random numbers according to exp(-x^2/2).
+
+double Rndm::gauss() {
+
+ // Generate pair of Gaussian random numbers.
+ if (!saveGauss) {
+ saveGauss = true;
+ double r = sqrt(-2. * log(flat()));
+ double phi = 2. * M_PI * flat();
+ save = r * sin(phi);
+ return r * cos(phi);
+
+ // Use saved element of pair.
+ } else {
+ saveGauss = false;
+ return save;
+ }
+
+}
+
+//*********
+
+// Pick one option among vector of (positive) probabilities.
+
+int Rndm::pick(const vector<double>& prob) {
+
+ double work = 0.;
+ for (int i = 0; i < int(prob.size()); ++i) {work += prob[i];}
+ work *= flat();
+ int index = -1;
+ do { work -= prob[++index]; } while (work > 0 && index < int(prob.size()));
+ return index;
+
+}
+
+//**************************************************************************
+
+// Vec4 class.
+// This class implements four-vectors, in energy-momentum space.
+// (But could also be used to hold space-time four-vectors.)
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Small number to avoid division by zero.
+const double Vec4::TINY = 1e-20;
+
+//*********
+
+// Rotation (simple).
+
+void Vec4::rot(double thetaIn, double phiIn) {
+
+ double cthe = cos(thetaIn);
+ double sthe = sin(thetaIn);
+ double cphi = cos(phiIn);
+ double sphi = sin(phiIn);
+ double tmpx = cthe * cphi * xx - sphi * yy + sthe * cphi * zz;
+ double tmpy = cthe * sphi * xx + cphi * yy + sthe * sphi * zz;
+ double tmpz = -sthe * xx + cthe * zz;
+ xx = tmpx;
+ yy = tmpy;
+ zz = tmpz;
+
+}
+
+//*********
+
+// Azimuthal rotation phi around an arbitrary axis (nz, ny, nz).
+
+void Vec4::rotaxis(double phiIn, double nx, double ny, double nz) {
+
+ double norm = 1./sqrt(nx*nx + ny*ny + nz*nz);
+ nx *= norm;
+ ny *= norm;
+ nz *= norm;
+ double cphi = cos(phiIn);
+ double sphi = sin(phiIn);
+ double comb = (nx * xx + ny * yy + nz * zz) * (1. - cphi);
+ double tmpx = cphi * xx + comb * nx + sphi * (ny * zz - nz * yy);
+ double tmpy = cphi * yy + comb * ny + sphi * (nz * xx - nx * zz);
+ double tmpz = cphi * zz + comb * nz + sphi * (nx * yy - ny * xx);
+ xx = tmpx;
+ yy = tmpy;
+ zz = tmpz;
+
+}
+
+//*********
+
+// Azimuthal rotation phi around an arbitrary (3-vector component of) axis.
+
+void Vec4::rotaxis(double phiIn, const Vec4& n) {
+
+ double nx = n.xx;
+ double ny = n.yy;
+ double nz = n.zz;
+ double norm = 1./sqrt(nx*nx + ny*ny + nz*nz);
+ nx *= norm;
+ ny *=norm;
+ nz *=norm;
+ double cphi = cos(phiIn);
+ double sphi = sin(phiIn);
+ double comb = (nx * xx + ny * yy + nz * zz) * (1. - cphi);
+ double tmpx = cphi * xx + comb * nx + sphi * (ny * zz - nz * yy);
+ double tmpy = cphi * yy + comb * ny + sphi * (nz * xx - nx * zz);
+ double tmpz = cphi * zz + comb * nz + sphi * (nx * yy - ny * xx);
+ xx = tmpx;
+ yy = tmpy;
+ zz = tmpz;
+
+}
+
+//*********
+
+// Boost (simple).
+
+void Vec4::bst(double betaX, double betaY, double betaZ) {
+
+ double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
+ double gamma = 1. / sqrt(1. - beta2);
+ double prod1 = betaX * xx + betaY * yy + betaZ * zz;
+ double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
+ xx += prod2 * betaX;
+ yy += prod2 * betaY;
+ zz += prod2 * betaZ;
+ tt = gamma * (tt + prod1);
+
+}
+
+//*********
+
+// Boost (simple, given gamma).
+
+void Vec4::bst(double betaX, double betaY, double betaZ, double gamma) {
+
+ double prod1 = betaX * xx + betaY * yy + betaZ * zz;
+ double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
+ xx += prod2 * betaX;
+ yy += prod2 * betaY;
+ zz += prod2 * betaZ;
+ tt = gamma * (tt + prod1);
+
+}
+
+//*********
+
+// Boost given by a Vec4 p.
+
+void Vec4::bst(const Vec4& pIn) {
+
+ double betaX = pIn.xx / pIn.tt;
+ double betaY = pIn.yy / pIn.tt;
+ double betaZ = pIn.zz / pIn.tt;
+ double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
+ double gamma = 1. / sqrt(1. - beta2);
+ double prod1 = betaX * xx + betaY * yy + betaZ * zz;
+ double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
+ xx += prod2 * betaX;
+ yy += prod2 * betaY;
+ zz += prod2 * betaZ;
+ tt = gamma * (tt + prod1);
+
+}
+
+//*********
+
+// Boost given by a Vec4 p and double m.
+
+void Vec4::bst(const Vec4& pIn, double mIn) {
+
+ double betaX = pIn.xx / pIn.tt;
+ double betaY = pIn.yy / pIn.tt;
+ double betaZ = pIn.zz / pIn.tt;
+ double gamma = pIn.tt / mIn;
+ double prod1 = betaX * xx + betaY * yy + betaZ * zz;
+ double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
+ xx += prod2 * betaX;
+ yy += prod2 * betaY;
+ zz += prod2 * betaZ;
+ tt = gamma * (tt + prod1);
+
+}
+
+//*********
+
+// Boost given by a Vec4 p; boost in opposite direction.
+
+void Vec4::bstback(const Vec4& pIn) {
+
+ double betaX = -pIn.xx / pIn.tt;
+ double betaY = -pIn.yy / pIn.tt;
+ double betaZ = -pIn.zz / pIn.tt;
+ double beta2 = betaX*betaX + betaY*betaY + betaZ*betaZ;
+ double gamma = 1. / sqrt(1. - beta2);
+ double prod1 = betaX * xx + betaY * yy + betaZ * zz;
+ double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
+ xx += prod2 * betaX;
+ yy += prod2 * betaY;
+ zz += prod2 * betaZ;
+ tt = gamma * (tt + prod1);
+
+}
+
+//*********
+
+// Boost given by a Vec4 p and double m; boost in opposite direction.
+
+void Vec4::bstback(const Vec4& pIn, double mIn) {
+
+ double betaX = -pIn.xx / pIn.tt;
+ double betaY = -pIn.yy / pIn.tt;
+ double betaZ = -pIn.zz / pIn.tt;
+ double gamma = pIn.tt / mIn;
+ double prod1 = betaX * xx + betaY * yy + betaZ * zz;
+ double prod2 = gamma * (gamma * prod1 / (1. + gamma) + tt);
+ xx += prod2 * betaX;
+ yy += prod2 * betaY;
+ zz += prod2 * betaZ;
+ tt = gamma * (tt + prod1);
+
+}
+
+//*********
+
+// Arbitrary combination of rotations and boosts defined by 4 * 4 matrix.
+
+void Vec4::rotbst(const RotBstMatrix& M) {
+
+ double x = xx; double y = yy; double z = zz; double t = tt;
+ tt = M.M[0][0] * t + M.M[0][1] * x + M.M[0][2] * y + M.M[0][3] * z;
+ xx = M.M[1][0] * t + M.M[1][1] * x + M.M[1][2] * y + M.M[1][3] * z;
+ yy = M.M[2][0] * t + M.M[2][1] * x + M.M[2][2] * y + M.M[2][3] * z;
+ zz = M.M[3][0] * t + M.M[3][1] * x + M.M[3][2] * y + M.M[3][3] * z;
+
+}
+
+//*********
+
+// The invariant mass of two four-vectors.
+
+double m(const Vec4& v1, const Vec4& v2) {
+ double m2 = pow2(v1.tt + v2.tt) - pow2(v1.xx + v2.xx)
+ - pow2(v1.yy + v2.yy) - pow2(v1.zz + v2.zz);
+ return (m2 > 0.) ? sqrt(m2) : 0.;
+}
+
+//*********
+
+// The squared invariant mass of two four-vectors.
+
+double m2(const Vec4& v1, const Vec4& v2) {
+ double m2 = pow2(v1.tt + v2.tt) - pow2(v1.xx + v2.xx)
+ - pow2(v1.yy + v2.yy) - pow2(v1.zz + v2.zz);
+ return m2;
+}
+
+//*********
+
+// The scalar product of two three-vectors.
+
+double dot3(const Vec4& v1, const Vec4& v2) {
+ return v1.xx*v2.xx + v1.yy*v2.yy + v1.zz*v2.zz;
+}
+
+//*********
+
+// The cross product of two three-vectors.
+
+Vec4 cross3(const Vec4& v1, const Vec4& v2) {
+ Vec4 v;
+ v.xx = v1.yy * v2.zz - v1.zz * v2.yy;
+ v.yy = v1.zz * v2.xx - v1.xx * v2.zz;
+ v.zz = v1.xx * v2.yy - v1.yy * v2.xx; return v;
+}
+
+//*********
+
+// Opening angle between two three-vectors.
+
+double theta(const Vec4& v1, const Vec4& v2) {
+ double cthe = (v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz)
+ / sqrt( (v1.xx*v1.xx + v1.yy*v1.yy + v1.zz*v1.zz)
+ * (v2.xx*v2.xx + v2.yy*v2.yy + v2.zz*v2.zz) );
+ cthe = max(-1., min(1., cthe));
+ return acos(cthe);
+}
+
+//*********
+
+// Cosine of the opening angle between two three-vectors.
+
+double costheta(const Vec4& v1, const Vec4& v2) {
+ double cthe = (v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz)
+ / sqrt( (v1.xx*v1.xx + v1.yy*v1.yy + v1.zz*v1.zz)
+ * (v2.xx*v2.xx + v2.yy*v2.yy + v2.zz*v2.zz) );
+ cthe = max(-1., min(1., cthe));
+ return cthe;
+}
+
+//*********
+
+// Azimuthal angle between two three-vectors.
+
+double phi(const Vec4& v1, const Vec4& v2) {
+ double cphi = (v1.xx * v2.xx + v1.yy * v2.yy) / sqrt( max( Vec4::TINY,
+ (v1.xx*v1.xx + v1.yy*v1.yy) * (v2.xx*v2.xx + v2.yy*v2.yy) ));
+ cphi = max(-1., min(1., cphi));
+ return acos(cphi);
+}
+
+//*********
+
+// Cosine of the azimuthal angle between two three-vectors.
+
+double cosphi(const Vec4& v1, const Vec4& v2) {
+ double cphi = (v1.xx * v2.xx + v1.yy * v2.yy) / sqrt( max( Vec4::TINY,
+ (v1.xx*v1.xx + v1.yy*v1.yy) * (v2.xx*v2.xx + v2.yy*v2.yy) ));
+ cphi = max(-1., min(1., cphi));
+ return cphi;
+}
+
+//*********
+
+// Azimuthal angle between two three-vectors around a third.
+
+double phi(const Vec4& v1, const Vec4& v2, const Vec4& n) {
+ double nx = n.xx; double ny = n.yy; double nz = n.zz;
+ double norm = 1. / sqrt(nx*nx + ny*ny + nz*nz);
+ nx *= norm; ny *=norm; nz *=norm;
+ double v1s = v1.xx * v1.xx + v1.yy * v1.yy + v1.zz * v1.zz;
+ double v2s = v2.xx * v2.xx + v2.yy * v2.yy + v2.zz * v2.zz;
+ double v1v2 = v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz;
+ double v1n = v1.xx * nx + v1.yy * ny + v1.zz * nz;
+ double v2n = v2.xx * nx + v2.yy * ny + v2.zz * nz;
+ double cphi = (v1v2 - v1n * v2n) / sqrt( max( Vec4::TINY,
+ (v1s - v1n*v1n) * (v2s - v2n*v2n) ));
+ cphi = max(-1., min(1., cphi));
+ return acos(cphi);
+}
+
+//*********
+
+// Cosine of the azimuthal angle between two three-vectors around a third.
+
+double cosphi(const Vec4& v1, const Vec4& v2, const Vec4& n) {
+ double nx = n.xx; double ny = n.yy; double nz = n.zz;
+ double norm = 1. / sqrt(nx*nx + ny*ny + nz*nz);
+ nx *= norm; ny *=norm; nz *=norm;
+ double v1s = v1.xx * v1.xx + v1.yy * v1.yy + v1.zz * v1.zz;
+ double v2s = v2.xx * v2.xx + v2.yy * v2.yy + v2.zz * v2.zz;
+ double v1v2 = v1.xx * v2.xx + v1.yy * v2.yy + v1.zz * v2.zz;
+ double v1n = v1.xx * nx + v1.yy * ny + v1.zz * nz;
+ double v2n = v2.xx * nx + v2.yy * ny + v2.zz * nz;
+ double cphi = (v1v2 - v1n * v2n) / sqrt( max( Vec4::TINY,
+ (v1s - v1n*v1n) * (v2s - v2n*v2n) ));
+ cphi = max(-1., min(1., cphi));
+ return cphi;
+}
+
+//*********
+
+// Print a four-vector: also operator overloading with friend.
+
+ostream& operator<<(ostream& os, const Vec4& v) {
+ os << fixed << setprecision(3) << setw(10) << v.xx << setw(10) << v.yy
+ << setw(10) << v.zz << setw(10) << v.tt << "\n";
+ return os;
+}
+
+//**************************************************************************
+
+// RotBstMatrix class.
+// This class implements 4 * 4 matrices that encode an arbitrary combination
+// of rotations and boosts, that can be applied to Vec4 four-vectors.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Small number to avoid division by zero.
+const double RotBstMatrix::TINY = 1e-20;
+
+//*********
+
+// Rotate by polar angle theta and azimuthal angle phi.
+
+void RotBstMatrix::rot(double theta, double phi) {
+
+ // Set up rotation matrix.
+ double cthe = cos(theta); double sthe = sin(theta);
+ double cphi = cos(phi); double sphi = sin(phi);
+ double Mrot[4][4] = {
+ {1., 0., 0., 0.},
+ {0., cthe * cphi, - sphi, sthe * cphi},
+ {0., cthe * sphi, cphi, sthe * sphi},
+ {0., -sthe, 0., cthe } };
+
+ // Rotate current matrix accordingly.
+ double Mtmp[4][4];
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ Mtmp[i][j] = M[i][j];
+ }
+ }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ M[i][j] = Mrot[i][0] * Mtmp[0][j] + Mrot[i][1] * Mtmp[1][j]
+ + Mrot[i][2] * Mtmp[2][j] + Mrot[i][3] * Mtmp[3][j];
+ }
+ }
+
+}
+
+//*********
+
+// Rotate so that vector originally along z axis becomes parallel with p.
+
+void RotBstMatrix::rot(const Vec4& p) {
+
+ double theta = p.theta();
+ double phi = p.phi();
+ rot(0., -phi);
+ rot(theta, phi);
+
+}
+
+//*********
+
+// Boost with velocity vector (betaX, betaY, betaZ).
+
+void RotBstMatrix::bst(double betaX, double betaY, double betaZ) {
+
+ // Set up boost matrix.
+ double gm = 1. / sqrt( max( TINY, 1. - betaX*betaX - betaY*betaY
+ - betaZ*betaZ ) );
+ double gf = gm*gm / (1. + gm);
+ double Mbst[4][4] = {
+ { gm, gm*betaX, gm*betaY, gm*betaZ },
+ { gm*betaX, 1. + gf*betaX*betaX, gf*betaX*betaY, gf*betaX*betaZ },
+ { gm*betaY, gf*betaY*betaX, 1. + gf*betaY*betaY, gf*betaY*betaZ },
+ { gm*betaZ, gf*betaZ*betaX, gf*betaZ*betaY, 1. + gf*betaZ*betaZ } };
+
+ // Boost current matrix correspondingly.
+ double Mtmp[4][4];
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ Mtmp[i][j] = M[i][j];
+ }
+ }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ M[i][j] = Mbst[i][0] * Mtmp[0][j] + Mbst[i][1] * Mtmp[1][j]
+ + Mbst[i][2] * Mtmp[2][j] + Mbst[i][3] * Mtmp[3][j];
+ }
+ }
+
+}
+
+//*********
+
+// Boost so that vector originally at rest obtains same velocity as p.
+
+void RotBstMatrix::bst(const Vec4& p) {
+ double betaX = p.px() / p.e();
+ double betaY = p.py() / p.e();
+ double betaZ = p.pz() / p.e();
+ bst(betaX, betaY, betaZ);
+}
+
+//*********
+
+// Boost so vector originally with same velocity as p is brought to rest.
+
+void RotBstMatrix::bstback(const Vec4& p) {
+ double betaX = -p.px() / p.e();
+ double betaY = -p.py() / p.e();
+ double betaZ = -p.pz() / p.e();
+ bst(betaX, betaY, betaZ);
+}
+
+//*********
+
+// Boost that transforms p1 to p2, where p1^2 = p2^2 is assumed.
+
+void RotBstMatrix::bst(const Vec4& p1, const Vec4& p2) {
+ double eSum = p1.e() + p2.e();
+ double betaX = (p2.px() - p1.px()) / eSum;
+ double betaY = (p2.py() - p1.py()) / eSum;
+ double betaZ = (p2.pz() - p1.pz()) / eSum;
+ double fac = 2. / (1. + betaX*betaX + betaY*betaY + betaZ*betaZ);
+ betaX *= fac; betaY *= fac; betaZ *= fac;
+ bst(betaX, betaY, betaZ);
+}
+
+//*********
+
+// Boost and rotation that transforms from p1 and p2
+// to their rest frame with p1 along +z axis.
+
+void RotBstMatrix::toCMframe(const Vec4& p1, const Vec4& p2) {
+ Vec4 pSum = p1 + p2;
+ Vec4 dir = p1;
+ dir.bstback(pSum);
+ double theta = dir.theta();
+ double phi = dir.phi();
+ bstback(pSum);
+ rot(0., -phi);
+ rot(-theta, phi);
+}
+
+//*********
+
+// Rotation and boost that transforms from rest frame of p1 and p2
+// with p1 along +z axis to actual frame of p1 and p2. (Inverse of above.)
+
+void RotBstMatrix::fromCMframe(const Vec4& p1, const Vec4& p2) {
+ Vec4 pSum = p1 + p2;
+ Vec4 dir = p1;
+ dir.bstback(pSum);
+ double theta = dir.theta();
+ double phi = dir.phi();
+ rot(0., -phi);
+ rot(theta, phi);
+ bst(pSum);
+}
+
+//*********
+
+// Combine existing rotation/boost matrix with another one.
+
+void RotBstMatrix::rotbst(const RotBstMatrix& Mrb) {
+ double Mtmp[4][4];
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ Mtmp[i][j] = M[i][j];
+ }
+ }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ M[i][j] = Mrb.M[i][0] * Mtmp[0][j] + Mrb.M[i][1] * Mtmp[1][j]
+ + Mrb.M[i][2] * Mtmp[2][j] + Mrb.M[i][3] * Mtmp[3][j];
+ }
+ }
+}
+
+//*********
+
+// Invert the rotation and boost.
+
+void RotBstMatrix::invert() {
+ double Mtmp[4][4];
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ Mtmp[i][j] = M[i][j];
+ }
+ }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ M[i][j] = ( (i == 0 && j > 0) || (i > 0 && j == 0) )
+ ? - Mtmp[j][i] : Mtmp[j][i];
+ }
+ }
+}
+
+//*********
+
+// Reset to diagonal matrix.
+
+void RotBstMatrix::reset() {
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ M[i][j] = (i==j) ? 1. : 0.;
+ }
+ }
+}
+
+//*********
+
+// Crude estimate deviation from unit matrix.
+
+double RotBstMatrix::deviation() const {
+ double devSum = 0.;
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ devSum += (i==j) ? abs(M[i][j] - 1.) : abs(M[i][j]);
+ }
+ }
+ return devSum;
+}
+
+//*********
+
+// Print a rotation and boost matrix: operator overloading with friend.
+
+ostream& operator<<(ostream& os, const RotBstMatrix& M) {
+ os << fixed << setprecision(5) << " Rotation/boost matrix: \n";
+ for (int i = 0; i <4; ++i) {
+ os << setw(10) << M.M[i][0] << setw(10) << M.M[i][1]
+ << setw(10) << M.M[i][2] << setw(10) << M.M[i][3] << "\n";
+ }
+ return os;
+}
+
+//**************************************************************************
+
+// Hist class.
+// This class handles a single histogram at a time
+// (or a vector of histograms).
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maximum number of bins in a histogram.
+const int Hist::NBINMAX = 100;
+
+// Maximum number of lines a histogram can use at output.
+const int Hist::NLINES = 30;
+
+// Tolerance in deviation of xMin and xMax between two histograms.
+const double Hist::TOLERANCE = 0.001;
+
+// Small number to avoid division by zero.
+const double Hist::TINY = 1e-20;
+
+// When minbin/maxbin < SMALLFRAC the y scale goes down to zero.
+const double Hist::SMALLFRAC = 0.1;
+
+// Constants for printout: fixed steps on y scale; filling characters.
+const double DYAC[] = {0.04, 0.05, 0.06, 0.08, 0.10,
+ 0.12, 0.15, 0.20, 0.25, 0.30};
+const char NUMBER[] = {'0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'X' };
+
+//*********
+
+// Book a histogram.
+
+void Hist::book(string titleIn, int nBinIn, double xMinIn,
+ double xMaxIn) {
+
+ title = titleIn;
+ nBin = nBinIn;
+ if (nBinIn < 1) nBin = 1;
+ if (nBinIn > NBINMAX) nBin = NBINMAX;
+ xMin = xMinIn;
+ xMax = xMaxIn;
+ dx = (xMax - xMin)/nBin;
+ res.resize(nBin);
+ null();
+
+}
+
+//*********
+
+// Reset bin contents.
+
+void Hist::null() {
+
+ nFill = 0;
+ under = 0.;
+ inside = 0.;
+ over = 0.;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] = 0.;}
+
+}
+
+//*********
+
+// Fill bin with weight.
+
+void Hist::fill(double x, double w) {
+
+ ++nFill;
+ int iBin = int(floor((x - xMin)/dx));
+ if (iBin < 0) {under += w; }
+ else if (iBin >= nBin) {over += w; }
+ else {inside += w; res[iBin] += w; }
+
+}
+
+//*********
+
+// Get content of specific bin.
+// Special values are bin 0 for underflow and bin nBin+1 for overflow.
+// All other bins outside proper histogram range return 0.
+
+double Hist::getBinContent(int iBin) {
+
+ if (iBin > 0 && iBin <= nBin) return res[iBin - 1];
+ else if (iBin == 0) return under;
+ else if (iBin == nBin + 1) return over;
+ else return 0.;
+
+}
+
+//*********
+
+// Print histogram contents as a table (e.g. for Gnuplot).
+
+void Hist::table(ostream& os) const {
+
+ // Print histogram vector bin by bin, with mean x as first column.
+ os << scientific << setprecision(4);
+ for (int ix = 0; ix < nBin; ++ix) {
+ os << setw(12) << xMin + (ix + 0.5) * dx
+ << setw(12) << res[ix] << "\n";
+
+ }
+}
+
+//*********
+
+// Check whether another histogram has same size and limits.
+
+bool Hist::sameSize(const Hist& h) const {
+
+ if (nBin == h.nBin && abs(xMin - h.xMin) < TOLERANCE * dx &&
+ abs(xMax - h.xMax) < TOLERANCE * dx) {return true;}
+ else {return false;}
+
+}
+
+//*********
+
+// Take 10-logarithm or natural logarithm of contents bin by bin.
+
+void Hist::takeLog(bool tenLog) {
+
+ // Find smallest positive bin content, and put min a bit below.
+ double yMin = 1e20;
+ for (int ix = 0; ix < nBin; ++ix)
+ if (res[ix] > 1e-20 && res[ix] < yMin ) yMin = res[ix];
+ yMin *= 0.8;
+
+ // Take 10-logarithm bin by bin, but ensure positivity.
+ if (tenLog) {
+ for (int ix = 0; ix < nBin; ++ix) res[ix] = log10( max( yMin, res[ix]) );
+ under = log10( max( yMin, under) );
+ inside = log10( max( yMin, inside) );
+ over = log10( max( yMin, over) );
+
+ // Take natural logarithm bin by bin, but ensure positivity.
+ } else {
+ for (int ix = 0; ix < nBin; ++ix) res[ix] = log( max( yMin, res[ix]) );
+ under = log( max( yMin, under) );
+ inside = log( max( yMin, inside) );
+ over = log( max( yMin, over) );
+ }
+
+}
+
+//*********
+
+// Add histogram to existing one.
+
+Hist& Hist::operator+=(const Hist& h) {
+ if (!sameSize(h)) return *this;
+ nFill += h.nFill;
+ under += h.under;
+ inside += h.inside;
+ over += h.over;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] += h.res[ix];}
+ return *this;
+}
+
+//*********
+
+// Subtract histogram from existing one.
+
+Hist& Hist::operator-=(const Hist& h) {
+ if (!sameSize(h)) return *this;
+ nFill += h.nFill;
+ under -= h.under;
+ inside -= h.inside;
+ over -= h.over;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] -= h.res[ix];}
+ return *this;
+}
+
+//*********
+
+// Multiply existing histogram by another one.
+
+Hist& Hist::operator*=(const Hist& h) {
+ if (!sameSize(h)) return *this;
+ nFill += h.nFill;
+ under *= h.under;
+ inside *= h.inside;
+ over *= h.over;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] *= h.res[ix];}
+ return *this;
+}
+
+//*********
+
+// Divide existing histogram by another one.
+
+Hist& Hist::operator/=(const Hist& h) {
+ if (!sameSize(h)) return *this;
+ nFill += h.nFill;
+ under = (abs(h.under) < Hist::TINY) ? 0. : under/h.under;
+ inside = (abs(h.inside) < Hist::TINY) ? 0. : inside/h.inside;
+ over = (abs(h.over) < Hist::TINY) ? 0. : over/h.over;
+ for (int ix = 0; ix < nBin; ++ix) {
+ res[ix] = (abs(h.res[ix]) < Hist::TINY) ? 0. : res[ix]/h.res[ix];
+ }
+ return *this;
+}
+
+//*********
+
+// Add constant offset to histogram.
+
+Hist& Hist::operator+=(double f) {
+ under += f;
+ inside += nBin * f;
+ over -= f;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] += f;}
+ return *this;
+}
+
+//*********
+
+// Subtract constant offset from histogram.
+
+Hist& Hist::operator-=(double f) {
+ under -= f;
+ inside -= nBin * f;
+ over -= f;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] -= f;}
+ return *this;
+}
+
+//*********
+
+// Multiply histogram by constant
+
+Hist& Hist::operator*=(double f) {
+ under *= f;
+ inside *= f;
+ over *= f;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] *= f;}
+ return *this;
+}
+
+//*********
+
+// Divide histogram by constant
+
+Hist& Hist::operator/=(double f) {
+ under /= f;
+ inside /= f;
+ over /= f;
+ for (int ix = 0; ix < nBin; ++ix) {res[ix] /= f;}
+ return *this;
+}
+
+//*********
+
+// Implementation of operator overloading with friends.
+
+Hist operator+(double f, const Hist& h1)
+ {Hist h = h1; return h += f;}
+
+Hist operator+(const Hist& h1, double f)
+ {Hist h = h1; return h += f;}
+
+Hist operator+(const Hist& h1, const Hist& h2)
+ {Hist h = h1; return h += h2;}
+
+Hist operator-(double f, const Hist& h1)
+ {Hist h = h1;
+ h.under = f - h1.under;
+ h.inside = h1.nBin * f - h1.inside;
+ h.over = f - h1.over;
+ for (int ix = 0; ix < h1.nBin; ++ix) {h.res[ix] = f - h1.res[ix];}
+ return h;}
+
+Hist operator-(const Hist& h1, double f)
+ {Hist h = h1; return h -= f;}
+
+Hist operator-(const Hist& h1, const Hist& h2)
+ {Hist h = h1; return h -= h2;}
+
+Hist operator*(double f, const Hist& h1)
+ {Hist h = h1; return h *= f;}
+
+Hist operator*(const Hist& h1, double f)
+ {Hist h = h1; return h *= f;}
+
+Hist operator*(const Hist& h1, const Hist& h2)
+ {Hist h = h1; return h *= h2;}
+
+Hist operator/(double f, const Hist& h1) {Hist h = h1;
+ h.under = (abs(h1.under) < Hist::TINY) ? 0. : f/h1.under;
+ h.inside = (abs(h1.inside) < Hist::TINY) ? 0. : f/h1.inside;
+ h.over = (abs(h1.over) < Hist::TINY) ? 0. : f/h1.over;
+ for (int ix = 0; ix < h1.nBin; ++ix) {
+ h.res[ix] = (abs(h1.res[ix]) < Hist::TINY) ? 0. : f/h1.res[ix];
+ }
+ return h;
+}
+
+Hist operator/(const Hist& h1, double f)
+ {Hist h = h1; return h /= f;}
+
+Hist operator/(const Hist& h1, const Hist& h2)
+ {Hist h = h1; return h /= h2;}
+
+//*********
+
+// Print a histogram: also operator overloading with friend.
+
+ostream& operator<<(ostream& os, const Hist& h) {
+
+ // Do not print empty histograms.
+ if (h.nFill <= 0) return os;
+
+ // Write time and title.
+ time_t t = time(0);
+ char date[18];
+ strftime(date,18,"%Y-%m-%d %H:%M",localtime(&t));
+ os << "\n\n " << date << " " << h.title << "\n\n";
+
+ // Find minimum and maximum bin content
+ double yMin = h.res[0];
+ double yMax = h.res[0];
+ for (int i = 1; i < h.nBin; ++i) {
+ if (h.res[i] < yMin) yMin = h.res[i];
+ if (h.res[i] > yMax) yMax = h.res[i];
+ }
+
+ // Determine scale and step size for y axis.
+ if (yMax - yMin > Hist::NLINES * DYAC[0] * 1e-9) {
+ if (yMin > 0. && yMin < Hist::SMALLFRAC * yMax) yMin = 0.;
+ if (yMax < 0. && yMax > Hist::SMALLFRAC * yMin) yMax = 0.;
+ int iPowY = int(floor( log10(yMax - yMin) ));
+ if (yMax - yMin < Hist::NLINES * DYAC[0] * pow(10.,iPowY))
+ iPowY = iPowY - 1;
+ if (yMax - yMin > Hist::NLINES * DYAC[9] * pow(10.,iPowY))
+ iPowY = iPowY + 1;
+ double nLinePow = Hist::NLINES * pow(10.,iPowY);
+ double delY = DYAC[0];
+ for (int idel = 0; idel < 9; ++idel) {
+ if (yMax - yMin >= nLinePow * DYAC[idel]) delY = DYAC[idel+1];
+ }
+ double dy = delY * pow(10.,iPowY);
+
+ // Convert bin contents to integer form; fractional fill in top row.
+ vector<int> row(h.nBin);
+ vector<int> frac(h.nBin);
+ for (int ix = 0; ix < h.nBin ; ++ix) {
+ double cta = abs(h.res[ix]) / dy;
+ row[ix] = int(cta + 0.95);
+ if(h.res[ix] < 0.) row[ix] = - row[ix];
+ frac[ix] = int(10. * (cta + 1.05 - floor(cta + 0.95)));
+ }
+ int rowMin = int(abs(yMin)/dy + 0.95);
+ if ( yMin < 0) rowMin = - rowMin;
+ int rowMax = int(abs(yMax)/dy + 0.95);
+ if ( yMax < 0) rowMax = - rowMax;
+
+ // Print histogram row by row.
+ os << fixed << setprecision(2);
+ for (int iRow = rowMax; iRow >= rowMin; iRow--) {
+ if (iRow != 0) {
+ os << " " << setw(10) << iRow*delY << "*10^"
+ << setw(2) << iPowY << " ";
+ for (int ix = 0; ix < h.nBin ; ++ix) {
+ if (iRow == row[ix]) {os << NUMBER[frac[ix]];}
+ else if (iRow * (row[ix] - iRow) > 0) {os << NUMBER[10];}
+ else {os << " ";}
+ } os << "\n";
+ }
+ } os << "\n";
+
+ // Print sign and value of bin contents
+ double maxim = log10(max(yMax, -yMin));
+ int iPowBin = int(floor(maxim + 0.0001));
+ os << " Contents ";
+ for (int ix = 0; ix < h.nBin ; ++ix) {
+ if (h.res[ix] < - pow(10., iPowBin-4)) {os << "-";}
+ else {os << " ";}
+ row[ix] = int(abs(h.res[ix]) * pow(10.,3-iPowBin) + 0.5);
+ } os << "\n";
+ for (int iRow = 3; iRow >= 0; iRow--) {
+ os << " *10^" << setw(2) << iPowBin+iRow-3 << " ";
+ int mask = int( pow(10., iRow) + 0.5);
+ for (int ix = 0; ix < h.nBin ; ++ix) {
+ os << NUMBER[(row[ix] / mask) % 10];
+ } os << "\n";
+ } os << "\n";
+
+ // Print sign and value of lower bin edge.
+ maxim = log10(max(-h.xMin, h.xMax - h.dx));
+ int iPowExp = int(floor(maxim + 0.0001));
+ os << " Low edge ";
+ for (int ix = 0; ix < h.nBin ; ++ix) {
+ if (h.xMin + ix * h.dx < - pow(10., iPowExp-3)) {os << "-";}
+ else {os << " ";}
+ row[ix] = int(abs(h.xMin + ix * h.dx) * pow(10.,2-iPowExp) + 0.5);
+ } os << "\n";
+ for (int iRow = 2; iRow >= 0; iRow--) {
+ os << " *10^" << setw(2) << iPowExp+iRow-2 << " ";
+ int mask = int( pow(10., iRow) + 0.5);
+ for (int ix = 0; ix < h.nBin ; ++ix) {
+ os << NUMBER[(row[ix] / mask) % 10];
+ } os << "\n";
+ } os << "\n";
+ }
+
+ // Calculate and print statistics.
+ double cSum = 0.;
+ double cxSum = 0.;
+ double cxxSum = 0.;
+ for (int ix = 0; ix < h.nBin ; ++ix) {
+ double cta = abs(h.res[ix]);
+ double x = h.xMin + (ix + 0.5) * h.dx;
+ cSum = cSum + cta;
+ cxSum = cxSum + cta * x;
+ cxxSum = cxxSum + cta * x * x;
+ }
+ double xmean = cxSum / max(cSum, Hist::TINY);
+ double rms = sqrtpos( cxxSum / max(cSum, Hist::TINY) - xmean*xmean );
+ os << scientific << setprecision(4)
+ << " Entries =" << setw(12) << h.nFill
+ << " Mean =" << setw(12) << xmean
+ << " Underflow =" << setw(12) << h.under
+ << " Low edge =" << setw(12) << h.xMin << "\n"
+ << " All chan =" << setw(12) << h.inside
+ << " Rms =" << setw(12) << rms
+ << " Overflow =" << setw(12) << h.over
+ << " High edge =" << setw(12) << h.xMax << endl;
+ return os;
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// BeamParticle.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// BeamParticle class.
+
+#include "BeamParticle.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The BeamParticle class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// A lepton that takes (almost) the full beam energy does not leave a remnant.
+const double BeamParticle::XMINUNRESOLVED = 1. - 1e-10;
+
+//*********
+
+// Initialize data on a beam particle and save pointers.
+
+void BeamParticle::init( int idIn, double pzIn, double eIn, double mIn,
+ Info* infoPtrIn, PDF* pdfInPtr, PDF* pdfHardInPtr,
+ bool isUnresolvedIn, StringFlav* flavSelPtrIn) {
+
+ // Store input pointers (and one bool) for future use.
+ infoPtr = infoPtrIn;
+ pdfBeamPtr = pdfInPtr;
+ pdfHardBeamPtr = pdfHardInPtr;
+ isUnresolvedBeam = isUnresolvedIn;
+ flavSelPtr = flavSelPtrIn;
+
+ // Maximum quark kind in allowed incoming beam hadrons.
+ maxValQuark = Settings::mode("BeamRemnants:maxValQuark");
+
+ // Power of (1-x)^power/sqrt(x) for remnant valence quark distribution.
+ valencePowerMeson = Settings::parm("BeamRemnants:valencePowerMeson");
+ valencePowerUinP = Settings::parm("BeamRemnants:valencePowerUinP");
+ valencePowerDinP = Settings::parm("BeamRemnants:valencePowerDinP");
+
+ // Enhancement factor of x of diquark.
+ valenceDiqEnhance = Settings::parm("BeamRemnants:valenceDiqEnhance");
+
+ // Assume g(x) ~ (1-x)^power/x to constrain companion to sea quark.
+ companionPower = Settings::mode("BeamRemnants:companionPower");
+
+ // Assume g(x) ~ (1-x)^power/x to constrain companion to sea quark.
+ companionPower = Settings::mode("BeamRemnants:companionPower");
+
+ // Allow or not more than one valence quark to be kicked out.
+ allowJunction = Settings::flag("BeamRemnants:allowJunction");
+
+ // For diffractive system kick out q/g = norm / mass^power.
+ pickQuarkNorm = Settings::parm("BeamRemnants:pickQuarkNorm");
+ pickQuarkPower = Settings::parm("BeamRemnants:pickQuarkPower");
+
+ // Width of primordial kT distribution in diffractive systems.
+ diffPrimKTwidth = Settings::parm("BeamRemnants:diffPrimKTwidth");
+
+ // Suppress large masses of beam remnant in diffractive systems.
+ diffLargeMassSuppress = Settings::parm("BeamRemnants:diffLargeMassSuppress");
+
+ // Store info on the incoming beam.
+ idBeam = idIn;
+ initBeamKind();
+ pBeam = Vec4( 0., 0., pzIn, eIn);
+ mBeam = mIn;
+
+}
+
+//*********
+
+// Initialize kind and valence flavour content of incoming beam.
+// For recognized hadrons one can generate multiple interactions.
+// So far we do not handle diagonal mesons or K0S/K0L (or photons),
+// for which flavour content is only known after first interaction.
+
+void BeamParticle::initBeamKind() {
+
+ // Reset.
+ idBeamAbs = abs(idBeam);
+ isLeptonBeam = false;
+ isHadronBeam = false;
+ isMesonBeam = false;
+ isBaryonBeam = false;
+ nValKinds = 0;
+
+ // Check for leptons.
+ if (idBeamAbs > 10 && idBeamAbs < 17) {
+ nValKinds = 1;
+ nVal[0] = 1;
+ idVal[0] = idBeam;
+ isLeptonBeam = true;
+ }
+
+ // Done if cannot be lowest-lying hadron state.
+ if (idBeamAbs < 101 || idBeamAbs > 9999) return;
+
+ // Resolve valence content for assumed meson. Flunk unallowed codes.
+ if (idBeamAbs < 1000) {
+ int id1 = idBeamAbs/100;
+ int id2 = (idBeamAbs/10)%10;
+ if ( id1 < 1 || id1 > maxValQuark
+ || id2 < 1 || id2 > maxValQuark ) return;
+ if (id2 == id1 || idBeamAbs == 130 || idBeamAbs == 310) return;
+ isMesonBeam = true;
+
+ // Store valence content of a confirmed meson.
+ nValKinds = 2;
+ nVal[0] = 1 ;
+ nVal[1] = 1;
+ if (id1%2 == 0) {
+ idVal[0] = id1;
+ idVal[1] = -id2;
+ } else {
+ idVal[0] = id2;
+ idVal[1] = -id1;
+ }
+
+ // Resolve valence content for assumed baryon. Flunk unallowed codes.
+ } else {
+ int id1 = idBeamAbs/1000;
+ int id2 = (idBeamAbs/100)%10;
+ int id3 = (idBeamAbs/10)%10;
+ if ( id1 < 1 || id1 > maxValQuark || id2 < 1 || id2 > maxValQuark
+ || id3 < 1 || id3 > maxValQuark) return;
+ if (id2 > id1 || id3 > id1) return;
+ isBaryonBeam = true;
+
+ // Store valence content of a confirmed baryon.
+ nValKinds = 1; idVal[0] = id1; nVal[0] = 1;
+ if (id2 == id1) ++nVal[0];
+ else {
+ nValKinds = 2;
+ idVal[1] = id2;
+ nVal[1] = 1;
+ }
+ if (id3 == id1) ++nVal[0];
+ else if (id3 == id2) ++nVal[1];
+ else {
+ idVal[nValKinds] = id3;
+ nVal[nValKinds] = 1;
+ ++nValKinds;
+ }
+ }
+
+ // Flip flavours for antimeson or antibaryon, and then done.
+ if (idBeam < 0) for (int i = 0; i < nValKinds; ++i) idVal[i] = -idVal[i];
+ isHadronBeam = true;
+ Q2ValFracSav = -1.;
+
+}
+
+//*********
+
+double BeamParticle::xMax(int iSkip) {
+
+ // Minimum requirement on remaining energy > nominal mass for hadron.
+ double xLeft = 1.;
+ if (isHadron()) xLeft -= m() / e();
+ if (size() == 0) return xLeft;
+
+ // Subtract what was carried away by initiators (to date).
+ for (int i = 0; i < size(); ++i)
+ if (i != iSkip) xLeft -= resolved[i].x();
+ return xLeft;
+
+}
+
+//*********
+
+// Parton distributions, reshaped to take into account previous
+// multiple interactions. By picking a non-negative iSkip value,
+// one particular interaction is skipped, as needed for ISR
+
+double BeamParticle::xfModified(int iSkip, int idIn, double x, double Q2) {
+
+ // Initial values.
+ idSave = idIn;
+ iSkipSave = iSkip;
+ xqVal = 0.;
+ xqgSea = 0.;
+ xqCompSum = 0.;
+
+ // Fast procedure for first interaction.
+ if (size() == 0) {
+ if (x >= 1.) return 0.;
+ bool canBeVal = false;
+ for (int i = 0; i < nValKinds; ++i)
+ if (idIn == idVal[i]) canBeVal = true;
+ if (canBeVal) {
+ xqVal = xfVal( idIn, x, Q2);
+ xqgSea = xfSea( idIn, x, Q2);
+ }
+ else xqgSea = xf( idIn, x, Q2);
+
+ // More complicated procedure for non-first interaction.
+ } else {
+
+ // Sum up the x already removed, and check that remaining x is enough.
+ double xUsed = 0.;
+ for (int i = 0; i < size(); ++i)
+ if (i != iSkip) xUsed += resolved[i].x();
+ double xLeft = 1. - xUsed;
+ if (x >= xLeft) return 0.;
+ double xRescaled = x / xLeft;
+
+ // Calculate total and remaining amount of x carried by valence quarks.
+ double xValTot = 0.;
+ double xValLeft = 0.;
+ for (int i = 0; i < nValKinds; ++i) {
+ nValLeft[i] = nVal[i];
+ for (int j = 0; j < size(); ++j)
+ if (j != iSkip && resolved[j].isValence()
+ && resolved[j].id() == idVal[i]) --nValLeft[i];
+ double xValNow = xValFrac(i, Q2);
+ xValTot += nVal[i] * xValNow;
+ xValLeft += nValLeft[i] * xValNow;
+ }
+
+ // Calculate total amount of x carried by unmatched companion quarks.
+ double xCompAdded = 0.;
+ for (int i = 0; i < size(); ++i)
+ if (i != iSkip && resolved[i].isUnmatched()) xCompAdded
+ += xCompFrac( resolved[i].x() / (xLeft + resolved[i].x()) )
+ // Typo warning: extrafactor missing in Skands&Sjostrand article;
+ // <x> for companion refers to fraction of x left INCLUDING sea quark.
+ // To be modified further??
+ * (1. + resolved[i].x() / xLeft);
+
+ // Calculate total rescaling factor and pdf for sea and gluon.
+ double rescaleGS = max( 0., (1. - xValLeft - xCompAdded)
+ / (1. - xValTot) );
+ xqgSea = rescaleGS * xfSea( idIn, xRescaled, Q2);
+
+ // Find valence part and rescale it to remaining number of quarks.
+ for (int i = 0; i < nValKinds; ++i)
+ if (idIn == idVal[i] && nValLeft[i] > 0)
+ xqVal = xfVal( idIn, xRescaled, Q2)
+ * double(nValLeft[i]) / double(nVal[i]);
+
+ // Find companion part, by adding all companion contributions.
+ for (int i = 0; i < size(); ++i)
+ if (i != iSkip && resolved[i].id() == -idIn
+ && resolved[i].isUnmatched()) {
+ double xsRescaled = resolved[i].x() / (xLeft + resolved[i].x());
+ double xcRescaled = x / (xLeft + resolved[i].x());
+ double xqCompNow = xCompDist( xcRescaled, xsRescaled);
+ resolved[i].xqCompanion( xqCompNow);
+ xqCompSum += xqCompNow;
+ }
+ }
+
+ // Add total, but only return relevant part for ISR. More cases??
+ // Watch out, e.g. g can come from either kind of quark.??
+ xqgTot = xqVal + xqgSea + xqCompSum;
+ if (iSkip >= 0) {
+ if (resolved[iSkip].isValence()) return xqVal;
+ if (resolved[iSkip].isUnmatched()) return xqgSea + xqCompSum;
+ }
+ return xqgTot;
+
+}
+
+//*********
+
+// Decide whether a quark extracted from the beam is of valence, sea or
+// companion kind; in the latter case also pick its companion.
+// Assumes xfModified has already been called.
+
+ int BeamParticle::pickValSeaComp() {
+
+ // If parton already has a companion than reset code for this.
+ int oldCompanion = resolved[iSkipSave].companion();
+ if (oldCompanion >= 0) resolved[oldCompanion].companion(-2);
+
+ // Default assignment is sea.
+ int vsc = -2;
+
+ // For gluons or photons no sense of valence or sea.
+ if (idSave == 21 || idSave == 22) vsc = -1;
+
+ // For lepton beam assume same-kind lepton inside is valence.
+ else if (isLeptonBeam && idSave == idBeam) vsc = -3;
+
+ // Decide if valence or sea quark.
+ else {
+ double xqRndm = xqgTot * Rndm::flat();
+ if (xqRndm < xqVal) vsc = -3;
+ else if (xqRndm < xqVal + xqgSea) vsc = -2;
+
+ // If not either, loop over all possible companion quarks.
+ else {
+ xqRndm -= xqVal + xqgSea;
+ for (int i = 0; i < size(); ++i)
+ if (i != iSkipSave && resolved[i].id() == -idSave
+ && resolved[i].isUnmatched()) {
+ xqRndm -= resolved[i].xqCompanion();
+ if (xqRndm < 0.) vsc = i;
+ break;
+ }
+ }
+ }
+
+ // Bookkeep assignment; for sea--companion pair both ways.
+ resolved[iSkipSave].companion(vsc);
+ if (vsc >= 0) resolved[vsc].companion(iSkipSave);
+
+ // Done; return code for choice (to distinguish valence/sea in Info).
+ return vsc;
+
+}
+
+//*********
+
+// Fraction of hadron momentum sitting in a valence quark distribution.
+// Based on hardcoded parametrizations of CTEQ 5L numbers.
+
+double BeamParticle::xValFrac(int j, double Q2) {
+
+ // Only recalculate when required.
+ if (Q2 != Q2ValFracSav) {
+ Q2ValFracSav = Q2;
+
+ // Q2-dependence of log-log form; assume fixed Lambda = 0.2.
+ double llQ2 = log( log( max( 1., Q2) / 0.04 ));
+
+ // Fractions carried by u and d in proton.
+ uValInt = 0.48 / (1. + 1.56 * llQ2);
+ dValInt = 0.385 / (1. + 1.60 * llQ2);
+ }
+
+ // Baryon with three different quark kinds: (2 * u + d) / 3 of proton.
+ if (isBaryonBeam && nValKinds == 3) return (2. * uValInt + dValInt) / 3.;
+
+ // Baryon with one or two identical: like d or u of proton.
+ if (isBaryonBeam && nVal[j] == 1) return dValInt;
+ if (isBaryonBeam && nVal[j] == 2) return uValInt;
+
+ // Meson: (2 * u + d) / 2 of proton so same total valence quark fraction.
+ return 0.5 * (2. * uValInt + dValInt);
+
+}
+
+//*********
+
+// The momentum integral of a companion quark, with its partner at x_s,
+// using an approximate gluon density like (1 - x_g)^power / x_g.
+// The value corresponds to an unrescaled range between 0 and 1 - x_s.
+
+double BeamParticle::xCompFrac(double xs) {
+
+ // Select case by power of gluon (1-x_g) shape.
+ switch (companionPower) {
+
+ case 0:
+ return xs * ( 5. + xs * (-9. - 2. * xs * (-3. + xs)) + 3. * log(xs) )
+ / ( (-1. + xs) * (2. + xs * (-1. + 2. * xs)) );
+
+ case 1:
+ return -1. -3. * xs + ( 2. * pow2(-1. + xs) * (1. + xs + xs*xs))
+ / ( 2. + xs*xs * (xs - 3.) + 3. * xs * log(xs) );
+
+ case 2:
+ return xs * ( (1. - xs) * (19. + xs * (43. + 4. * xs))
+ + 6. * log(xs) * (1. + 6. * xs + 4.*xs*xs) ) /
+ ( 4. * ( (xs - 1.) * (1. + xs * (4. + xs) )
+ - 3. * xs * log(xs) * (1 + xs) ) );
+
+ case 3:
+ return 3. * xs * ( (xs - 1.) * (7. + xs * (28. + 13. * xs))
+ - 2. * log(xs) * (1. + xs * (9. + 2. * xs * (6. + xs))) )
+ / ( 4. + 27. * xs - 31. * pow3(xs)
+ + 6. * xs * log(xs) * (3. + 2. * xs * (3.+xs)) );
+
+ default:
+ return ( -9. * xs * (xs*xs - 1.) * (5. + xs * (24. + xs)) + 12. * xs
+ * log(xs) * (1. + 2. * xs) * (1. + 2. * xs * (5. + 2. * xs)) )
+ / ( 8. * (1. + 2. * xs) * ((xs - 1.) * (1. + xs * (10. + xs))
+ - 6. * xs * log(xs) * (1. + xs)) );
+
+ }
+}
+
+//*********
+
+// The x*f pdf of a companion quark at x_c, with its sea partner at x_s,
+// using an approximate gluon density like (1 - x_g)^power / x_g.
+// The value corresponds to an unrescaled range between 0 and 1 - x_s.
+
+double BeamParticle::xCompDist(double xc, double xs) {
+
+ // Mother gluon momentum fraction. Check physical limit.
+ double xg = xc + xs;
+ if (xg > 1.) return 0.;
+
+ // Common factor, including splitting kernel and part of gluon density
+ // (and that it is x_c * f that is coded).
+ double fac = 3. * xc * xs * (xc*xc + xs*xs) / pow4(xg);
+
+ // Select case by power of gluon (1-x_g) shape.
+ switch (companionPower) {
+
+ case 0:
+ return fac / ( 2. - xs * (3. - xs * (3. - 2. * xs)) );
+
+ case 1:
+ return fac * (1. - xg) / ( 2. + xs*xs * (-3. + xs) + 3. * xs * log(xs) );
+
+ case 2:
+ return fac * pow2(1. - xg) / ( 2. * ((1. - xs) * (1. + xs * (4. + xs))
+ + 3. * xs * (1. + xs) * log(xs)) );
+
+ case 3:
+ return fac * pow3(1. - xg) * 2. / ( 4. + 27. * xs - 31. * pow3(xs)
+ + 6. * xs * log(xs) * (3. + 2. * xs * (3. + xs)) );
+
+ default:
+ return fac * pow4(1. - xg) / ( 2. * (1. + 2. * xs) * ((1. - xs)
+ * (1. + xs * (10. + xs)) + 6. * xs * log(xs) * (1. + xs)) );
+
+ }
+}
+
+//*********
+
+// Add required extra remnant flavour content. Also initial colours.
+
+bool BeamParticle::remnantFlavours(Event& event) {
+
+ // A baryon will have a junction, unless a diquark is formed later.
+ hasJunctionBeam = (isBaryon());
+
+ // Store how many hard-scattering partons were removed from beam.
+ nInit = size();
+
+ // Find remaining valence quarks.
+ for (int i = 0; i < nValKinds; ++i) {
+ nValLeft[i] = nVal[i];
+ for (int j = 0; j < nInit; ++j) if (resolved[j].isValence()
+ && resolved[j].id() == idVal[i]) --nValLeft[i];
+ // Add remaining valence quarks to record. Partly temporary values.
+ for (int k = 0; k < nValLeft[i]; ++k) append(0, idVal[i], 0., -3);
+ }
+
+ // If at least two valence quarks left in baryon remnant then form diquark.
+ int nInitPlusVal = size();
+ if (isBaryon() && nInitPlusVal - nInit >= 2) {
+
+ // If three, pick two at random to form diquark, else trivial.
+ int iQ1 = nInit;
+ int iQ2 = nInit + 1;
+ if (nInitPlusVal - nInit == 3) {
+ double pickDq = 3. * Rndm::flat();
+ if (pickDq > 1.) iQ2 = nInit + 2;
+ if (pickDq > 2.) iQ1 = nInit + 1;
+ }
+
+ // Pick spin 0 or 1 according to SU(6) wave function factors.
+ int idDq = flavSelPtr->makeDiquark( resolved[iQ1].id(),
+ resolved[iQ2].id(), idBeam);
+
+ // Overwrite with diquark flavour and remove one slot. No more junction.
+ resolved[iQ1].id(idDq);
+ if (nInitPlusVal - nInit == 3 && iQ2 == nInit + 1)
+ resolved[nInit + 1].id( resolved[nInit + 2].id() );
+ resolved.pop_back();
+ hasJunctionBeam = false;
+ }
+
+ // Find companion quarks to unmatched sea quarks.
+ for (int i = 0; i < nInit; ++i)
+ if (resolved[i].isUnmatched()) {
+
+ // Add companion quark to record; and bookkeep both ways.
+ append(0, -resolved[i].id(), 0., i);
+ resolved[i].companion(size() - 1);
+ }
+
+ // If no other remnants found, add a gluon or photon to carry momentum.
+ if (size() == nInit) {
+ int idRemnant = (isHadronBeam) ? 21 : 22;
+ append(0, idRemnant, 1., -1);
+ }
+
+ // Set initiator and remnant masses.
+ for (int i = 0; i < size(); ++i) {
+ if (i < nInit) resolved[i].m(0.);
+ else resolved[i].m( ParticleDataTable::m0( resolved[i].id() ) );
+ }
+
+ // For debug purposes: reject beams with resolved junction topology.
+ if (hasJunctionBeam && !allowJunction) return false;
+
+ // Pick initial colours for remnants.
+ for (int i = nInit; i < size(); ++i) {
+ int colType = ParticleDataTable::colType( resolved[i].id() );
+ int col = (colType == 1 || colType == 2) ? event.nextColTag() : 0;
+ int acol = (colType == -1 || colType == 2) ? event.nextColTag() : 0;
+ resolved[i].cols( col, acol);
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Correlate all initiators and remnants to make a colour singlet.
+
+bool BeamParticle::remnantColours(Event& event, vector<int>& colFrom,
+ vector<int>& colTo) {
+
+ // No colours in lepton beams so no need to do anything.
+ if (isLeptonBeam) return true;
+
+ // Copy initiator colour info from the event record to the beam.
+ for (int i = 0; i < size(); ++i) {
+ int j = resolved[i].iPos();
+ resolved[i].cols( event[j].col(), event[j].acol());
+ }
+
+ // Find number and position of valence quarks, of gluons, and
+ // of sea-companion pairs (counted as gluons) in the beam remnants.
+ // Skip gluons with same colour as anticolour.
+ vector<int> iVal;
+ vector<int> iGlu;
+ for (int i = 0; i < size(); ++i) {
+ if ( resolved[i].isValence() ) iVal.push_back(i);
+ else if ( resolved[i].isCompanion() && resolved[i].companion() > i )
+ iGlu.push_back(i);
+ else if ( resolved[i].id() == 21
+ && resolved[i].col() != resolved[i].acol() ) iGlu.push_back(i);
+ }
+
+ // Pick a valence quark to which gluons are attached.
+ // Do not resolve quarks in diquark. (More sophisticated??)
+ int iValSel= iVal[0];
+ if (iVal.size() == 2) {
+ if ( abs(resolved[iValSel].id()) > 10 ) iValSel = iVal[1];
+ } else {
+ double rndmValSel = 3. * Rndm::flat();
+ if (rndmValSel > 1.) iValSel= iVal[1];
+ if (rndmValSel > 2.) iValSel= iVal[2];
+ }
+
+ // This valence quark defines initial (anti)colour.
+ int iBeg = iValSel;
+ bool hasCol = (resolved[iBeg].col() > 0);
+ int begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
+
+ // Do random stepping through gluon/(sea+companion) list.
+ vector<int> iGluRndm;
+ for (int i = 0; i < int(iGlu.size()); ++i)
+ iGluRndm.push_back( iGlu[i] );
+ for (int iOrder = 0; iOrder < int(iGlu.size()); ++iOrder) {
+ int iRndm = int( double(iGluRndm.size()) * Rndm::flat());
+ int iGluSel = iGluRndm[iRndm];
+ iGluRndm[iRndm] = iGluRndm[iGluRndm.size() - 1];
+ iGluRndm.pop_back();
+
+ // Find matching anticolour/colour to current colour/anticolour.
+ int iEnd = iGluSel;
+ int endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
+ // Not gluon but sea+companion pair: go to other.
+ if (endCol == 0) {
+ iEnd = resolved[iEnd].companion();
+ endCol = (hasCol) ? resolved[iEnd].acol() : resolved[iEnd].col();
+ }
+
+ // Collapse this colour-anticolour pair to the lowest one.
+ if (begCol < endCol) {
+ if (hasCol) resolved[iEnd].acol(begCol);
+ else resolved[iEnd].col(begCol);
+ colFrom.push_back(endCol);
+ colTo.push_back(begCol);
+ } else {
+ if (hasCol) resolved[iBeg].col(endCol);
+ else resolved[iBeg].acol(endCol);
+ colFrom.push_back(begCol);
+ colTo.push_back(endCol);
+ }
+
+ // Pick up the other colour of the recent gluon and repeat.
+ iBeg = iEnd;
+ begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
+ // Not gluon but sea+companion pair: go to other.
+ if (begCol == 0) {
+ iBeg = resolved[iBeg].companion();
+ begCol = (hasCol) ? resolved[iBeg].col() : resolved[iBeg].acol();
+ }
+
+ // At end of gluon/(sea+companion) list.
+ }
+
+ // Now begin checks, and also finding junction information.
+ // Loop through remnant partons; isolate all colours and anticolours.
+ vector<int> colList;
+ vector<int> acolList;
+ for (int i = 0; i < size(); ++i)
+ if ( resolved[i].col() != resolved[i].acol() ) {
+ if (resolved[i].col() > 0) colList.push_back( resolved[i].col() );
+ if (resolved[i].acol() > 0) acolList.push_back( resolved[i].acol() );
+ }
+
+ // Remove all matching colour-anticolour pairs.
+ bool foundPair = true;
+ while (foundPair && colList.size() > 0 && acolList.size() > 0) {
+ foundPair = false;
+ for (int iCol = 0; iCol < int(colList.size()); ++iCol) {
+ for (int iAcol = 0; iAcol < int(acolList.size()); ++iAcol) {
+ if (acolList[iAcol] == colList[iCol]) {
+ colList[iCol] = colList.back(); colList.pop_back();
+ acolList[iAcol] = acolList.back(); acolList.pop_back();
+ foundPair = true; break;
+ }
+ } if (foundPair) break;
+ }
+ }
+
+ // Usually one unmatched pair left to collapse.
+ if (colList.size() == 1 && acolList.size() == 1) {
+ int finalFrom = max( colList[0], acolList[0]);
+ int finalTo = min( colList[0], acolList[0]);
+ for (int i = 0; i < size(); ++i) {
+ if (resolved[i].col() == finalFrom) resolved[i].col(finalTo);
+ if (resolved[i].acol() == finalFrom) resolved[i].acol(finalTo);
+ }
+ colFrom.push_back(finalFrom);
+ colTo.push_back(finalTo);
+
+ // Store an (anti)junction when three (anti)coloured daughters.
+ } else if (hasJunctionBeam && colList.size() == 3
+ && acolList.size() == 0) {
+ event.appendJunction( 1, colList[0], colList[1], colList[2]);
+ junCol[0] = colList[0];
+ junCol[1] = colList[1];
+ junCol[2] = colList[2];
+ } else if (hasJunctionBeam && acolList.size() == 3
+ && colList.size() == 0) {
+ event.appendJunction( 2, acolList[0], acolList[1], acolList[2]);
+ junCol[0] = acolList[0];
+ junCol[1] = acolList[1];
+ junCol[2] = acolList[2];
+
+ // Any other nonvanishing values indicate failure.
+ } else if (colList.size() > 0 || acolList.size() > 0) {
+ infoPtr->errorMsg("Error in BeamParticle::remnantColours: "
+ "leftover unmatched colours");
+ return false;
+ }
+
+ // Store colour assignment of beam particles.
+ for (int i = nInit; i < size(); ++i)
+ event[resolved[i].iPos()].cols( resolved[i].col(), resolved[i].acol() );
+
+ // Done.
+ return true;
+}
+
+
+//*********
+
+// Pick unrescaled x values for beam remnant sharing.
+
+double BeamParticle::xRemnant( int i) {
+
+ double x = 0.;
+
+ // Calculation of x of valence quark or diquark, for latter as sum.
+ if (resolved[i].isValence()) {
+
+ // Resolve diquark into sum of two quarks.
+ int id1 = resolved[i].id();
+ int id2 = 0;
+ if (abs(id1) > 10) {
+ id2 = (id1 > 0) ? (id1/100)%10 : -(((-id1)/100)%10);
+ id1 = (id1 > 0) ? id1/1000 : -((-id1)/1000);
+ }
+
+ // Loop over (up to) two quarks; add their contributions.
+ for (int iId = 0; iId < 2; ++iId) {
+ int idNow = (iId == 0) ? id1 : id2;
+ if (idNow == 0) break;
+ double xPart = 0.;
+
+ // Assume form (1-x)^a / sqrt(x).
+ double xPow = valencePowerMeson;
+ if (isBaryonBeam) {
+ if (nValKinds == 3 || nValKinds == 1)
+ xPow = (3. * Rndm::flat() < 2.)
+ ? valencePowerUinP : valencePowerDinP ;
+ else if (nValence(idNow) == 2) xPow = valencePowerUinP;
+ else xPow = valencePowerDinP;
+ }
+ do xPart = pow2( Rndm::flat() );
+ while ( pow(1. - xPart, xPow) < Rndm::flat() );
+
+ // End loop over (up to) two quarks. Possibly enhancement for diquarks.
+ x += xPart;
+ }
+ if (id2 != 0) x *= valenceDiqEnhance;
+
+ // Calculation of x of sea quark, based on companion association.
+ } else if (resolved[i].isCompanion()) {
+
+ // Find rescaled x value of companion.
+ double xLeft = 1.;
+ for (int iInit = 0; iInit < nInit; ++iInit)
+ xLeft -= resolved[iInit].x();
+ double xCompanion = resolved[ resolved[i].companion() ].x();
+ xCompanion /= (xLeft + xCompanion);
+
+ // Now use ansatz q(x; x_c) < N/(x +x_c) to pick x.
+ do x = pow( xCompanion, Rndm::flat()) - xCompanion;
+ while ( pow( (1. - x - xCompanion) / (1. - xCompanion), companionPower)
+ * (pow2(x) + pow2(xCompanion)) / pow2(x + xCompanion) < Rndm::flat() );
+
+ // Else, rarely, a single gluon remnant, so value does not matter.
+ } else x = 1.;
+ return x;
+
+}
+
+//*********
+
+// Print the list of resolved partons in a beam.
+
+void BeamParticle::list(ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA Partons resolved in beam ------------"
+ << "--------------------------------------------------------\n"
+ << "\n i iPos id x comp xqcomp colours"
+ << " p_x p_y p_z e m \n";
+
+ // Loop over list of removed partons and print it.
+ double xSum = 0.;
+ Vec4 pSum;
+ for (int i = 0; i < size(); ++i) {
+ ResolvedParton res = resolved[i];
+ os << fixed << setprecision(6) << setw(5) << i << setw(6) << res.iPos()
+ << setw(8) << res.id() << setw(10) << res.x() << setw(6)
+ << res.companion() << setw(10) << res.xqCompanion()
+ << setprecision(3) << setw(6) << res.col() << setw(6) << res.acol()
+ << setw(11) << res.px() << setw(11) << res.py() << setw(11)
+ << res.pz() << setw(11) << res.e() << setw(11) << res.m() << "\n";
+
+ // Also find and print sum of x and p values. Endline.
+ xSum += res.x();
+ pSum += res.p();
+ }
+ os << setprecision(6) << " x sum:" << setw(10) << xSum
+ << setprecision(3) << " p sum:" << setw(11)
+ << pSum.px() << setw(11) << pSum.py() << setw(11) << pSum.pz()
+ << setw(11) << pSum.e()
+ << "\n\n -------- End PYTHIA Partons resolved in beam ------"
+ << "----------------------------------------------------------"
+ << endl;
+}
+
+//*********
+
+// Test whether a lepton is to be considered as unresolved.
+
+bool BeamParticle::isUnresolvedLepton() {
+
+ // Require record to consist of lepton with full energy plus a photon.
+ if (!isLeptonBeam || resolved.size() > 2 || resolved[1].id() != 22
+ || resolved[0].x() < XMINUNRESOLVED) return false;
+ return true;
+
+}
+
+//*********
+
+// For a diffractive system, decide whether to kick out gluon or quark.
+
+bool BeamParticle::pickGluon(double mDiff) {
+
+ // Relative weight to pick a quark, assumed falling with energy.
+ double probPickQuark = pickQuarkNorm / pow( mDiff, pickQuarkPower);
+ return ( (1. + probPickQuark) * Rndm::flat() < 1. );
+
+}
+
+//*********
+
+// Pick a valence quark at random. (Used for diffractive systems.)
+
+int BeamParticle::pickValence() {
+
+ // Pick one valence quark at random.
+ int nTotVal = (isBaryonBeam) ? 3 : 2;
+ double rnVal = Rndm::flat() * nTotVal;
+ int iVal = (rnVal < 1.) ? 1 : ( (rnVal < 2.) ? 2 : 3 );
+
+ // This valence in slot 1, the rest thereafter.
+ idVal1 = 0;
+ idVal2 = 0;
+ idVal3 = 0;
+ int iNow = 0;
+ for (int i = 0; i < nValKinds; ++i)
+ for (int j = 0; j < nVal[i]; ++j) {
+ ++iNow;
+ if (iNow == iVal) idVal1 = idVal[i];
+ else if ( idVal2 == 0) idVal2 = idVal[i];
+ else idVal3 = idVal[i];
+ }
+
+ // Construct diquark if baryon.
+ if (idVal3 != 0) idVal2 = flavSelPtr->makeDiquark( idVal2, idVal3);
+
+ // Done.
+ return idVal1;
+
+}
+
+//*********
+
+// Share lightcone momentum between two remnants in a diffractive system.
+
+double BeamParticle::zShare( double mDiff, double m1, double m2) {
+
+ // Set up as valence in normal beam so can use xRemnant code.
+ append(0, idVal1, 0., -3);
+ append(0, idVal2, 0., -3);
+ double m2Diff = mDiff*mDiff;
+
+ // Begin to generate z and pT until acceptable solution.
+ double wtAcc = 0.;
+ do {
+ double x1 = xRemnant(0);
+ double x2 = xRemnant(0);
+ zRel = x1 / (x1 + x2);
+ pxRel = diffPrimKTwidth * Rndm::gauss();
+ pyRel = diffPrimKTwidth * Rndm::gauss();
+
+ // Suppress large invariant masses of remnant system.
+ double mTS1 = m1*m1 + pxRel*pxRel + pyRel*pyRel;
+ double mTS2 = m2*m2 + pxRel*pxRel + pyRel*pyRel;
+ double m2Sys = mTS1 / zRel + mTS2 / (1. - zRel);
+ wtAcc = (m2Sys < m2Diff)
+ ? pow( 1. - m2Sys / m2Diff, diffLargeMassSuppress) : 0.;
+ } while (wtAcc < Rndm::flat());
+
+ // Done.
+ return zRel;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// BeamRemnants.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// BeamRemnants class.
+
+#include "BeamRemnants.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The BeamDipole class is purely internal to reconnectColours.
+
+class BeamDipole {
+
+public:
+
+ // Constructor.
+ BeamDipole( int colIn = 0, int iColIn = 0, int iAcolIn = 0)
+ : col(colIn), iCol(iColIn), iAcol(iAcolIn) {}
+
+ // Members.
+ int col, iCol, iAcol;
+ double p1p2;
+
+};
+
+//**************************************************************************
+
+// The BeamRemnants class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maximum number of tries to match colours and kinematics in the event.
+const int BeamRemnants::NTRYCOLMATCH = 10;
+const int BeamRemnants::NTRYKINMATCH = 10;
+
+//*********
+
+// Initialization.
+
+bool BeamRemnants::init( Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn) {
+
+ // Save pointers.
+ infoPtr = infoPtrIn;
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+
+ // Width of primordial kT distribution.
+ doPrimordialKT = Settings::flag("BeamRemnants:primordialKT");
+ primordialKTsoft = Settings::parm("BeamRemnants:primordialKTsoft");
+ primordialKThard = Settings::parm("BeamRemnants:primordialKThard");
+ primordialKTremnant = Settings::parm("BeamRemnants:primordialKTremnant");
+ halfScaleForKT = Settings::parm("BeamRemnants:halfScaleForKT");
+ halfMassForKT = Settings::parm("BeamRemnants:halfMassForKT");
+
+ // Parameters for colour reconnection scenario, partly borrowed from
+ // multiple interactions not to introduce too many new ones.
+ doReconnect = Settings::flag("BeamRemnants:reconnectColours");
+ reconnectRange = Settings::parm("BeamRemnants:reconnectRange");
+ pT0Ref = Settings::parm("MultipleInteractions:pT0Ref");
+ ecmRef = Settings::parm("MultipleInteractions:ecmRef");
+ ecmPow = Settings::parm("MultipleInteractions:ecmPow");
+
+ // Total and squared CM energy at nominal energy.
+ eCM = infoPtr->eCM();
+ sCM = eCM * eCM;
+
+ // The MI pT0 smoothening scale and its reconnection-strength combination.
+ pT0 = pT0Ref * pow(eCM / ecmRef, ecmPow);
+ pT20Rec = pow2(reconnectRange * pT0);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Select the flavours/kinematics/colours of the two beam remnants.
+// Notation: iPar = all partons, iSys = matched systems of two beams,
+// iRem = additional partons in remnants.
+
+bool BeamRemnants::add( Event& event) {
+
+ // Update to current CM energy.
+ eCM = infoPtr->eCM();
+ sCM = eCM * eCM;
+
+ // Number of scattering subsystems. Size of event record before treatment.
+ nSys = event.sizeSystems();
+ oldSize = event.size();
+
+ // Add required extra remnant flavour content.
+ // Start all over if fails (in option where junctions not allowed).
+ if ( !beamAPtr->remnantFlavours(event)
+ || !beamBPtr->remnantFlavours(event) ) {
+ infoPtr->errorMsg("Error in BeamRemnants::add:"
+ " remnant flavour setup failed");
+ return false;
+ }
+
+ // Do the kinematics of the collision subsystems and two beam remnants
+ if (!setKinematics(event)) return false;
+
+ // Allow colour reconnections.
+ if (doReconnect) reconnectColours(event);
+
+ // Save current modifiable colour configuration for fast restoration.
+ vector<int> colSave;
+ vector<int> acolSave;
+ for (int i = oldSize; i < event.size(); ++i) {
+ colSave.push_back( event[i].col() );
+ acolSave.push_back( event[i].acol() );
+ }
+ event.saveJunctionSize();
+
+ // Allow several tries to match colours of initiators and remnants.
+ // Frequent "failures" since shortcutting colours separately on
+ // the two event sides may give "colour singlet gluons" etc.
+ bool physical = true;
+ for (int iTry = 0; iTry < NTRYCOLMATCH; ++iTry) {
+ physical = true;
+
+ // Reset list of colour "collapses" (transformations).
+ colFrom.resize(0);
+ colTo.resize(0);
+
+ // First process each set of beam colours on its own.
+ if (!beamAPtr->remnantColours(event, colFrom, colTo))
+ physical = false;
+ if (!beamBPtr->remnantColours(event, colFrom, colTo))
+ physical = false;
+
+ // Then check that colours and anticolours are matched in whole event.
+ if ( physical && !checkColours(event) ) physical = false;
+
+ // If no problems then done, else restore and loop.
+ if (physical) break;
+ for (int i = oldSize; i < event.size(); ++i)
+ event[i].cols( colSave[i - oldSize], acolSave[i - oldSize] );
+ event.restoreJunctionSize();
+ }
+
+ // If no solution after several tries then failed.
+ if (!physical) {
+ infoPtr->errorMsg("Error in BeamRemnants::add:"
+ " colour tracing failed");
+ return false;
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Set up trial transverse and longitudinal kinematics for each beam
+// separately. Final decisions involve comparing the two beams.
+
+bool BeamRemnants::setKinematics( Event& event) {
+
+ // References to beams to simplify indexing.
+ BeamParticle& beamA = *beamAPtr;
+ BeamParticle& beamB = *beamBPtr;
+
+ // Nothing to do for lepton-lepton scattering with all energy already used.
+ if ( beamA.isUnresolvedLepton() && beamB.isUnresolvedLepton() )
+ return true;
+
+ // Allow primordial kT reduction for small-mass and small-pT systems
+ // (for hardest interaction pT -> renormalization scale so also 2 -> 1).
+ vector<double> kTwidth;
+ vector<double> kTcomp;
+ double kTcompSumSys = 0.;
+ for (int iSys = 0; iSys < nSys; ++iSys) {
+ double kTwidthNow = 0.;
+ double mHatDamp = 1.;
+ if (doPrimordialKT) {
+ double mHat = sqrtpos( beamA[iSys].x() * beamB[iSys].x() * sCM );
+ mHatDamp = mHat / (mHat + halfMassForKT);
+ double scale = (iSys == 0) ? infoPtr->QRen() : infoPtr->pTMI(iSys);
+ kTwidthNow = ( (halfScaleForKT * primordialKTsoft
+ + scale * primordialKThard) / (halfScaleForKT + scale) ) * mHatDamp;
+ }
+ kTwidth.push_back( kTwidthNow );
+ kTcomp.push_back( mHatDamp );
+ kTcompSumSys += mHatDamp;
+ }
+ double kTwidthNow = (doPrimordialKT) ? primordialKTremnant : 0.;
+ for (int iRem = nSys; iRem < max( beamA.size(), beamB.size() ); ++iRem) {
+ kTwidth.push_back( kTwidthNow );
+ kTcomp.push_back( 1. );
+ }
+
+ // Allow ten tries to construct kinematics (but normally works first).
+ bool physical;
+ double xSum[2], xInvM[2], w2Beam[2], wPosRem, wNegRem, w2Rem;
+ for (int iTry = 0; iTry < NTRYKINMATCH; ++iTry) {
+ physical = true;
+
+ // Loop over the two beams. Sum px and py separately within each.
+ for (int iBeam = 0; iBeam < 2; ++iBeam) {
+ BeamParticle& beam = (iBeam == 0) ? beamA : beamB;
+ int nPar = beam.size();
+ double pxSum = 0.;
+ double pySum = 0.;
+
+ // Loop over the partons in a beam. Generate Gaussian pT for hadrons.
+ for (int iPar = 0; iPar < nPar; ++iPar) {
+ double px = 0.;
+ double py = 0.;
+ if (beam.isHadron() && doPrimordialKT) {
+ px = kTwidth[iPar] * Rndm::gauss();
+ py = kTwidth[iPar] * Rndm::gauss();
+ }
+ beam[iPar].px(px);
+ beam[iPar].py(py);
+ pxSum += px;
+ pySum += py;
+ }
+
+ // Share recoil between all partons.
+ if (doPrimordialKT) {
+ double kTcompSum = kTcompSumSys + (nPar - nSys);
+ for (int iPar = 0; iPar < nPar; ++iPar) {
+ beam[iPar].px( beam[iPar].px() - pxSum * kTcomp[iPar] / kTcompSum );
+ beam[iPar].py( beam[iPar].py() - pySum * kTcomp[iPar] / kTcompSum );
+ }
+ }
+
+ // Pick unrescaled x values for remnants. Sum up (unscaled) p+ and p-.
+ xSum[iBeam] = 0.;
+ xInvM[iBeam] = 0.;
+ for (int iRem = nSys; iRem < nPar; ++iRem) {
+ double xPrel = beam.xRemnant( iRem);
+ beam[iRem].x(xPrel);
+ xSum[iBeam] += xPrel;
+ xInvM[iBeam] += beam[iRem].mT2()/xPrel;
+ }
+
+ // Squared transverse mass for each beam, using lightcone x.
+ w2Beam[iBeam] = xSum[iBeam] * xInvM[iBeam];
+
+ // End separate treatment of the two beams.
+ }
+
+ // Recalculate kinematics of initiator systems with primordial kT.
+ wPosRem = eCM;
+ wNegRem = eCM;
+ for (int iSys = 0; iSys < nSys; ++iSys) {
+ double sHat = beamA[iSys].x() * beamB[iSys].x() * sCM;
+ double sHatT = sHat
+ + pow2( beamA[iSys].px() + beamB[iSys].px())
+ + pow2( beamA[iSys].py() + beamB[iSys].py());
+ double rescale = sqrt( sHatT / sHat);
+ wPosRem -= rescale * beamA[iSys].x() * eCM;
+ wNegRem -= rescale * beamB[iSys].x() * eCM;
+
+ // Kinematics forbids too large primordial kT.
+ if (sqrt(sHatT) < beamA[iSys].pT() + beamB[iSys].pT())
+ physical = false;
+ }
+
+ // Check that remaining momentum is enough for remnants.
+ if (wPosRem < 0. || wNegRem < 0.) physical = false;
+ w2Rem = wPosRem * wNegRem;
+ if (sqrtpos(w2Rem) < sqrt(w2Beam[0]) + sqrt(w2Beam[1]))
+ physical = false;
+
+ // End of loop over ten tries. Do not loop when solution found.
+ if (physical) break;
+ }
+
+ // If no solution after ten tries then failed.
+ if (!physical) {
+ infoPtr->errorMsg("Error in BeamRemnants::add:"
+ " kinematics construction failed");
+ return false;
+ }
+
+ // Construct energy and pz for each initiator pair.
+ for (int iSys = 0; iSys < nSys; ++iSys) {
+ double sHat = beamA[iSys].x() * beamB[iSys].x() * sCM;
+ double sHatT = sHat + pow2( beamA[iSys].px() + beamB[iSys].px())
+ + pow2( beamA[iSys].py() + beamB[iSys].py());
+ double rescale = sqrt( sHatT / sHat);
+ double wPos = rescale * beamA[iSys].x() * eCM;
+ double wNeg = rescale * beamB[iSys].x() * eCM;
+ double w2A = beamA[iSys].mT2();
+ double w2B = beamB[iSys].mT2();
+ double lambdaRoot = sqrtpos( pow2( sHatT - w2A - w2B) - 4. * w2A * w2B );
+ double pPosA = 0.5 * (sHatT + w2A - w2B + lambdaRoot) / sHatT * wPos;
+ beamA[iSys].e( 0.5 * (pPosA + w2A / pPosA) );
+ beamA[iSys].pz( 0.5 * (pPosA - w2A / pPosA) );
+ double pNegB = 0.5 * (sHatT + w2B - w2A + lambdaRoot) / sHatT * wNeg;
+ beamB[iSys].e( 0.5 * (pNegB + w2B / pNegB) );
+ beamB[iSys].pz( 0.5 * (w2B / pNegB - pNegB) );
+
+ // Construct rotations and boosts caused by primordial kT.
+ int iA = beamA[iSys].iPos();
+ int iB = beamB[iSys].iPos();
+ RotBstMatrix M;
+ M.toCMframe( event[iA].p(), event[iB].p() );
+ M.fromCMframe( beamA[iSys].p(), beamB[iSys].p() );
+
+ // Copy initiators and their systems and boost them accordingly.
+ // Update subsystem and beams info on new positions of partons.
+ int iAcopy = event.copy(iA, -61);
+ event[iAcopy].rotbst(M);
+ event.setInSystem(iSys, 0, iAcopy);
+ beamA[iSys].iPos( iAcopy);
+ int iBcopy = event.copy(iB, -61);
+ event[iBcopy].rotbst(M);
+ event.setInSystem(iSys, 1, iBcopy);
+ beamB[iSys].iPos( iBcopy);
+ for (int iABsys = 2; iABsys < event.sizeSystem(iSys); ++iABsys) {
+ int iAB = event.getInSystem(iSys, iABsys);
+ int iABcopy = event.copy(iAB, 62);
+ event[iABcopy].rotbst(M);
+ event.setInSystem(iSys, iABsys, iABcopy);
+ }
+
+ // Update daughter info of mothers, i.e. of beams, for hardest interaction.
+ if (iSys == 0) {
+ int mother = event[iAcopy].mother1();
+ event[mother].daughter1(iAcopy);
+ mother = event[iBcopy].mother1();
+ event[mother].daughter1(iBcopy);
+ }
+ }
+
+ // Construct x rescaling factors for the two remants.
+ double lambdaRoot = sqrtpos( pow2(w2Rem - w2Beam[0] - w2Beam[1])
+ - 4. * w2Beam[0] * w2Beam[1] );
+ double rescaleA = (w2Rem + w2Beam[0] - w2Beam[1] + lambdaRoot)
+ / (2. * w2Rem * xSum[0]) ;
+ double rescaleB = (w2Rem + w2Beam[1] - w2Beam[0] + lambdaRoot)
+ / (2. * w2Rem * xSum[1]) ;
+
+ // Construct energy and pz for remnants in first beam.
+ for (int iRem = nSys; iRem < beamA.size(); ++iRem) {
+ double pPos = rescaleA * beamA[iRem].x() * wPosRem;
+ double pNeg = beamA[iRem].mT2() / pPos;
+ beamA[iRem].e( 0.5 * (pPos + pNeg) );
+ beamA[iRem].pz( 0.5 * (pPos - pNeg) );
+
+ // Add these partons to the normal event record.
+ int iNew = event.append( beamA[iRem].id(), 63, 1, 0, 0, 0,
+ beamA[iRem].col(), beamA[iRem].acol(), beamA[iRem].p(),
+ beamA[iRem].m() );
+ beamA[iRem].iPos( iNew);
+ }
+
+ // Construct energy and pz for remnants in second beam.
+ for (int iRem = nSys; iRem < beamB.size(); ++iRem) {
+ double pNeg = rescaleB * beamB[iRem].x() * wNegRem;
+ double pPos = beamB[iRem].mT2() / pNeg;
+ beamB[iRem].e( 0.5 * (pPos + pNeg) );
+ beamB[iRem].pz( 0.5 * (pPos - pNeg) );
+
+ // Add these partons to the normal event record.
+ int iNew = event.append( beamB[iRem].id(), 63, 2, 0, 0, 0,
+ beamB[iRem].col(), beamB[iRem].acol(), beamB[iRem].p(),
+ beamB[iRem].m() );
+ beamB[iRem].iPos( iNew);
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Allow colour reconnections by mergings of collision subsystems.
+// iRec is system that may be reconnected, by moving its gluons to iSys,
+// where minimal pT (or equivalently Lambda) is used to pick location.
+// Therefore all dipoles in iSys have to be found, and all gluons in iRec.
+// Matching q-qbar pairs are treated by analogy with gluons.
+
+bool BeamRemnants::reconnectColours( Event& event) {
+
+ // Prepare record of which systems should be merged onto another.
+ // The iSys system must have colour in final state to attach to it.
+ vector<int> iMerge;
+ vector<bool> hasColour;
+ for (int iSys = 0; iSys < nSys; ++iSys) {
+ iMerge.push_back( iSys );
+ bool hasCol = false;
+ for (int iMem = 2; iMem < event.sizeSystem( iSys); ++iMem) {
+ int iNow = event.getInSystem( iSys, iMem);
+ if (event[iNow].col() > 0 || event[iNow].acol() > 0) {
+ hasCol = true;
+ break;
+ }
+ }
+ hasColour.push_back( hasCol );
+ }
+
+ // Loop over system that may be reconnected.
+ for (int iRec = nSys - 1; iRec > 0; --iRec) {
+
+ // Determine reconnection strength from pT scale of system.
+ double pT2Rec = pow2( infoPtr->pTMI(iRec) );
+ double probRec = pT20Rec / (pT20Rec + pT2Rec);
+
+ // Loop over other systems iSys at higher pT scale and
+ // decide whether to reconnect the iRec gluons onto one of them.
+ for (int iSys = iRec - 1; iSys >= 0; --iSys)
+ if (hasColour[iSys] && probRec > Rndm::flat()) {
+
+ // The iRec system and all merged with it to be merged with iSys.
+ iMerge[iRec] = iSys;
+ for (int iRec2 = iRec + 1; iRec2 < nSys; ++iRec2)
+ if (iMerge[iRec2] == iRec) iMerge[iRec2] = iSys;
+
+ // Once a system has been merged do not test it anymore.
+ break;
+ }
+ }
+
+ // Loop over systems. Check whether other systems to be merged with it.
+ for (int iSys = 0; iSys < nSys; ++iSys) {
+
+ int nMerge = 0;
+ for (int iRec = iSys + 1; iRec < nSys; ++iRec)
+ if (iMerge[iRec] == iSys) ++nMerge;
+ if (nMerge == 0) continue;
+
+ // Begin find dipoles in iSys system.
+ vector<BeamDipole> dipoles;
+ int sizeSys = event.sizeSystem( iSys);
+ int iInASys = event.getInSystem( iSys, 0);
+ int iInBSys = event.getInSystem( iSys, 1);
+ for (int iMem = 2; iMem < sizeSys; ++iMem) {
+
+ // Find colour dipoles to beam remnant.
+ int iNow = event.getInSystem( iSys, iMem);
+ int col = event[iNow].col();
+ if (col > 0) {
+ if (event[iInASys].col() == col)
+ dipoles.push_back( BeamDipole( col, iNow, iInASys ) );
+ else if (event[iInBSys].col() == col)
+ dipoles.push_back( BeamDipole( col, iNow, iInBSys ) );
+
+ // Find colour dipole between final-state partons.
+ else for (int iMem2 = 2; iMem2 < sizeSys; ++iMem2)
+ if (iMem2 != iMem) {
+ int iNow2 = event.getInSystem( iSys, iMem2);
+ if (event[iNow2].acol() == col) {
+ dipoles.push_back( BeamDipole( col, iNow, iNow2) );
+ break;
+ }
+ }
+ }
+
+ // Find anticolour dipoles to beam remnant.
+ int acol = event[iNow].acol();
+ if (acol > 0) {
+ if (event[iInASys].acol() == acol)
+ dipoles.push_back( BeamDipole( acol, iInASys, iNow ) );
+ else if (event[iInBSys].acol() == acol)
+ dipoles.push_back( BeamDipole( acol, iInBSys, iNow ) );
+ }
+ }
+
+ // Find dipole sizes.
+ for (int iDip = 0; iDip < int(dipoles.size()); ++iDip)
+ dipoles[iDip].p1p2 = event[dipoles[iDip].iCol].p()
+ * event[dipoles[iDip].iAcol].p();
+
+ // Loop over systems iRec to be merged with iSys.
+ for (int iRec = iSys + 1; iRec < nSys; ++iRec) {
+ if (iMerge[iRec] != iSys) continue;
+
+ // Information on iRec. Vectors for gluons and anything else.
+ int sizeRec = event.sizeSystem( iRec);
+ int iInARec = event.getInSystem( iRec, 0);
+ int iInBRec = event.getInSystem( iRec, 1);
+ int nGluRec = 0;
+ vector<int> iGluRec;
+ vector<double> pT2GluRec;
+ int nAnyRec = 0;
+ vector<int> iAnyRec;
+ vector<bool> freeAnyRec;
+
+ // Copy of gluon positions in descending order.
+ for (int iMem = 2; iMem < sizeRec; ++iMem) {
+ int iNow = event.getInSystem( iRec, iMem);
+ if (event[iNow].isGluon()) {
+ ++nGluRec;
+ iGluRec.push_back( iNow );
+ pT2GluRec.push_back( event[iNow].pT2() );
+ for (int i = nGluRec - 1; i > 1; --i) {
+ if (pT2GluRec[i - 1] > pT2GluRec[i]) break;
+ swap( iGluRec[i - 1], iGluRec[i] );
+ swap( pT2GluRec[i - 1], pT2GluRec[i] );
+ }
+ // Copy of anything else, mainly quarks, in no particular order.
+ } else {
+ ++nAnyRec;
+ iAnyRec.push_back( iNow );
+ freeAnyRec.push_back( true );
+ }
+ }
+
+ // For each gluon in iRec now find the dipole that gives the smallest
+ // (pGlu * pI) (pGlu * pJ) / (pI * pJ), i.e. minimal pT (and Lambda).
+ for (int iGRec = 0; iGRec < nGluRec; ++iGRec) {
+ int iGlu = iGluRec[iGRec];
+ Vec4 pGlu = event[iGlu].p();
+ int iDipMin = 0;
+ double pT2DipMin = sCM;
+ for (int iDip = 0; iDip < int(dipoles.size()); ++iDip) {
+ double pT2Dip = (pGlu * event[dipoles[iDip].iCol].p())
+ * (pGlu * event[dipoles[iDip].iAcol].p()) / dipoles[iDip].p1p2;
+ if (pT2Dip < pT2DipMin) {
+ iDipMin = iDip;
+ pT2DipMin = pT2Dip;
+ }
+ }
+
+ // Attach the gluon to the dipole, i.e. split the dipole in two.
+ int colGlu = event[iGlu].col();
+ int acolGlu = event[iGlu].acol();
+ int colDip = dipoles[iDipMin].col;
+ int iColDip = dipoles[iDipMin].iCol;
+ int iAcolDip = dipoles[iDipMin].iAcol;
+ event[iGlu].acol( colDip );
+ if (event[iAcolDip].acol() == colDip)
+ event[iAcolDip].acol( colGlu );
+ else event[iAcolDip].col( colGlu );
+ dipoles[iDipMin].iAcol = iGlu;
+ dipoles[iDipMin].p1p2 = event[iColDip].p() * pGlu;
+ dipoles.push_back( BeamDipole( colGlu, iGlu, iAcolDip ) );
+ dipoles.back().p1p2 = pGlu * event[iAcolDip].p();
+
+ // Remove gluon from old system: reconnect colours.
+ if (event[iInARec].col() == colGlu)
+ event[iInARec].col( acolGlu );
+ else if (event[iInBRec].col() == colGlu)
+ event[iInBRec].col( acolGlu );
+ else for (int i = iGRec + 1; i < nGluRec; ++i)
+ if (event[iGluRec[i]].acol() == colGlu) {
+ event[iGluRec[i]].acol( acolGlu );
+ break;
+ }
+ for (int i = 0; i < nAnyRec; ++i)
+ if (event[iAnyRec[i]].acol() == colGlu) {
+ event[iAnyRec[i]].acol( acolGlu );
+ break;
+ }
+ }
+
+ // See if any matching quark-antiquark pairs among the rest.
+ for (int iQRec = 0; iQRec < nAnyRec; ++iQRec) {
+ int iQ = iAnyRec[iQRec];
+ int idQ = event[iQ].id();
+ if (freeAnyRec[iQRec] && idQ > 0 && idQ < 6)
+ for (int iQbarRec = 0; iQbarRec < nAnyRec; ++iQbarRec) {
+ int iQbar = iAnyRec[iQbarRec];
+ if (freeAnyRec[iQbarRec] && event[iQbar].id() == -idQ) {
+
+ // Check that these can be traced back to same gluon splitting.
+ int iTopQ = event.iTopCopyId(iQ);
+ int iTopQbar = event.iTopCopyId(iQbar);
+ int iMother = event[iTopQ].mother1();
+ if (event[iTopQbar].mother1() == iMother
+ && event[iMother].isGluon()) {
+
+ // Now find the dipole that gives the smallest
+ // ((pQ + pQbar) * pI) ((pQ + pQbar) * pJ) / (pI * pJ).
+ Vec4 pGlu = event[iQ].p() + event[iQbar].p();
+ int iDipMin = 0;
+ double pT2DipMin = sCM;
+ for (int iDip = 0; iDip < int(dipoles.size()); ++iDip) {
+ double pT2Dip = (pGlu * event[dipoles[iDip].iCol].p())
+ * (pGlu * event[dipoles[iDip].iAcol].p())
+ / dipoles[iDip].p1p2;
+ if (pT2Dip < pT2DipMin) {
+ iDipMin = iDip;
+ pT2DipMin = pT2Dip;
+ }
+ }
+
+ // Attach the q-qbar pair to the dipole, i.e. split the dipole.
+ int colGlu = event[iQ].col();
+ int acolGlu = event[iQbar].acol();
+ int colDip = dipoles[iDipMin].col;
+ int iColDip = dipoles[iDipMin].iCol;
+ int iAcolDip = dipoles[iDipMin].iAcol;
+ event[iQbar].acol( colDip );
+ if (event[iAcolDip].acol() == colDip)
+ event[iAcolDip].acol( colGlu );
+ else event[iAcolDip].col( colGlu );
+ dipoles[iDipMin].iAcol = iQbar;
+ dipoles[iDipMin].p1p2 = event[iColDip].p() * event[iQbar].p();
+ dipoles.push_back( BeamDipole( colGlu, iQ, iAcolDip ) );
+ dipoles.back().p1p2 = event[iQ].p() * event[iAcolDip].p();
+
+ // Remove q-qbar pair from old system: reconnect colours.
+ freeAnyRec[iQRec] = false;
+ freeAnyRec[iQbarRec] = false;
+ if (event[iInARec].col() == colGlu)
+ event[iInARec].col( acolGlu );
+ else if (event[iInBRec].col() == colGlu)
+ event[iInBRec].col( acolGlu );
+ else for (int i = 0; i < nAnyRec; ++i)
+ if (freeAnyRec[i] && event[iAnyRec[i]].acol() == colGlu) {
+ event[iAnyRec[i]].acol( acolGlu );
+ break;
+ }
+
+ // Done with processing of q-qbar pairs.
+ }
+ }
+ }
+ }
+
+ // If only two beam gluons left of system, set their colour = anticolour.
+ // Used by BeamParticle::remnantColours to skip irrelevant gluons.
+ if ( event[iInARec].isGluon() && event[iInBRec].isGluon()
+ && event[iInARec].col() == event[iInBRec].acol()
+ && event[iInARec].acol() == event[iInBRec].col() ) {
+ event[iInARec].acol( event[iInARec].col() );
+ event[iInBRec].acol( event[iInBRec].col() );
+ }
+
+ // End of loops over iRec and iSys systems.
+ }
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Collapse colours and check that they are consistent.
+
+bool BeamRemnants::checkColours( Event& event) {
+
+ // No colours in lepton beams so no need to do anything.
+ if (beamAPtr->isLepton() && beamBPtr->isLepton()) return true;
+
+ // Remove ambiguities when one colour collapses two ways.
+ // Resolve chains where one colour is mapped to another.
+ for (int iCol = 1; iCol < int(colFrom.size()); ++iCol)
+ for (int iColRef = 0; iColRef < iCol; ++iColRef) {
+ if (colFrom[iCol] == colFrom[iColRef]) {
+ colFrom[iCol] = colTo[iCol];
+ colTo[iCol] = colTo[iColRef];
+ }
+ if (colTo[iCol] == colFrom[iColRef]) colTo[iCol] = colTo[iColRef];
+ }
+
+ // Transform event record colours from beam remnant colour collapses.
+ for (int i = oldSize; i < event.size(); ++i) {
+ int col = event[i].col();
+ int acol = event[i].acol();
+ for (int iCol = 0; iCol < int(colFrom.size()); ++iCol) {
+ if (col == colFrom[iCol]) {col = colTo[iCol]; event[i].col(col);}
+ if (acol == colFrom[iCol]) {acol = colTo[iCol]; event[i].acol(acol);}
+ }
+ }
+
+ // Transform junction colours from beam remnant colour collapses.
+ for (int iJun = 0; iJun < event.sizeJunction(); ++iJun)
+ for (int leg = 0; leg < 3; ++leg) {
+ int col = event.colJunction(iJun, leg);
+ for (int iCol = 0; iCol < int(colFrom.size()); ++iCol)
+ if (col == colFrom[iCol]) {
+ col = colTo[iCol];
+ event.colJunction(iJun, leg, col);
+ }
+ }
+
+ // Arrays for current colours and anticolours, and for singlet gluons.
+ vector<int> colList;
+ vector<int> acolList;
+ vector<int> iSingletGluon;
+
+ // Find current colours and anticolours in the event record.
+ for (int i = oldSize; i < event.size(); ++i)
+ if (event[i].status() > 0) {
+ int id = event[i].id();
+ int col = event[i].col();
+ int acol = event[i].acol();
+
+ // Quarks must have colour set, antiquarks anticolour, gluons both.
+ if ( (id > 0 && id < 9 && (col <= 0 || acol != 0) )
+ || (id < 0 && id > -9 && (col != 0 || acol <= 0) )
+ || (id == 21 && (col <= 0 || acol <= 0) ) ) {
+ infoPtr->errorMsg("Error in BeamRemnants::checkColours: "
+ "q/qbar/g has wrong colour slots set");
+ return false;
+ }
+
+ // Save colours/anticolours, and position of colour singlet gluons.
+ if ( col > 0) colList.push_back( col );
+ if (acol > 0) acolList.push_back( acol );
+ if (col > 0 && acol == col) iSingletGluon.push_back(i);
+ }
+
+ // Run though list of singlet gluons and put them on final-state dipole
+ // (i,j) that offers smallest (p_g p_i) * (p_g p_j) / (p_i p_j).
+ for (int iS = 0; iS < int(iSingletGluon.size()); ++iS) {
+ int iGlu = iSingletGluon[iS];
+ int iAcolDip = 0;
+ double pT2DipMin = sCM;
+ for (int iC = oldSize; iC < event.size(); ++iC)
+ if (iC != iGlu && event[iC].status() > 0) {
+ int colDip = event[iC].col();
+ if (colDip > 0 && event[iC].acol() !=colDip)
+ for (int iA = oldSize; iA < event.size(); ++iA)
+ if (iA != iGlu && iA != iC && event[iA].status() > 0
+ && event[iA].acol() == colDip && event[iA].col() !=colDip) {
+ double pT2Dip = (event[iGlu].p() * event[iC].p())
+ * (event[iGlu].p() * event[iA].p())
+ / (event[iC].p() * event[iA].p());
+ if (pT2Dip < pT2DipMin) {
+ iAcolDip = iA;
+ pT2DipMin = pT2Dip;
+ }
+ }
+ }
+ event[iGlu].acol( event[iAcolDip].acol() );
+ event[iAcolDip].acol( event[iGlu].col() );
+ }
+
+ // Check that not the same colour or anticolour appears twice.
+ for (int iCol = 0; iCol < int(colList.size()) - 1; ++iCol) {
+ int col = colList[iCol];
+ for (int iCol2 = iCol + 1; iCol2 < int(colList.size()); ++iCol2)
+ if (colList[iCol2] == col) return false;
+ }
+ for (int iAcol = 0; iAcol < int(acolList.size()) - 1; ++iAcol) {
+ int acol = acolList[iAcol];
+ for (int iAcol2 = iAcol + 1; iAcol2 < int(acolList.size()); ++iAcol2)
+ if (acolList[iAcol2] == acol) return false;
+ }
+
+ // Remove all matching colour-anticolour pairs.
+ bool foundPair = true;
+ while (foundPair && colList.size() > 0 && acolList.size() > 0) {
+ foundPair = false;
+ for (int iCol = 0; iCol < int(colList.size()); ++iCol) {
+ for (int iAcol = 0; iAcol < int(acolList.size()); ++iAcol) {
+ if (acolList[iAcol] == colList[iCol]) {
+ colList[iCol] = colList.back(); colList.pop_back();
+ acolList[iAcol] = acolList.back(); acolList.pop_back();
+ foundPair = true; break;
+ }
+ } if (foundPair) break;
+ }
+ }
+
+ // Check that remaining (anti)colours are accounted for by junctions.
+ for (int iJun = 0; iJun < event.sizeJunction(); ++iJun) {
+ int kindJun = event.kindJunction(iJun);
+ for (int leg = 0; leg < 3; ++leg) {
+ int colEnd = event.colJunction(iJun, leg);
+
+ // Junction connected to three colours.
+ if (kindJun == 1) {
+ bool foundCol = false;
+ for (int iCol = 0; iCol < int(colList.size()); ++iCol)
+ if (colList[iCol] == colEnd) {
+ colList[iCol] = colList.back();
+ colList.pop_back();
+ foundCol = true;
+ break;
+ }
+ }
+
+ // Junction connected to three anticolours.
+ else if (kindJun == 2) {
+ bool foundCol = false;
+ for (int iAcol = 0; iAcol < int(acolList.size()); ++iAcol)
+ if (acolList[iAcol] == colEnd) {
+ acolList[iAcol] = acolList.back();
+ acolList.pop_back();
+ foundCol = true;
+ break;
+ }
+ }
+
+ // End junction check. More junction cases to come??
+ }
+ }
+
+ // Done.
+ return (colList.size() == 0 && acolList.size() == 0);
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// BeamShape.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the BeamShape class.
+
+#include "BeamShape.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The BeamShape class.
+
+//*********
+
+// Initialize beam parameters.
+
+void BeamShape::init() {
+
+ // Main flags.
+ allowMomentumSpread = Settings::flag("Beams:allowMomentumSpread");
+ allowVertexSpread = Settings::flag("Beams:allowVertexSpread");
+
+ // Parameters for beam A momentum spread.
+ sigmaPxA = Settings::parm("Beams:sigmaPxA");
+ sigmaPyA = Settings::parm("Beams:sigmaPyA");
+ sigmaPzA = Settings::parm("Beams:sigmaPzA");
+ maxDevA = Settings::parm("Beams:maxDevA");
+
+ // Parameters for beam B momentum spread.
+ sigmaPxB = Settings::parm("Beams:sigmaPxB");
+ sigmaPyB = Settings::parm("Beams:sigmaPyB");
+ sigmaPzB = Settings::parm("Beams:sigmaPzB");
+ maxDevB = Settings::parm("Beams:maxDevB");
+
+ // Parameters for beam vertex spread.
+ sigmaVertexX = Settings::parm("Beams:sigmaVertexX");
+ sigmaVertexY = Settings::parm("Beams:sigmaVertexY");
+ sigmaVertexZ = Settings::parm("Beams:sigmaVertexZ");
+ maxDevVertex = Settings::parm("Beams:maxDevVertex");
+ sigmaTime = Settings::parm("Beams:sigmaTime");
+ maxDevTime = Settings::parm("Beams:maxDevTime");
+
+ // Parameters for beam vertex offset.
+ offsetX = Settings::parm("Beams:offsetVertexX");
+ offsetY = Settings::parm("Beams:offsetVertexY");
+ offsetZ = Settings::parm("Beams:offsetVertexZ");
+ offsetT = Settings::parm("Beams:offsetTime");
+
+}
+
+//*********
+
+// Set the two beam momentum deviations and the beam vertex.
+
+void BeamShape::pick() {
+
+ // Reset all values.
+ deltaPxA = deltaPyA = deltaPzA = deltaPxB = deltaPyB = deltaPzB
+ = vertexX = vertexY = vertexZ = vertexT = 0.;
+
+ // Set beam A momentum deviation by a three-dimensional Gaussian.
+ if (allowMomentumSpread) {
+ double totalDev, gauss;
+ do {
+ totalDev = 0.;
+ if (sigmaPxA > 0.) {
+ gauss = Rndm::gauss();
+ deltaPxA = sigmaPxA * gauss;
+ totalDev += gauss * gauss;
+ }
+ if (sigmaPyA > 0.) {
+ gauss = Rndm::gauss();
+ deltaPyA = sigmaPyA * gauss;
+ totalDev += gauss * gauss;
+ }
+ if (sigmaPzA > 0.) {
+ gauss = Rndm::gauss();
+ deltaPzA = sigmaPzA * gauss;
+ totalDev += gauss * gauss;
+ }
+ } while (totalDev > maxDevA * maxDevA);
+
+ // Set beam B momentum deviation by a three-dimensional Gaussian.
+ do {
+ totalDev = 0.;
+ if (sigmaPxB > 0.) {
+ gauss = Rndm::gauss();
+ deltaPxB = sigmaPxB * gauss;
+ totalDev += gauss * gauss;
+ }
+ if (sigmaPyB > 0.) {
+ gauss = Rndm::gauss();
+ deltaPyB = sigmaPyB * gauss;
+ totalDev += gauss * gauss;
+ }
+ if (sigmaPzB > 0.) {
+ gauss = Rndm::gauss();
+ deltaPzB = sigmaPzB * gauss;
+ totalDev += gauss * gauss;
+ }
+ } while (totalDev > maxDevB * maxDevB);
+ }
+
+ // Set beam vertex location by a three-dimensional Gaussian.
+ if (allowVertexSpread) {
+ double totalDev, gauss;
+ do {
+ totalDev = 0.;
+ if (sigmaVertexX > 0.) {
+ gauss = Rndm::gauss();
+ vertexX = sigmaVertexX * gauss;
+ totalDev += gauss * gauss;
+ }
+ if (sigmaVertexY > 0.) {
+ gauss = Rndm::gauss();
+ vertexY = sigmaVertexY * gauss;
+ totalDev += gauss * gauss;
+ }
+ if (sigmaVertexZ > 0.) {
+ gauss = Rndm::gauss();
+ vertexZ = sigmaVertexZ * gauss;
+ totalDev += gauss * gauss;
+ }
+ } while (totalDev > maxDevVertex * maxDevVertex);
+
+ // Set beam collision time by a Gaussian.
+ if (sigmaTime > 0.) {
+ do gauss = Rndm::gauss();
+ while (abs(gauss) > maxDevTime);
+ vertexT = sigmaTime * gauss;
+ }
+
+ // Add offset to beam vertex.
+ vertexX += offsetX;
+ vertexY += offsetY;
+ vertexZ += offsetZ;
+ vertexT += offsetT;
+ }
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
--- /dev/null
+// BoseEinstein.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the BoseEinsten class.
+
+#include "BoseEinstein.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The BoseEinstein class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Enumeration of id codes and table for particle species considered.
+const int BoseEinstein::IDHADRON[9] = { 211, -211, 111, 321, -321,
+ 130, 310, 221, 331 };
+const int BoseEinstein::ITABLE[9] = { 0, 0, 0, 1, 1, 1, 1, 2, 3 };
+
+// Distance between table entries, normalized to min( 2*mass, QRef).
+const double BoseEinstein::STEPSIZE = 0.05;
+
+// Skip shift for two extremely close particles, to avoid instabilities.
+const double BoseEinstein::Q2MIN = 1e-8;
+
+// Parameters of energy compensation procedure: maximally allowed
+// relative energy error, iterative stepsize, and number of iterations.
+const double BoseEinstein::COMPRELERR = 1e-10;
+const double BoseEinstein::COMPFACMAX = 1000.;
+const int BoseEinstein::NCOMPSTEP = 10;
+
+//*********
+
+// Find settings. Precalculate table used to find momentum shifts.
+
+bool BoseEinstein::init(Info* infoPtrIn) {
+
+ // Save pointer.
+ infoPtr = infoPtrIn;
+
+ // Main flags.
+ doPion = Settings::flag("BoseEinstein:Pion");
+ doKaon = Settings::flag("BoseEinstein:Kaon");
+ doEta = Settings::flag("BoseEinstein:Eta");
+
+ // Shape of Bose-Einstein enhancement/suppression.
+ lambda = Settings::parm("BoseEinstein:lambda");
+ QRef = Settings::parm("BoseEinstein:QRef");
+
+ // Multiples and inverses (= "radii") of distance parameters in Q-space.
+ QRef2 = 2. * QRef;
+ QRef3 = 3. * QRef;
+ R2Ref = 1. / (QRef * QRef);
+ R2Ref2 = 1. / (QRef2 * QRef2);
+ R2Ref3 = 1. / (QRef3 * QRef3);
+
+ // Masses of particles with Bose-Einstein implemented.
+ for (int iSpecies = 0; iSpecies < 9; ++iSpecies)
+ mHadron[iSpecies] = ParticleDataTable::m0( IDHADRON[iSpecies] );
+
+ // Pair pi, K, eta and eta' masses for use in tables.
+ mPair[0] = 2. * mHadron[0];
+ mPair[1] = 2. * mHadron[3];
+ mPair[2] = 2. * mHadron[7];
+ mPair[3] = 2. * mHadron[8];
+
+ // Loop over the four required tables. Local variables.
+ double Qnow, Q2now, centerCorr;
+ for (int iTab = 0; iTab < 4; ++iTab) {
+ m2Pair[iTab] = mPair[iTab] * mPair[iTab];
+
+ // Step size and number of steps in normal table.
+ deltaQ[iTab] = STEPSIZE * min(mPair[iTab], QRef);
+ nStep[iTab] = min( 199, 1 + int(3. * QRef / deltaQ[iTab]) );
+ maxQ[iTab] = (nStep[iTab] - 0.1) * deltaQ[iTab];
+ centerCorr = deltaQ[iTab] * deltaQ[iTab] / 12.;
+
+ // Construct normal table recursively in Q space.
+ shift[iTab][0] = 0.;
+ for (int i = 1; i <= nStep[iTab]; ++i) {
+ Qnow = deltaQ[iTab] * (i - 0.5);
+ Q2now = Qnow * Qnow;
+ shift[iTab][i] = shift[iTab][i - 1] + exp(-Q2now * R2Ref)
+ * deltaQ[iTab] * (Q2now + centerCorr) / sqrt(Q2now + m2Pair[iTab]);
+ }
+
+ // Step size and number of steps in compensation table.
+ deltaQ3[iTab] = STEPSIZE * min(mPair[iTab], QRef3);
+ nStep3[iTab] = min( 199, 1 + int(9. * QRef / deltaQ3[iTab]) );
+ maxQ3[iTab] = (nStep3[iTab] - 0.1) * deltaQ3[iTab];
+ centerCorr = deltaQ3[iTab] * deltaQ3[iTab] / 12.;
+
+ // Construct compensation table recursively in Q space.
+ shift3[iTab][0] = 0.;
+ for (int i = 1; i <= nStep3[iTab]; ++i) {
+ Qnow = deltaQ3[iTab] * (i - 0.5);
+ Q2now = Qnow * Qnow;
+ shift3[iTab][i] = shift3[iTab][i - 1] + exp(-Q2now * R2Ref3)
+ * deltaQ3[iTab] * (Q2now + centerCorr) / sqrt(Q2now + m2Pair[iTab]);
+ }
+
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Perform Bose-Einstein corrections on an event.
+
+bool BoseEinstein::shiftEvent( Event& event) {
+
+ // Reset list of identical particles.
+ hadronBE.resize(0);
+
+ // Loop over all hadron species with BE effects.
+ nStored[0] = 0;
+ for (int iSpecies = 0; iSpecies < 9; ++iSpecies) {
+ nStored[iSpecies + 1] = nStored[iSpecies];
+ if (!doPion && iSpecies <= 2) continue;
+ if (!doKaon && iSpecies >= 3 && iSpecies <= 6) continue;
+ if (!doEta && iSpecies >= 7) continue;
+
+ // Properties of current hadron species.
+ int idNow = IDHADRON[ iSpecies ];
+ int iTab = ITABLE[ iSpecies ];
+
+ // Loop through event record to store copies of current species.
+ for (int i = 0; i < event.size(); ++i)
+ if ( event[i].id() == idNow && event[i].isFinal() )
+ hadronBE.push_back(
+ BoseEinsteinHadron( idNow, i, event[i].p(), event[i].m() ) );
+ nStored[iSpecies + 1] = hadronBE.size();
+
+ // Loop through pairs of identical particles and find shifts.
+ for (int i1 = nStored[iSpecies]; i1 < nStored[iSpecies+1] - 1; ++i1)
+ for (int i2 = i1 + 1; i2 < nStored[iSpecies+1]; ++i2)
+ shiftPair( i1, i2, iTab);
+ }
+
+ // Must have at least two pairs to carry out compensation.
+ if (nStored[9] < 2) return true;
+
+ // Shift momenta and recalculate energies.
+ double eSumOriginal = 0.;
+ double eSumShifted = 0.;
+ double eDiffByComp = 0.;
+ for (int i = 0; i < nStored[9]; ++i) {
+ eSumOriginal += hadronBE[i].p.e();
+ hadronBE[i].p += hadronBE[i].pShift;
+ hadronBE[i].p.e( sqrt( hadronBE[i].p.pAbs2() + hadronBE[i].m2 ) );
+ eSumShifted += hadronBE[i].p.e();
+ eDiffByComp += dot3( hadronBE[i].pComp, hadronBE[i].p)
+ / hadronBE[i].p.e();
+ }
+
+ // Iterate compensation shift until convergence.
+ int iStep = 0;
+ while ( abs(eSumShifted - eSumOriginal) > COMPRELERR * eSumOriginal
+ && abs(eSumShifted - eSumOriginal) < COMPFACMAX * abs(eDiffByComp)
+ && iStep < NCOMPSTEP ) {
+ ++iStep;
+ double compFac = (eSumOriginal - eSumShifted) / eDiffByComp;
+ eSumShifted = 0.;
+ eDiffByComp = 0.;
+ for (int i = 0; i < nStored[9]; ++i) {
+ hadronBE[i].p += compFac * hadronBE[i].pComp;
+ hadronBE[i].p.e( sqrt( hadronBE[i].p.pAbs2() + hadronBE[i].m2 ) );
+ eSumShifted += hadronBE[i].p.e();
+ eDiffByComp += dot3( hadronBE[i].pComp, hadronBE[i].p)
+ / hadronBE[i].p.e();
+ }
+ }
+
+ // Error if no convergence, and then return without doing BE shift.
+ // However, not grave enough to kill event, so return true.
+ if ( abs(eSumShifted - eSumOriginal) > COMPRELERR * eSumOriginal ) {
+ infoPtr->errorMsg("Warning in BoseEinstein::shiftEvent: "
+ "no consistent BE shift topology found, so skip BE");
+ return true;
+ }
+
+ // Store new particle copies with shifted momenta.
+ for (int i = 0; i < nStored[9]; ++i) {
+ int iNew = event.copy( hadronBE[i].iPos, 99);
+ event[ iNew ].p( hadronBE[i].p );
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Calculate shift and (unnormalized) compensation for pair.
+
+void BoseEinstein::shiftPair( int i1, int i2, int iTab) {
+
+ // Calculate old relative momentum.
+ double Q2old = m2(hadronBE[i1].p, hadronBE[i2].p) - m2Pair[iTab];
+ if (Q2old < Q2MIN) return;
+ double Qold = sqrt(Q2old);
+ double psFac = sqrt(Q2old + m2Pair[iTab]) / Q2old;
+
+ // Calculate new relative momentum for normal shift.
+ double Qmove = 0.;
+ if (Qold < deltaQ[iTab]) Qmove = Qold / 3.;
+ else if (Qold < maxQ[iTab]) {
+ double realQbin = Qold / deltaQ[iTab];
+ int intQbin = int( realQbin );
+ double inter = (pow3(realQbin) - pow3(intQbin))
+ / (3 * intQbin * (intQbin + 1) + 1);
+ Qmove = ( shift[iTab][intQbin] + inter * (shift[iTab][intQbin + 1]
+ - shift[iTab][intQbin]) ) * psFac;
+ }
+ else Qmove = shift[iTab][nStep[iTab]] * psFac;
+ double Q2new = Q2old * pow( Qold / (Qold + 3. * lambda * Qmove), 2. / 3.);
+
+ // Calculate corresponding three-momentum shift.
+ double Q2Diff = Q2new - Q2old;
+ double p2DiffAbs = (hadronBE[i1].p - hadronBE[i2].p).pAbs2();
+ double p2AbsDiff = hadronBE[i1].p.pAbs2() - hadronBE[i2].p.pAbs2();
+ double eSum = hadronBE[i1].p.e() + hadronBE[i2].p.e();
+ double eDiff = hadronBE[i1].p.e() - hadronBE[i2].p.e();
+ double sumQ2E = Q2Diff + eSum * eSum;
+ double rootA = eSum * eDiff * p2AbsDiff - p2DiffAbs * sumQ2E;
+ double rootB = p2DiffAbs * sumQ2E - p2AbsDiff * p2AbsDiff;
+ double factor = 0.5 * ( rootA + sqrtpos(rootA * rootA
+ + Q2Diff * (sumQ2E - eDiff * eDiff) * rootB) ) / rootB;
+
+ // Add shifts to sum. (Energy component dummy.)
+ Vec4 pDiff = factor * (hadronBE[i1].p - hadronBE[i2].p);
+ hadronBE[i1].pShift += pDiff;
+ hadronBE[i2].pShift -= pDiff;
+
+ // Calculate new relative momentum for compensation shift.
+ double Qmove3 = 0.;
+ if (Qold < deltaQ3[iTab]) Qmove3 = Qold / 3.;
+ else if (Qold < maxQ3[iTab]) {
+ double realQbin = Qold / deltaQ3[iTab];
+ int intQbin = int( realQbin );
+ double inter = (pow3(realQbin) - pow3(intQbin))
+ / (3 * intQbin * (intQbin + 1) + 1);
+ Qmove3 = ( shift3[iTab][intQbin] + inter * (shift3[iTab][intQbin + 1]
+ - shift3[iTab][intQbin]) ) * psFac;
+ }
+ else Qmove3 = shift3[iTab][nStep3[iTab]] *psFac;
+ double Q2new3 = Q2old * pow( Qold / (Qold + 3. * lambda * Qmove3), 2. / 3.);
+
+ // Calculate corresponding three-momentum shift.
+ Q2Diff = Q2new3 - Q2old;
+ sumQ2E = Q2Diff + eSum * eSum;
+ rootA = eSum * eDiff * p2AbsDiff - p2DiffAbs * sumQ2E;
+ rootB = p2DiffAbs * sumQ2E - p2AbsDiff * p2AbsDiff;
+ factor = 0.5 * ( rootA + sqrtpos(rootA * rootA
+ + Q2Diff * (sumQ2E - eDiff * eDiff) * rootB) ) / rootB;
+
+ // Extra dampening factor to go from BE_3 to BE_32.
+ factor *= 1. - exp(-Q2old * R2Ref2);
+
+ // Add shifts to sum. (Energy component dummy.)
+ pDiff = factor * (hadronBE[i1].p - hadronBE[i2].p);
+ hadronBE[i1].pComp += pDiff;
+ hadronBE[i2].pComp -= pDiff;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
--- /dev/null
+// Event.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// Particle and Event classes, and some related global functions.
+
+#include "Event.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Particle class.
+// This class holds info on a particle in general.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Small number to avoid division by zero.
+const double Particle::TINY = 1e-20;
+
+//*********
+
+// Functions for rapidity and pseudorapidity.
+
+double Particle::y() const {
+ double temp = log( ( pSave.e() + abs(pSave.pz()) ) / max( TINY, mT() ) );
+ return (pSave.pz() > 0) ? temp : -temp;
+}
+
+double Particle::eta() const {
+ double temp = log( ( pSave.pAbs() + abs(pSave.pz()) ) / max( TINY, pT() ) );
+ return (pSave.pz() > 0) ? temp : -temp;
+}
+
+//*********
+
+// Particle name, with status but imposed maximum length -> may truncate.
+
+string Particle::nameWithStatus(int maxLen) const {
+
+ string temp = (statusSave > 0) ? particlePtr->name(idSave)
+ : "(" + particlePtr->name(idSave) + ")";
+ while (int(temp.length()) > maxLen) {
+ // Remove from end, excluding closing bracket and charge.
+ int iRem = temp.find_last_not_of(")+-0");
+ temp.erase(iRem, 1);
+ }
+ return temp;
+}
+
+//*********
+
+// Add offsets to mother and daughter pointers (must be non-negative).
+
+void Particle::offsetHistory( int minMother, int addMother, int minDaughter,
+ int addDaughter) {
+
+ if (addMother < 0 || addDaughter < 0) return;
+ if ( mother1Save > minMother ) mother1Save += addMother;
+ if ( mother2Save > minMother ) mother2Save += addMother;
+ if (daughter1Save > minDaughter) daughter1Save += addDaughter;
+ if (daughter2Save > minDaughter) daughter2Save += addDaughter;
+
+}
+
+//*********
+
+// Add offsets to colour and anticolour (must be positive).
+
+void Particle::offsetCol( int addCol) {
+
+ if (addCol < 0) return;
+ if ( colSave > 0) colSave += addCol;
+ if (acolSave > 0) acolSave += addCol;
+
+}
+
+//*********
+
+// Set the ParticleDataEntry pointer, using the stored idSave value.
+
+void Particle::setParticlePtr() {
+
+ particlePtr = ParticleDataTable::particleDataPtr(idSave);
+
+}
+
+//*********
+
+// Invariant mass of a pair and its square.
+// (Not part of class proper, but tightly linked.)
+
+double m(const Particle& pp1, const Particle& pp2) {
+ double m2 = pow2(pp1.e() + pp2.e()) - pow2(pp1.px() + pp2.px())
+ - pow2(pp1.py() + pp2.py()) - pow2(pp1.pz() + pp2.pz());
+ return (m2 > 0. ? sqrt(m2) : 0.);
+}
+
+double m2(const Particle& pp1, const Particle& pp2) {
+ double m2 = pow2(pp1.e() + pp2.e()) - pow2(pp1.px() + pp2.px())
+ - pow2(pp1.py() + pp2.py()) - pow2(pp1.pz() + pp2.pz());
+ return m2;
+}
+
+//**************************************************************************
+
+// Event class.
+// This class holds info on the complete event record.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maxmimum number of mothers or daughter indices per line in listing.
+const int Event::IPERLINE = 20;
+
+//*********
+
+// Copy all information from one event record to another.
+
+Event& Event::operator=( const Event& oldEvent) {
+
+ // Do not copy if same.
+ if (this != &oldEvent) {
+
+ // Reset all current info in the event.
+ clear();
+
+ // Copy all the particles one by one.
+ for (int i = 0; i < oldEvent.size(); ++i) append( oldEvent[i] );
+
+ // Copy all the junctions one by one.
+ for (int i = 0; i < oldEvent.sizeJunction(); ++i)
+ appendJunction( oldEvent.getJunction(i) );
+
+ // Copy values in the system arrays.
+ for (int i = 0; i < int(oldEvent.beginSys.size()); ++i)
+ beginSys.push_back( oldEvent.beginSys[i] );
+ for (int i = 0; i < int(oldEvent.sizeSys.size()); ++i)
+ sizeSys.push_back( oldEvent.sizeSys[i] );
+ for (int i = 0; i < int(oldEvent.memberSys.size()); ++i)
+ memberSys.push_back( oldEvent.memberSys[i] );
+
+ // Copy all other values.
+ startColTag = oldEvent.startColTag;
+ maxColTag = oldEvent.maxColTag;
+ savedSize = oldEvent.savedSize;
+ savedJunctionSize = oldEvent.savedJunctionSize;
+ scaleSave = oldEvent.scaleSave;
+ scaleSecondSave = oldEvent.scaleSecondSave;
+ headerList = oldEvent.headerList;
+
+ // Done.
+ }
+ return *this;
+
+}
+
+//*********
+
+// Initialize colour and header specification for event listing.
+
+void Event::init( string headerIn) {
+
+ // The starting colour tag for the event.
+ startColTag = Settings::mode("Event:startColTag");
+
+ // Set header specification for event listing.
+ headerList.replace(0, headerIn.length() + 2, headerIn + " ");
+
+}
+
+//*********
+
+// Add a copy of an existing particle at the end of the event record;
+// return index. Three cases, depending on sign of new status code:
+// Positive: copy is viewed as daughter, status of original is negated.
+// Negative: copy is viewed as mother, status of original is unchanged.
+// Zero: the new is a perfect carbon copy (maybe to be changed later).
+
+int Event::copy(int iCopy, int newStatus) {
+
+ // Simple carbon copy.
+ entry.push_back(entry[iCopy]);
+ int iNew = entry.size() - 1;
+
+ // Set up to make new daughter of old.
+ if (newStatus > 0) {
+ entry[iCopy].daughters(iNew,iNew);
+ entry[iCopy].statusNeg();
+ entry[iNew].mothers(iCopy, iCopy);
+ entry[iNew].status(newStatus);
+
+ // Set up to make new mother of old.
+ } else if (newStatus < 0) {
+ entry[iCopy].mothers(iNew,iNew);
+ entry[iNew].daughters(iCopy, iCopy);
+ entry[iNew].status(newStatus);
+ }
+
+ // Done.
+ return iNew;
+
+}
+
+//*********
+
+// Print an event.
+
+void Event::list(bool showScaleAndVertex, bool showMothersAndDaughters,
+ ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA Event Listing " << headerList << "----------"
+ << "------------------------------------------------- \n \n no "
+ << " id name status mothers daughters colou"
+ << "rs p_x p_y p_z e m \n";
+ if (showScaleAndVertex)
+ os << " scale "
+ << " xProd yProd zProd tProd "
+ << " tau\n";
+
+ // At high energy switch to scientific format for momenta.
+ bool useFixed = (entry[0].e() < 1e5);
+
+ // Listing of complete event.
+ Vec4 pSum;
+ double chargeSum = 0.;
+ for (int i = 0; i < int(entry.size()); ++i) {
+ const Particle& pt = entry[i];
+
+ // Basic line for a particle, always printed.
+ os << setw(6) << i << setw(10) << pt.id() << " " << left
+ << setw(18) << pt.nameWithStatus(18) << right << setw(4)
+ << pt.status() << setw(6) << pt.mother1() << setw(6)
+ << pt.mother2() << setw(6) << pt.daughter1() << setw(6)
+ << pt.daughter2() << setw(6) << pt.col() << setw(6) << pt.acol()
+ << ( (useFixed) ? fixed : scientific ) << setprecision(3)
+ << setw(11) << pt.px() << setw(11) << pt.py() << setw(11)
+ << pt.pz() << setw(11) << pt.e() << setw(11) << pt.m() << "\n";
+
+ // Optional extra line for scale value and production vertex.
+ if (showScaleAndVertex)
+ os << " " << setw(11) << pt.scale()
+ << " " << scientific
+ << setprecision(3) << setw(11) << pt.xProd() << setw(11)
+ << pt.yProd() << setw(11) << pt.zProd() << setw(11)
+ << pt.tProd() << setw(11) << pt.tau() << "\n";
+
+ // Optional extra line, giving a complete list of mothers and daughters.
+ if (showMothersAndDaughters) {
+ int linefill = 2;
+ os << " mothers:";
+ vector<int> allMothers = motherList(i);
+ for (int j = 0; j < int(allMothers.size()); ++j) {
+ os << " " << allMothers[j];
+ if (++linefill == IPERLINE) {os << "\n "; linefill = 0;}
+ }
+ os << "; daughters:";
+ vector<int> allDaughters = daughterList(i);
+ for (int j = 0; j < int(allDaughters.size()); ++j) {
+ os << " " << allDaughters[j];
+ if (++linefill == IPERLINE) {os << "\n "; linefill = 0;}
+ }
+ if (linefill !=0) os << "\n";
+ }
+
+ // Statistics on momentum and charge.
+ if (entry[i].status() > 0) {
+ pSum += entry[i].p();
+ chargeSum += entry[i].charge();
+ }
+ }
+
+ // Line with sum charge, momentum, energy and invariant mass.
+ os << fixed << setprecision(3) << " "
+ << "Charge sum:" << setw(7) << chargeSum << " Momentum sum:"
+ << ( (useFixed) ? fixed : scientific ) << setprecision(3)
+ << setw(11) << pSum.px() << setw(11) << pSum.py() << setw(11)
+ << pSum.pz() << setw(11) << pSum.e() << setw(11) << pSum.mCalc()
+ << "\n";
+
+ // Listing finished.
+ os << "\n -------- End PYTHIA Event Listing ----------------------------"
+ << "-------------------------------------------------------------------"
+ << endl;
+}
+
+//*********
+
+// Find complete list of mothers.
+
+vector<int> Event::motherList(int i) const {
+
+ // Vector of all the mothers; created empty.
+ vector<int> mothers;
+
+ // Read out the two official mother indices and status code.
+ int mother1 = entry[i].mother1();
+ int mother2 = entry[i].mother2();
+ int statusAbs = entry[i].statusAbs();
+
+ // Special cases in the beginning, where the meaning of zero is unclear.
+ if (statusAbs == 11 || statusAbs == 12) ;
+ else if (mother1 == 0 && mother2 == 0) mothers.push_back(0);
+
+ // One mother or a carbon copy
+ else if (mother2 == 0 || mother2 == mother1) mothers.push_back(mother1);
+
+ // A range of mothers from string fragmentation.
+ else if ( statusAbs > 80 && statusAbs < 90)
+ for (int iRange = mother1; iRange <= mother2; ++iRange)
+ mothers.push_back(iRange);
+
+ // Two separate mothers.
+ else {
+ mothers.push_back( min(mother1, mother2) );
+ mothers.push_back( max(mother1, mother2) );
+ }
+
+ // Done.
+ return mothers;
+
+}
+
+//*********
+
+// Find complete list of daughters.
+
+vector<int> Event::daughterList(int i) const {
+
+ // Vector of all the daughters; created empty.
+ vector<int> daughters;
+
+ // Read out the two official daughter indices.
+ int daughter1 = entry[i].daughter1();
+ int daughter2 = entry[i].daughter2();
+
+ // Simple cases: no or one daughter.
+ if (daughter1 == 0 && daughter2 == 0) ;
+ else if (daughter2 == 0 || daughter2 == daughter1)
+ daughters.push_back(daughter1);
+
+ // A range of daughters.
+ else if (daughter2 > daughter1)
+ for (int iRange = daughter1; iRange <= daughter2; ++iRange)
+ daughters.push_back(iRange);
+
+ // Two separated daughters.
+ else {
+ daughters.push_back(daughter2);
+ daughters.push_back(daughter1);
+ }
+
+ // Special case for two incoming beams: attach further
+ // initiators and remnants that have beam as mother.
+ if (entry[i].statusAbs() == 12 || entry[i].statusAbs() == 13)
+ for (int iDau = 3; iDau < size(); ++iDau)
+ if (entry[iDau].mother1() == i) {
+ bool isIn = false;
+ for (int iIn = 0; iIn < int(daughters.size()); ++iIn)
+ if (iDau == daughters[iIn]) isIn = true;
+ if (!isIn) daughters.push_back(iDau);
+ }
+
+ // Done.
+ return daughters;
+
+}
+
+//*********
+
+// Trace the first and last copy of one and the same particle.
+
+int Event::iTopCopy( int i) const {
+
+ int iUp = i;
+ while ( iUp > 0 && entry[iUp].mother2() == entry[iUp].mother1()
+ && entry[iUp].mother1() > 0) iUp = entry[iUp].mother1();
+ return iUp;
+
+}
+
+int Event::iBotCopy( int i) const {
+
+ int iDn = i;
+ while ( iDn > 0 && entry[iDn].daughter2() == entry[iDn].daughter1()
+ && entry[iDn].daughter1() > 0) iDn = entry[iDn].daughter1();
+ return iDn;
+
+}
+
+//*********
+
+// Trace the first and last copy of one and the same particle,
+// also through shower branchings, making use of flavour matches.
+// Stops tracing when this gives ambiguities.
+
+int Event::iTopCopyId( int i) const {
+
+ int id = entry[i].id();
+ int iUp = i;
+ for ( ; ; ) {
+ int mother1 = entry[iUp].mother1();
+ int id1 = (mother1 > 0) ? entry[mother1].id() : 0;
+ int mother2 = entry[iUp].mother2();
+ int id2 = (mother2 > 0) ? entry[mother2].id() : 0;
+ if (mother2 != mother1 && id2 == id1) break;
+ if (id1 == id) {
+ iUp = mother1;
+ continue;
+ }
+ if (id2 == id) {
+ iUp = mother2;
+ continue;
+ }
+ break;
+ }
+ return iUp;
+
+}
+
+int Event::iBotCopyId( int i) const {
+
+ int id = entry[i].id();
+ int iDn = i;
+ for ( ; ; ) {
+ int daughter1 = entry[iDn].daughter1();
+ int id1 = (daughter1 > 0) ? entry[daughter1].id() : 0;
+ int daughter2 = entry[iDn].daughter2();
+ int id2 = (daughter2 > 0) ? entry[daughter2].id() : 0;
+ if (daughter2 != daughter1 && id2 == id1) break;
+ if (id1 == id) {
+ iDn = daughter1;
+ continue;
+ }
+ if (id2 == id) {
+ iDn = daughter2;
+ continue;
+ }
+ break;
+ }
+ return iDn;
+
+}
+
+//*********
+
+// Find complete list of sisters.
+
+vector<int> Event::sisterList(int i) const {
+
+ // Vector of all the sisters; created empty.
+ vector<int> sisters;
+ if (entry[i].statusAbs() == 11) return sisters;
+
+ // Find mother and all its daughters.
+ int iMother = entry[i].mother1();
+ vector<int> daughters = daughterList(iMother);
+
+ // Copy all daughters, excepting the input particle itself.
+ for (int j = 0; j < int(daughters.size()); ++j)
+ if (daughters[j] != i) sisters.push_back( daughters[j] );
+
+ // Done.
+ return sisters;
+
+}
+
+//*********
+
+// Find complete list of sisters. Traces up with iTopCopy and
+// down with iBotCopy to give sisters at same level of evolution.
+// Should this not give any final particles, the search is widened.
+
+vector<int> Event::sisterListTopBot(int i, bool widenSearch) const {
+
+ // Vector of all the sisters; created empty.
+ vector<int> sisters;
+ if (entry[i].statusAbs() == 11) return sisters;
+
+ // Trace up to first copy of current particle.
+ int iUp = iTopCopy(i);
+
+ // Find mother and all its daughters.
+ int iMother = entry[iUp].mother1();
+ vector<int> daughters = daughterList(iMother);
+
+ // Trace all daughters down, excepting the input particle itself.
+ for (int jD = 0; jD < int(daughters.size()); ++jD)
+ if (daughters[jD] != iUp)
+ sisters.push_back( iBotCopy( daughters[jD] ) );
+
+ // Prune any non-final particles from list.
+ int jP = 0;
+ while (jP < int(sisters.size())) {
+ if (entry[sisters[jP]].status() > 0) ++jP;
+ else {
+ sisters[jP] = sisters.back();
+ sisters.pop_back();
+ }
+ }
+
+ // If empty list then restore immediate daughters.
+ if (sisters.size() == 0 && widenSearch) {
+ for (int jR = 0; jR < int(daughters.size()); ++jR)
+ if (daughters[jR] != iUp)
+ sisters.push_back( iBotCopy( daughters[jR] ) );
+
+ // Then trace all daughters, not only bottom copy.
+ for (int jT = 0; jT < int(sisters.size()); ++jT) {
+ daughters = daughterList( sisters[jT] );
+ for (int k = 0; k < int(daughters.size()); ++k)
+ sisters.push_back( daughters[k] );
+ }
+
+ // And then prune any non-final particles from list.
+ int jN = 0;
+ while (jN < int(sisters.size())) {
+ if (entry[sisters[jN]].status() > 0) ++jN;
+ else {
+ sisters[jN] = sisters.back();
+ sisters.pop_back();
+ }
+ }
+ }
+
+ // Done.
+ return sisters;
+
+}
+
+//*********
+
+// Check whether a given particle is an arbitrarily-steps-removed
+// mother to another. For the parton -> hadron transition, only
+// first-rank hadrons are associated with the respective end quark.
+
+bool Event::isAncestor(int i, int iAncestor) const {
+
+ // Begin loop to trace upwards from the daughter.
+ int iUp = i;
+ for ( ; ; ) {
+
+ // If positive match then done.
+ if (iUp == iAncestor) return true;
+
+ // If out of range then failed to find match.
+ if (iUp <= 0 || iUp > size()) return false;
+
+ // If unique mother then keep on moving up the chain.
+ int mother1 = entry[iUp].mother1();
+ int mother2 = entry[iUp].mother2();
+ if (mother2 == mother1 || mother2 == 0) {iUp = mother1; continue;}
+
+ // If many mothers, except hadronization, then fail tracing.
+ int status = entry[iUp].statusAbs();
+ if (status < 81 || status > 86) return false;
+
+ // For hadronization step, fail if not first rank, else move up.
+ if (status == 82) {
+ iUp = (iUp + 1 < size() && entry[iUp + 1].mother1() == mother1)
+ ? mother1 : mother2; continue;
+ }
+ if (status == 83) {
+ if (entry[iUp - 1].mother1() == mother1) return false;
+ iUp = mother1; continue;
+ }
+ if (status == 84) {
+ if (iUp + 1 < size() && entry[iUp + 1].mother1() == mother1)
+ return false;
+ iUp = mother1; continue;
+ }
+
+ // Fail for ministring -> one hadron and for junctions.
+ return false;
+
+ }
+ // End of loop. Should never reach beyond here.
+ return false;
+
+}
+
+//*********
+
+// Erase junction stored in specified slot and move up the ones under.
+
+void Event::eraseJunction(int i) {
+
+ for (int j = i; j < int(junction.size()) - 1; ++j)
+ junction[j] = junction[j + 1];
+ junction.pop_back();
+
+}
+
+//*********
+
+// Print the junctions in an event.
+
+void Event::listJunctions(ostream& os) const {
+
+ // Header.
+ os << "\n -------- PYTHIA Junction Listing "
+ << headerList.substr(0,30) << "\n \n no kind col0 col1 col2 "
+ << "endc0 endc1 endc2 stat0 stat1 stat2\n";
+
+ // Loop through junctions in event and list them.
+ for (int i = 0; i < sizeJunction(); ++i)
+ os << setw(6) << i << setw(6) << kindJunction(i) << setw(6)
+ << colJunction(i, 0) << setw(6) << colJunction(i, 1) << setw(6)
+ << colJunction(i, 2) << setw(6) << endColJunction(i, 0) << setw(6)
+ << endColJunction(i, 1) << setw(6) << endColJunction(i, 2) << setw(6)
+ << statusJunction(i, 0) << setw(6) << statusJunction(i, 1) << setw(6)
+ << statusJunction(i, 2) << "\n";
+
+ // Alternative if no junctions. Listing finished.
+ if (sizeJunction() == 0) os << " no junctions present \n";
+ os << "\n -------- End PYTHIA Junction Listing --------------------"
+ << "------" << endl;
+}
+
+//*********
+
+// Add parton to system, by shifting everything below to make room.
+
+void Event::addToSystem(int iSys, int iPos) {
+
+ int newPos = beginSys[iSys] + sizeSys[iSys];
+ memberSys.push_back(0);
+ for (int i = int(memberSys.size()) - 2; i >= newPos; --i)
+ memberSys[i+1] = memberSys[i];
+ memberSys[newPos] = iPos;
+ ++sizeSys[iSys];
+ for (int i = iSys + 1; i < int(beginSys.size()); ++i) ++beginSys[i];
+
+}
+
+//*********
+
+// Replace existing value by new one in given system but unknown member.
+
+void Event::replaceInSystem(int iSys, int iPosOld, int iPosNew) {
+
+ for (int i = beginSys[iSys]; i < beginSys[iSys] + sizeSys[iSys]; ++i)
+ if (memberSys[i] == iPosOld) memberSys[i] = iPosNew;
+
+}
+
+//*********
+
+// Print members in systems; for debug mainly.
+
+void Event::listSystems(ostream& os) const {
+
+
+ // Header.
+ os << "\n -------- PYTHIA Systems Listing " << headerList
+ << "------------ \n \n no members \n";
+
+ // Loop over system list and over members in each system.
+ for (int iSys = 0; iSys < int(beginSys.size()); ++iSys) {
+ os << " " << setw(5) << iSys << " ";
+ for (int iMem = 0; iMem < sizeSys[iSys]; ++iMem) {
+ if (iMem%16 == 0 && iMem > 0) os << "\n ";
+ os << " " << setw(4) << memberSys[beginSys[iSys] + iMem];
+ }
+ os << "\n";
+ }
+
+ // Alternative if no systems. Done.
+ if (beginSys.size() == 0) os << " no systems defined \n";
+ os << "\n -------- End PYTHIA Systems Listing ----------------------"
+ << "--------------------------" << endl;
+
+}
+
+//*********
+
+// Operator overloading allows to append one event to an existing one.
+
+Event& Event::operator+=( const Event& addEvent) {
+
+ // Find offsets. One less since won't copy line 0.
+ int offsetIdx = entry.size() - 1;
+ int offsetCol = maxColTag;
+
+ // Add energy to zeroth line and calculate new invariant mass.
+ entry[0].p( entry[0].p() + addEvent[0].p() );
+ entry[0].m( entry[0].mCalc() );
+
+ // Read out particles from line 1 (not 0) onwards.
+ Particle temp;
+ for (int i = 1; i < addEvent.size(); ++i) {
+ temp = addEvent[i];
+
+ // Add offset to nonzero mother, daughter and colour indices.
+ if (temp.mother1() > 0) temp.mother1( temp.mother1() + offsetIdx );
+ if (temp.mother2() > 0) temp.mother2( temp.mother2() + offsetIdx );
+ if (temp.daughter1() > 0) temp.daughter1( temp.daughter1() + offsetIdx );
+ if (temp.daughter2() > 0) temp.daughter2( temp.daughter2() + offsetIdx );
+ if (temp.col() > 0) temp.col( temp.col() + offsetCol );
+ if (temp.acol() > 0) temp.acol( temp.acol() + offsetCol );
+
+ // Append particle to summed event.
+ append( temp );
+ }
+
+ // Read out junctions one by one.
+ Junction tempJ;
+ int begCol, endCol;
+ for (int i = 0; i < addEvent.sizeJunction(); ++i) {
+ tempJ = addEvent.getJunction(i);
+
+ // Add colour offsets to all three legs.
+ for (int j = 0; j < 3; ++j) {
+ begCol = tempJ.col(j);
+ endCol = tempJ.endCol(j);
+ if (begCol > 0) begCol += offsetCol;
+ if (endCol > 0) endCol += offsetCol;
+ tempJ.cols( j, begCol, endCol);
+ }
+
+ // Append junction to summed event.
+ appendJunction( tempJ );
+ }
+
+ // Read out systems one by one. Append new system to event.
+ for (int i = 0; i < addEvent.sizeSystems(); ++i) {
+ int iNew = newSystem();
+
+ // Append members in system, with offset.
+ for (int j = 0; j < addEvent.sizeSystem(i); ++j)
+ addToSystem( iNew, addEvent.getInSystem( i, j) + offsetIdx );
+ }
+
+ // Set header that indicates character as sum of events.
+ headerList = "(combination of several events) -------";
+
+ // Done.
+ return *this;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// FragmentationFlavZpT.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// StringFlav, StringZ and StringPT classes.
+
+#include "FragmentationFlavZpT.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The StringFlav class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Offset for different meson multiplet id values.
+const int StringFlav::mesonMultipletCode[6]
+ = { 1, 3, 10003, 10001, 20003, 5};
+
+// Clebsch-Gordan coefficients for baryon octet and decuplet are
+// fixed once and for all, so only weighted sum needs to be edited.
+// Order: ud0 + u, ud0 + s, uu1 + u, uu1 + d, ud1 + u, ud1 + s.
+const double StringFlav::baryonCGOct[6]
+ = { 0.75, 0.5, 0., 0.1667, 0.0833, 0.1667};
+const double StringFlav::baryonCGDec[6]
+ = { 0., 0., 1., 0.3333, 0.6667, 0.3333};
+
+//*********
+
+// Initialize data members of the flavour generation.
+
+void StringFlav::init() {
+
+ // Basic parameters for generation of new flavour.
+ probQQtoQ = Settings::parm("StringFlav:probQQtoQ");
+ probStoUD = Settings::parm("StringFlav:probStoUD");
+ probSQtoQQ = Settings::parm("StringFlav:probSQtoQQ");
+ probQQ1toQQ0 = Settings::parm("StringFlav:probQQ1toQQ0");
+
+ // Parameters derived from above.
+ probQandQQ = 1. + probQQtoQ;
+ probQandS = 2. + probStoUD;
+ probQandSinQQ = 2. + probSQtoQQ * probStoUD;
+ probQQ1corr = 3. * probQQ1toQQ0;
+ probQQ1corrInv = 1. / probQQ1corr;
+ probQQ1norm = probQQ1corr / (1. + probQQ1corr);
+
+ // Parameters for normal meson production.
+ for (int i = 0; i < 4; ++i) mesonRate[i][0] = 1.;
+ mesonRate[0][1] = Settings::parm("StringFlav:mesonUDvector");
+ mesonRate[1][1] = Settings::parm("StringFlav:mesonSvector");
+ mesonRate[2][1] = Settings::parm("StringFlav:mesonCvector");
+ mesonRate[3][1] = Settings::parm("StringFlav:mesonBvector");
+
+ // Parameters for L=1 excited-meson production.
+ mesonRate[0][2] = Settings::parm("StringFlav:mesonUDL1S0J1");
+ mesonRate[1][2] = Settings::parm("StringFlav:mesonSL1S0J1");
+ mesonRate[2][2] = Settings::parm("StringFlav:mesonCL1S0J1");
+ mesonRate[3][2] = Settings::parm("StringFlav:mesonBL1S0J1");
+ mesonRate[0][3] = Settings::parm("StringFlav:mesonUDL1S1J0");
+ mesonRate[1][3] = Settings::parm("StringFlav:mesonSL1S1J0");
+ mesonRate[2][3] = Settings::parm("StringFlav:mesonCL1S1J0");
+ mesonRate[3][3] = Settings::parm("StringFlav:mesonBL1S1J0");
+ mesonRate[0][4] = Settings::parm("StringFlav:mesonUDL1S1J1");
+ mesonRate[1][4] = Settings::parm("StringFlav:mesonSL1S1J1");
+ mesonRate[2][4] = Settings::parm("StringFlav:mesonCL1S1J1");
+ mesonRate[3][4] = Settings::parm("StringFlav:mesonBL1S1J1");
+ mesonRate[0][5] = Settings::parm("StringFlav:mesonUDL1S1J2");
+ mesonRate[1][5] = Settings::parm("StringFlav:mesonSL1S1J2");
+ mesonRate[2][5] = Settings::parm("StringFlav:mesonCL1S1J2");
+ mesonRate[3][5] = Settings::parm("StringFlav:mesonBL1S1J2");
+
+ // Store sum over multiplets for Monte Carlo generation.
+ for (int i = 0; i < 4; ++i) mesonRateSum[i]
+ = mesonRate[i][0] + mesonRate[i][1] + mesonRate[i][2]
+ + mesonRate[i][3] + mesonRate[i][4] + mesonRate[i][5];
+
+ // Parameters for uubar - ddbar - ssbar meson mixing.
+ for (int spin = 0; spin < 6; ++spin) {
+ double theta;
+ if (spin == 0) theta = Settings::parm("StringFlav:thetaPS");
+ else if (spin == 1) theta = Settings::parm("StringFlav:thetaV");
+ else if (spin == 2) theta = Settings::parm("StringFlav:thetaL1S0J1");
+ else if (spin == 3) theta = Settings::parm("StringFlav:thetaL1S1J0");
+ else if (spin == 4) theta = Settings::parm("StringFlav:thetaL1S1J1");
+ else theta = Settings::parm("StringFlav:thetaL1S1J2");
+ double alpha = (spin == 0) ? 90. - (theta + 54.7) : theta + 54.7;
+ alpha *= M_PI / 180.;
+ // Fill in (flavour, spin)-dependent probability of producing
+ // the lightest or the lightest two mesons of the nonet.
+ mesonMix1[0][spin] = 0.5;
+ mesonMix2[0][spin] = 0.5 * (1. + pow2(sin(alpha)));
+ mesonMix1[1][spin] = 0.;
+ mesonMix2[1][spin] = pow2(cos(alpha));
+ }
+
+ // Additional suppression of eta and etaPrime.
+ etaSup = Settings::parm("StringFlav:etaSup");
+ etaPrimeSup = Settings::parm("StringFlav:etaPrimeSup");
+
+ // Sum of baryon octet and decuplet weights.
+ decupletSup = Settings::parm("StringFlav:decupletSup");
+ for (int i = 0; i < 6; ++i) baryonCGSum[i]
+ = baryonCGOct[i] + decupletSup * baryonCGDec[i];
+
+ // Maximum SU(6) weight for ud0, ud1, uu1 types.
+ baryonCGMax[0] = max( baryonCGSum[0], baryonCGSum[1]);
+ baryonCGMax[1] = baryonCGMax[0];
+ baryonCGMax[2] = max( baryonCGSum[2], baryonCGSum[3]);
+ baryonCGMax[3] = baryonCGMax[2];
+ baryonCGMax[4] = max( baryonCGSum[4], baryonCGSum[5]);
+ baryonCGMax[5] = baryonCGMax[4];
+
+ // Popcorn baryon parameters.
+ popcornRate = Settings::parm("StringFlav:popcornRate");
+ popcornSpair = Settings::parm("StringFlav:popcornSpair");
+ popcornSmeson = Settings::parm("StringFlav:popcornSmeson");
+
+ // Suppression of leading (= first-rank) baryons.
+ suppressLeadingB = Settings::flag("StringFlav:suppressLeadingB");
+ lightLeadingBSup = Settings::parm("StringFlav:lightLeadingBSup");
+ heavyLeadingBSup = Settings::parm("StringFlav:heavyLeadingBSup");
+
+ // Begin calculation of derived parameters for baryon production.
+
+ // Enumerate distinguishable diquark types (in diquark first is popcorn q).
+ enum Diquark {ud0, ud1, uu1, us0, su0, us1, su1, ss1};
+
+ // Maximum SU(6) weight by diquark type.
+ double barCGMax[8];
+ barCGMax[ud0] = baryonCGMax[0];
+ barCGMax[ud1] = baryonCGMax[4];
+ barCGMax[uu1] = baryonCGMax[2];
+ barCGMax[us0] = baryonCGMax[0];
+ barCGMax[su0] = baryonCGMax[0];
+ barCGMax[us1] = baryonCGMax[4];
+ barCGMax[su1] = baryonCGMax[4];
+ barCGMax[ss1] = baryonCGMax[2];
+
+ // Diquark SU(6) survival = Sum_quark (quark tunnel weight) * SU(6).
+ double dMB[8];
+ dMB[ud0] = 2. * baryonCGSum[0] + probStoUD * baryonCGSum[1];
+ dMB[ud1] = 2. * baryonCGSum[4] + probStoUD * baryonCGSum[5];
+ dMB[uu1] = baryonCGSum[2] + (1. + probStoUD) * baryonCGSum[3];
+ dMB[us0] = (1. + probStoUD) * baryonCGSum[0] + baryonCGSum[1];
+ dMB[su0] = dMB[us0];
+ dMB[us1] = (1. + probStoUD) * baryonCGSum[4] + baryonCGSum[5];
+ dMB[su1] = dMB[us1];
+ dMB[ss1] = probStoUD * baryonCGSum[2] + 2. * baryonCGSum[3];
+ for (int i = 1; i < 8; ++i) dMB[i] = dMB[i] / dMB[0];
+
+ // Tunneling factors for diquark production; only half a pair = sqrt.
+ double probStoUDroot = sqrt(probStoUD);
+ double probSQtoQQroot = sqrt(probSQtoQQ);
+ double probQQ1toQQ0root = sqrt(probQQ1toQQ0);
+ double qBB[8];
+ qBB[ud1] = probQQ1toQQ0root;
+ qBB[uu1] = probQQ1toQQ0root;
+ qBB[us0] = probSQtoQQroot;
+ qBB[su0] = probStoUDroot * probSQtoQQroot;
+ qBB[us1] = probQQ1toQQ0root * qBB[us0];
+ qBB[su1] = probQQ1toQQ0root * qBB[su0];
+ qBB[ss1] = probStoUDroot * pow2(probSQtoQQroot) * probQQ1toQQ0root;
+
+ // spin * (vertex factor) * (half-tunneling factor above).
+ double qBM[8];
+ qBM[ud1] = 3. * qBB[ud1];
+ qBM[uu1] = 6. * qBB[uu1];
+ qBM[us0] = probStoUD * qBB[us0];
+ qBM[su0] = qBB[su0];
+ qBM[us1] = probStoUD * 3. * qBB[us1];
+ qBM[su1] = 3. * qBB[su1];
+ qBM[ss1] = probStoUD * 6. * qBB[ss1];
+
+ // Combine above two into total diquark weight for q -> B Bbar.
+ for (int i = 1; i < 8; ++i) qBB[i] = qBB[i] * qBM[i];
+
+ // Suppression from having strange popcorn meson.
+ qBM[us0] *= popcornSmeson;
+ qBM[us1] *= popcornSmeson;
+ qBM[ss1] *= popcornSmeson;
+
+ // Suppression for a heavy quark of a diquark to fit into a baryon
+ // on the other side of popcorn meson: (0) s/u for q -> B M;
+ // (1) s/u for rank 0 diquark su -> M B; (2) ditto for s -> c/b.
+ double uNorm = 1. + qBM[ud1] + qBM[uu1] + qBM[us0] + qBM[us1];
+ scbBM[0] = (2. * (qBM[su0] + qBM[su1]) + qBM[ss1]) / uNorm;
+ scbBM[1] = scbBM[0] * popcornSpair * qBM[su0] / qBM[us0];
+ scbBM[2] = (1. + qBM[ud1]) * (2. + qBM[us0]) / uNorm;
+
+ // Include maximum of Clebsch-Gordan coefficients.
+ for (int i = 1; i < 8; ++i) dMB[i] *= qBM[i];
+ for (int i = 1; i < 8; ++i) qBM[i] *= barCGMax[i] / barCGMax[0];
+ for (int i = 1; i < 8; ++i) qBB[i] *= barCGMax[i] / barCGMax[0];
+
+ // Popcorn fraction for normal diquark production.
+ double qNorm = uNorm * popcornRate / 3.;
+ double sNorm = scbBM[0] * popcornSpair;
+ popFrac = qNorm * (1. + qBM[ud1] + qBM[uu1] + qBM[us0] + qBM[us1]
+ + sNorm * (qBM[su0] + qBM[su1] + 0.5 * qBM[ss1])) / (1. + qBB[ud1]
+ + qBB[uu1] + 2. * (qBB[us0] + qBB[us1]) + 0.5 * qBB[ss1]);
+
+ // Popcorn fraction for rank 0 diquarks, depending on number of s quarks.
+ popS[0] = qNorm * qBM[ud1] / qBB[ud1];
+ popS[1] = qNorm * 0.5 * (qBM[us1] / qBB[us1]
+ + sNorm * qBM[su1] / qBB[su1]);
+ popS[2] = qNorm * sNorm * qBM[ss1] / qBB[ss1];
+
+ // Recombine diquark weights to flavour and spin ratios. Second index:
+ // 0 = s/u popcorn quark ratio.
+ // 1, 2 = s/u ratio for vertex quark if popcorn quark is u/d or s.
+ // 3 = q/q' vertex quark ratio if popcorn quark is light and = q.
+ // 4, 5, 6 = (spin 1)/(spin 0) ratio for su, us and ud.
+
+ // Case 0: q -> B B.
+ dWT[0][0] = (2. * (qBB[su0] + qBB[su1]) + qBB[ss1])
+ / (1. + qBB[ud1] + qBB[uu1] + qBB[us0] + qBB[us1]);
+ dWT[0][1] = 2. * (qBB[us0] + qBB[us1]) / (1. + qBB[ud1] + qBB[uu1]);
+ dWT[0][2] = qBB[ss1] / (qBB[su0] + qBB[su1]);
+ dWT[0][3] = qBB[uu1] / (1. + qBB[ud1] + qBB[uu1]);
+ dWT[0][4] = qBB[su1] / qBB[su0];
+ dWT[0][5] = qBB[us1] / qBB[us0];
+ dWT[0][6] = qBB[ud1];
+
+ // Case 1: q -> B M B.
+ dWT[1][0] = (2. * (qBM[su0] + qBM[su1]) + qBM[ss1])
+ / (1. + qBM[ud1] + qBM[uu1] + qBM[us0] + qBM[us1]);
+ dWT[1][1] = 2. * (qBM[us0] + qBM[us1]) / (1. + qBM[ud1] + qBM[uu1]);
+ dWT[1][2] = qBM[ss1] / (qBM[su0] + qBM[su1]);
+ dWT[1][3] = qBM[uu1] / (1. + qBM[ud1] + qBM[uu1]);
+ dWT[1][4] = qBM[su1] / qBM[su0];
+ dWT[1][5] = qBM[us1] / qBM[us0];
+ dWT[1][6] = qBM[ud1];
+
+ // Case 2: qq -> M B; diquark inside chain.
+ dWT[2][0] = (2. * (dMB[su0] + dMB[su1]) + dMB[ss1])
+ / (1. + dMB[ud1] + dMB[uu1] + dMB[us0] + dMB[us1]);
+ dWT[2][1] = 2. * (dMB[us0] + dMB[us1]) / (1. + dMB[ud1] + dMB[uu1]);
+ dWT[2][2] = dMB[ss1] / (dMB[su0] + dMB[su1]);
+ dWT[2][3] = dMB[uu1] / (1. + dMB[ud1] + dMB[uu1]);
+ dWT[2][4] = dMB[su1] / dMB[su0];
+ dWT[2][5] = dMB[us1] / dMB[us0];
+ dWT[2][6] = dMB[ud1];
+
+}
+
+//*********
+
+// Pick a new flavour (including diquarks) given an incoming one.
+
+FlavContainer StringFlav::pick(FlavContainer& flavOld) {
+
+ // Initial values for new flavour.
+ FlavContainer flavNew;
+ flavNew.rank = flavOld.rank + 1;
+
+ // For original diquark assign popcorn quark and whether popcorn meson.
+ int idOld = abs(flavOld.id);
+ if (flavOld.rank == 0 && idOld > 1000) assignPopQ(flavOld);
+
+ // Diquark exists, to be forced into baryon now.
+ bool doOldBaryon = (idOld > 1000 && flavOld.nPop == 0);
+ // Diquark exists, but do meson now.
+ bool doPopcornMeson = flavOld.nPop > 0;
+ // Newly created diquark gives baryon now, antibaryon later.
+ bool doNewBaryon = false;
+
+ // Choose whether to generate a new meson or a new baryon.
+ if (!doOldBaryon && !doPopcornMeson && probQandQQ * Rndm::flat() > 1.) {
+ doNewBaryon = true;
+ if ((1. + popFrac) * Rndm::flat() > 1.) flavNew.nPop = 1;
+ }
+
+ // Optional suppression of first-rank baryon.
+ if (flavOld.rank == 0 && doNewBaryon && suppressLeadingB) {
+ double leadingBSup = (idOld < 4) ? lightLeadingBSup : heavyLeadingBSup;
+ if (Rndm::flat() > leadingBSup) {
+ doNewBaryon = false;
+ flavNew.nPop = 0;
+ }
+ }
+
+ // Single quark for new meson or for baryon where diquark already exists.
+ if (!doPopcornMeson && !doNewBaryon) {
+ flavNew.id = pickLightQ();
+ if ( (flavOld.id > 0 && flavOld.id < 9) || flavOld.id < -1000 )
+ flavNew.id = -flavNew.id;
+
+ // Done for simple-quark case.
+ return flavNew;
+ }
+
+ // Case: 0 = q -> B B, 1 = q -> B M B, 2 = qq -> M B.
+ int iCase = flavNew.nPop;
+ if (flavOld.nPop == 1) iCase = 2;
+
+ // Flavour of popcorn quark (= q shared between B and Bbar).
+ if (doNewBaryon) {
+ double sPopWT = dWT[iCase][0];
+ if (iCase == 1) sPopWT *= scbBM[0] * popcornSpair;
+ double rndmFlav = (2. + sPopWT) * Rndm::flat();
+ flavNew.idPop = 1;
+ if (rndmFlav > 1.) flavNew.idPop = 2;
+ if (rndmFlav > 2.) flavNew.idPop = 3;
+ } else flavNew.idPop = flavOld.idPop;
+
+ // Flavour of vertex quark.
+ double sVtxWT = dWT[iCase][1];
+ if (flavNew.idPop >= 3) sVtxWT = dWT[iCase][2];
+ if (flavNew.idPop > 3) sVtxWT *= 0.5 * (1. + 1./dWT[iCase][4]);
+ double rndmFlav = (2. + sVtxWT) * Rndm::flat();
+ flavNew.idVtx = 1;
+ if (rndmFlav > 1.) flavNew.idVtx = 2;
+ if (rndmFlav > 2.) flavNew.idVtx = 3;
+
+ // Special case for light flavours, possibly identical.
+ if (flavNew.idPop < 3 && flavNew.idVtx < 3) {
+ flavNew.idVtx = flavNew.idPop;
+ if (Rndm::flat() > dWT[iCase][3]) flavNew.idVtx = 3 - flavNew.idPop;
+ }
+
+ // Pick 2 * spin + 1.
+ int spin = 3;
+ if (flavNew.idVtx != flavNew.idPop) {
+ double spinWT = dWT[iCase][6];
+ if (flavNew.idVtx == 3) spinWT = dWT[iCase][5];
+ if (flavNew.idPop >= 3) spinWT = dWT[iCase][4];
+ if ((1. + spinWT) * Rndm::flat() < 1.) spin = 1;
+ }
+
+ // Form outgoing diquark. Done.
+ flavNew.id = 1000 * max(flavNew.idVtx, flavNew.idPop)
+ + 100 * min(flavNew.idVtx, flavNew.idPop) + spin;
+ if ( (flavOld.id < 0 && flavOld.id > -9) || flavOld.id > 1000 )
+ flavNew.id = -flavNew.id;
+ return flavNew;
+
+}
+
+//*********
+
+// Combine two flavours (including diquarks) to produce a hadron.
+// The weighting of the combination may fail, giving output 0.
+
+int StringFlav::combine(FlavContainer& flav1, FlavContainer& flav2) {
+
+ // Recognize largest and smallest flavour.
+ int id1Abs = abs(flav1.id);
+ int id2Abs = abs(flav2.id);
+ int idMax = max(id1Abs, id2Abs);
+ int idMin = min(id1Abs, id2Abs);
+
+ // Construct a meson.
+ if (idMax < 9 || idMin > 1000) {
+
+ // Popcorn meson: use only vertex quarks.
+ if (idMin > 1000) {
+ id1Abs = flav1.idVtx;
+ id2Abs = flav2.idVtx;
+ idMax = max(id1Abs, id2Abs);
+ idMin = min(id1Abs, id2Abs);
+ }
+
+ // Pick spin state and preliminary code.
+ int flav = (idMax < 3) ? 0 : idMax - 2;
+ double rndmSpin = mesonRateSum[flav] * Rndm::flat();
+ int spin = -1;
+ do rndmSpin -= mesonRate[flav][++spin];
+ while (rndmSpin > 0.);
+ int idMeson = 100 * idMax + 10 * idMin + mesonMultipletCode[spin];
+
+ // For nondiagonal mesons distinguish particle/antiparticle.
+ if (idMax != idMin) {
+ int sign = (idMax%2 == 0) ? 1 : -1;
+ if ( (idMax == id1Abs && flav1.id < 0)
+ || (idMax == id2Abs && flav2.id < 0) ) sign = -sign;
+ idMeson *= sign;
+
+ // For light diagonal mesons include uubar - ddbar - ssbar mixing.
+ } else if (flav < 2) {
+ double rMix = Rndm::flat();
+ if (rMix < mesonMix1[flav][spin]) idMeson = 110;
+ else if (rMix < mesonMix2[flav][spin]) idMeson = 220;
+ else idMeson = 330;
+ idMeson += mesonMultipletCode[spin];
+
+ // Additional suppression of eta and eta' may give failure.
+ if (idMeson == 221 && etaSup < Rndm::flat()) return 0;
+ if (idMeson == 331 && etaPrimeSup < Rndm::flat()) return 0;
+ }
+
+ // Finished for mesons.
+ return idMeson;
+ }
+
+ // SU(6) factors for baryon production may give failure.
+ int idQQ1 = idMax / 1000;
+ int idQQ2 = (idMax / 100) % 10;
+ int spinQQ = idMax % 10;
+ int spinFlav = spinQQ - 1;
+ if (spinFlav == 2 && idQQ1 != idQQ2) spinFlav = 4;
+ if (idMin != idQQ1 && idMin != idQQ2) spinFlav++;
+ if (baryonCGSum[spinFlav] < Rndm::flat() * baryonCGMax[spinFlav])
+ return 0;
+
+ // Order quarks to form baryon. Pick spin.
+ int idOrd1 = max( idMin, max( idQQ1, idQQ2) );
+ int idOrd3 = min( idMin, min( idQQ1, idQQ2) );
+ int idOrd2 = idMin + idQQ1 + idQQ2 - idOrd1 - idOrd3;
+ int spinBar = (baryonCGSum[spinFlav] * Rndm::flat()
+ < baryonCGOct[spinFlav]) ? 2 : 4;
+
+ // Distinguish Lambda- and Sigma-like.
+ bool LambdaLike = false;
+ if (spinBar == 2 && idOrd1 > idOrd2 && idOrd2 > idOrd3) {
+ LambdaLike = (spinQQ == 1);
+ if (idOrd1 != idMin && spinQQ == 1) LambdaLike = (Rndm::flat() < 0.25);
+ else if (idOrd1 != idMin) LambdaLike = (Rndm::flat() < 0.75);
+ }
+
+ // Form baryon code and return with sign.
+ int idBaryon = (LambdaLike)
+ ? 1000 * idOrd1 + 100 * idOrd3 + 10 * idOrd2 + spinBar
+ : 1000 * idOrd1 + 100 * idOrd2 + 10 * idOrd3 + spinBar;
+ return (flav1.id > 0) ? idBaryon : -idBaryon;
+
+}
+
+//*********
+
+// Assign popcorn quark inside an original (= rank 0) diquark.
+
+void StringFlav::assignPopQ(FlavContainer& flav) {
+
+ // Safety check that intended to do something.
+ int idAbs = abs(flav.id);
+ if (flav.rank > 0 || idAbs < 1000) return;
+
+ // Make choice of popcorn quark.
+ int id1 = (idAbs/1000)%10;
+ int id2 = (idAbs/100)%10;
+ double pop2WT = 1.;
+ if (id1 == 3) pop2WT = scbBM[1];
+ else if (id1 > 3) pop2WT = scbBM[2];
+ if (id2 == 3) pop2WT /= scbBM[1];
+ else if (id2 > 3) pop2WT /= scbBM[2];
+ // Agrees with Patrik code, but opposite to intention??
+ flav.idPop = ((1. + pop2WT) * Rndm::flat() > 1.) ? id2 : id1;
+ flav.idVtx = id1 + id2 - flav.idPop;
+
+ // Also determine if to produce popcorn meson.
+ flav.nPop = 0;
+ double popWT = popS[0];
+ if (id1 == 3) popWT = popS[1];
+ if (id2 == 3) popWT = popS[2];
+ if (idAbs%10 == 1) popWT *= sqrt(probQQ1toQQ0);
+ if ((1. + popWT) * Rndm::flat() > 1.) flav.nPop = 1;
+
+}
+
+//*********
+
+// Combine two quarks to produce a diquark.
+// Normally according to production composition, but nonvanishing idHad
+// means diquark from known hadron content, so use SU(6) wave fucntion.
+
+int StringFlav::makeDiquark(int id1, int id2, int idHad) {
+
+ // Initial values.
+ int idMin = min( abs(id1), abs(id2));
+ int idMax = max( abs(id1), abs(id2));
+ int spin = 1;
+
+ // Select spin of diquark formed from two valence quarks in proton.
+ // (More hadron cases??)
+ if (abs(idHad) == 2212) {
+ if (idMin == 1 && idMax == 2 && Rndm::flat() < 0.75) spin = 0;
+
+ // Else select spin of diquark according to production composition.
+ } else {
+ if (idMin != idMax && Rndm::flat() > probQQ1norm) spin = 0;
+ }
+
+ // Combined diquark code.
+ int idNewAbs = 1000 * idMax + 100 * idMin + 2 * spin + 1;
+ return (id1 > 0) ? idNewAbs : -idNewAbs;
+
+}
+
+//**************************************************************************
+
+// The StringZ class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// When a or c are close to special cases, default to these.
+const double StringZ::CFROMUNITY = 0.01;
+const double StringZ::AFROMZERO = 0.02;
+const double StringZ::AFROMC = 0.01;
+
+// Do not take exponent of too large or small number.
+const double StringZ::EXPMAX = 50.;
+
+//*********
+
+// Initialize data members of the string z selection.
+
+void StringZ::init() {
+
+ // c and b quark masses.
+ mc2 = pow2( ParticleDataTable::m0(4));
+ mb2 = pow2( ParticleDataTable::m0(5));
+
+ // Paramaters of Lund/Bowler symmetric fragmentation function.
+ aLund = Settings::parm("StringZ:aLund");
+ bLund = Settings::parm("StringZ:bLund");
+ aExtraDiquark = Settings::parm("StringZ:aExtraDiquark");
+ rFactC = Settings::parm("StringZ:rFactC");
+ rFactB = Settings::parm("StringZ:rFactB");
+ rFactH = Settings::parm("StringZ:rFactH");
+
+ // Flags and parameters of Peterson/SLAC fragmentation function.
+ usePetersonC = Settings::flag("StringZ:usePetersonC");
+ usePetersonB = Settings::flag("StringZ:usePetersonB");
+ usePetersonH = Settings::flag("StringZ:usePetersonH");
+ epsilonC = Settings::parm("StringZ:epsilonC");
+ epsilonB = Settings::parm("StringZ:epsilonB");
+ epsilonH = Settings::parm("StringZ:epsilonH");
+
+}
+
+//*********
+
+// Generate the fraction z that the next hadron will take,
+// using either Lund/Bowler or, for heavy, Peterson/SLAC functions.
+// Note: for a heavy new coloured particle we assume pT negligible.
+
+double StringZ::zFrag( int idOld, int idNew, double mT2) {
+
+ // Find if old or new flavours correspond to diquarks.
+ int idOldAbs = abs(idOld);
+ int idNewAbs = abs(idNew);
+ bool isOldDiquark = (idOldAbs > 1000 && idOldAbs < 10000);
+ bool isNewDiquark = (idNewAbs > 1000 && idNewAbs < 10000);
+
+ // Find heaviest quark in fragmenting parton/diquark.
+ int idFrag = idOldAbs;
+ if (isOldDiquark) idFrag = max( idOldAbs / 1000, (idOldAbs / 100) % 10);
+
+ // Use Peterson where explicitly requested for heavy flavours.
+ if (idFrag == 4 && usePetersonC) return zPeterson( epsilonC);
+ if (idFrag == 5 && usePetersonB) return zPeterson( epsilonB);
+ if (idFrag > 5 && usePetersonH) {
+ double epsilon = epsilonH * mb2 / mT2;
+ return zPeterson( epsilon);
+ }
+
+ // Shape parameters of Lund symmetric fragmentation function.
+ double aShape = aLund;
+ if (isOldDiquark) aShape += aExtraDiquark;
+ double bShape = bLund * mT2;
+ double cShape = 1.;
+ if (isOldDiquark) cShape -= aExtraDiquark;
+ if (isNewDiquark) cShape += aExtraDiquark;
+ if (idFrag == 4) cShape += rFactC * bLund * mc2;
+ if (idFrag == 5) cShape += rFactB * bLund * mb2;
+ if (idFrag > 5) cShape += rFactH * bLund * mT2;
+ return zLund( aShape, bShape, cShape);
+
+}
+
+//*********
+
+// Generate a random z according to the Lund/Bowler symmetric
+// fragmentation function f(z) = (1 -z)^a * exp(-b/z) / z^c.
+// Normalized so that f(z_max) = 1 it can also be written as
+// f(z) = exp( a * ln( (1 - z) / (1 - z_max) ) + b * (1/z_max - 1/z)
+// + c * ln(z_max/z) ).
+
+double StringZ::zLund( double a, double b, double c) {
+
+ // Special cases for c = 1, a = 0 and a = c.
+ bool cIsUnity = (abs( c - 1.) < CFROMUNITY);
+ bool aIsZero = (a < AFROMZERO);
+ bool aIsC = (abs(a - c) < AFROMC);
+
+ // Determine position of maximum.
+ double zMax;
+ if (aIsZero) zMax = (c > b) ? b / c : 1.;
+ else if (aIsC) zMax = b / (b + c);
+ else { zMax = 0.5 * (b + c - sqrt( pow2(b - c) + 4. * a * b)) / (c - a);
+ if (zMax > 0.9999 && b > 100.) zMax = min(zMax, 1. - a / b); }
+
+ // Subdivide z range if distribution very peaked near either endpoint.
+ bool peakedNearZero = (zMax < 0.1);
+ bool peakedNearUnity = (zMax > 0.85 && b > 1.);
+
+ // Find integral of trial function everywhere bigger than f.
+ // (Dummy start values.)
+ double fIntLow = 1.;
+ double fIntHigh = 1.;
+ double fInt = 2.;
+ double zDiv = 0.5;
+ double zDivC = 0.5;
+ // When z_max is small use that f(z)
+ // < 1 for z < z_div = 2.75 * z_max,
+ // < (z_div/z)^c for z > z_div (=> logarithm for c = 1, else power).
+ if (peakedNearZero) {
+ zDiv = 2.75 * zMax;
+ fIntLow = zDiv;
+ if (cIsUnity) fIntHigh = -zDiv * log(zDiv);
+ else { zDivC = pow( zDiv, 1. - c);
+ fIntHigh = zDiv * (1. - 1./zDivC) / (c - 1.);}
+ fInt = fIntLow + fIntHigh;
+ // When z_max large use that f(z)
+ // < exp( b * (z - z_div) ) for z < z_div with z_div messy expression,
+ // < 1 for z > z_div.
+ // To simplify expressions the integral is extended to z = -infinity.
+ } else if (peakedNearUnity) {
+ double rcb = sqrt(4. + pow2(c / b));
+ zDiv = rcb - 1./zMax - (c / b) * log( zMax * 0.5 * (rcb + c / b) );
+ if (!aIsZero) zDiv += (a/b) * log(1. - zMax);
+ zDiv = min( zMax, max(0., zDiv));
+ fIntLow = 1. / b;
+ fIntHigh = 1. - zDiv;
+ fInt = fIntLow + fIntHigh;
+ }
+
+ // Choice of z, preweighted for peaks at low or high z. (Dummy start values.)
+ double z = 0.5;
+ double fPrel = 1.;
+ double fVal = 1.;
+ do {
+ // Choice of z flat good enough for distribution peaked in the middle;
+ // if not this z can be reused as a random number in general.
+ z = Rndm::flat();
+ fPrel = 1.;
+ // When z_max small use flat below z_div and 1/z^c above z_div.
+ if (peakedNearZero) {
+ if (fInt * Rndm::flat() < fIntLow) z = zDiv * z;
+ else if (cIsUnity) {z = pow( zDiv, z); fPrel = zDiv / z;}
+ else { z = pow( zDivC + (1. - zDivC) * z, 1. / (1. - c) );
+ fPrel = pow( zDiv / z, c); }
+ // When z_max large use exp( b * (z -z_div) ) below z_div and flat above it.
+ } else if (peakedNearUnity) {
+ if (fInt * Rndm::flat() < fIntLow) {
+ z = zDiv + log(z) / b;
+ fPrel = exp( b * (z - zDiv) );
+ } else z = zDiv + (1. - zDiv) * z;
+ }
+
+ // Evaluate actual f(z) (if in physical range) and correct.
+ if (z > 0 && z < 1) {
+ double fExp = b * (1. / zMax - 1. / z)+ c * log(zMax / z);
+ if (!aIsZero) fExp += a * log( (1. - z) / (1. - zMax) );
+ fVal = exp( max( -EXPMAX, min( EXPMAX, fExp) ) ) ;
+ } else fVal = 0.;
+ } while (fVal < Rndm::flat() * fPrel);
+
+ // Done.
+ return z;
+
+}
+
+//*********
+
+// Generate a random z according to the Peterson/SLAC formula
+// f(z) = 1 / ( z * (1 - 1/z - epsilon/(1-z))^2 )
+// = z * (1-z)^2 / ((1-z)^2 + epsilon * z)^2.
+
+double StringZ::zPeterson( double epsilon) {
+
+ double z, fVal;
+
+ // For large epsilon pick z flat and reject,
+ // knowing that 4 * epsilon * f(z) < 1 everywhere.
+ if (epsilon > 0.01) {
+ do {
+ z = Rndm::flat();
+ fVal = 4. * epsilon * z * pow2(1. - z)
+ / pow2( pow2(1. - z) + epsilon * z);
+ } while (fVal < Rndm::flat());
+ return z;
+ }
+
+ // Else split range, using that 4 * epsilon * f(z)
+ // < 4 * epsilon / (1 - z)^2 for 0 < z < 1 - 2 * sqrt(epsilon)
+ // < 1 for 1 - 2 * sqrt(epsilon) < z < 1
+ double epsRoot = sqrt(epsilon);
+ double epsComb = 0.5 / epsRoot - 1.;
+ double fIntLow = 4. * epsilon * epsComb;
+ double fInt = fIntLow + 2. * epsRoot;
+ do {
+ if (Rndm::flat() * fInt < fIntLow) {
+ z = 1. - 1. / (1. + Rndm::flat() * epsComb);
+ fVal = z * pow2( pow2(1. - z) / (pow2(1. - z) + epsilon * z) );
+ } else {
+ z = 1. - 2. * epsRoot * Rndm::flat();
+ fVal = 4. * epsilon * z * pow2(1. - z)
+ / pow2( pow2(1. - z) + epsilon * z);
+ }
+ } while (fVal < Rndm::flat());
+ return z;
+
+}
+
+//**************************************************************************
+
+// The StringPT class.
+
+//*********
+
+// Initialize data members of the string pT selection.
+
+void StringPT::init() {
+
+ // Parameters of the pT width and enhancement.
+ sigmaQ = Settings::parm("StringPT:sigma") / sqrt(2.);
+ enhancedFraction = Settings::parm("StringPT:enhancedFraction");
+ enhancedWidth = Settings::parm("StringPT:enhancedWidth");
+
+}
+
+//*********
+
+// Generate Gaussian pT such that <p_x^2> = <p_x^2> = sigma^2 = width^2/2,
+// but with small fraction multiplied up to a broader spectrum.
+
+double StringPT::pxy() {
+
+ double pxyNow = sigmaQ * Rndm::gauss();
+ if (Rndm::flat() < enhancedFraction) pxyNow *= enhancedWidth;
+ return pxyNow;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// FragmentationSystems.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// ColConfig, StringRegion and StringSystem classes.
+
+#include "FragmentationSystems.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ColConfig class.
+
+//*********
+
+// Initialize and save pointers.
+
+void ColConfig::init(StringFlav* flavSelPtrIn) {
+
+ // Save pointer.
+ flavSelPtr = flavSelPtrIn;
+
+ // Joining of nearby partons along the string.
+ mJoin = Settings::parm("FragmentationSystems:mJoin");
+
+ // For consistency ensure that mJoin is bigger than in StringRegion.
+ mJoin = max( mJoin, 2. * StringRegion::MJOIN);
+
+ // Simplification of q q q junction topology to quark - diquark one.
+ mJoinJunction = Settings::parm("FragmentationSystems:mJoinJunction");
+ mStringMin = Settings::parm("HadronLevel:mStringMin");
+
+}
+
+//*********
+
+// Insert a new colour singlet system in ascending mass order.
+// Calculate its properties. Join nearby partons.
+
+void ColConfig::insert( vector<int>& iPartonIn, Event& event) {
+
+ // Find momentum and invariant mass of system, minus endpoint masses.
+ Vec4 pSumIn;
+ double mSumIn = 0.;
+ bool hasJunctionIn = false;
+ for (int i = 0; i < int(iPartonIn.size()); ++i) {
+ if (iPartonIn[i] < 0) {
+ hasJunctionIn = true;
+ continue;
+ }
+ pSumIn += event[ iPartonIn[i] ].p();
+ if (!event[ iPartonIn[i] ].isGluon())
+ mSumIn += event[ iPartonIn[i] ].constituentMass();
+ }
+ double massIn = pSumIn.mCalc();
+ double massExcessIn = massIn - mSumIn;
+
+ // Identify closed gluon loop. Assign "endpoint" masses as light quarks.
+ bool isClosedIn = (iPartonIn[0] >= 0 && event[ iPartonIn[0] ].isGluon());
+ if (isClosedIn) massExcessIn -= 2. * ParticleDataTable::constituentMass(1);
+
+ // For junction topology: join two nearby legs into a diquark.
+ if (hasJunctionIn && joinJunction( iPartonIn, event, massExcessIn))
+ hasJunctionIn = false;
+
+ // Loop while > 2 partons left and hope of finding joining pair.
+ bool hasJoined = true;
+ while (hasJoined && iPartonIn.size() > 2) {
+
+ // Look for the pair of neighbour partons (along string) with
+ // the smallest invariant mass (subtracting quark masses).
+ int iJoinMin = -1;
+ double mJoinMin = 2. * mJoin;
+ int nSize = iPartonIn.size();
+ int nPair = (isClosedIn) ? nSize : nSize - 1;
+ for (int i = 0; i < nPair; ++i) {
+ // Keep three legs of junction separate.
+ if (iPartonIn[i] < 0 || iPartonIn[(i + 1)%nSize] < 0) continue;
+ Particle& parton1 = event[ iPartonIn[i] ];
+ Particle& parton2 = event[ iPartonIn[(i + 1)%nSize] ];
+ Vec4 pSumNow;
+ pSumNow += (parton1.isGluon()) ? 0.5 * parton1.p() : parton1.p();
+ pSumNow += (parton2.isGluon()) ? 0.5 * parton2.p() : parton2.p();
+ double mJoinNow = pSumNow.mCalc();
+ if (!parton1.isGluon()) mJoinNow -= parton1.m();
+ if (!parton2.isGluon()) mJoinNow -= parton2.m();
+ if (mJoinNow < mJoinMin) { iJoinMin = i; mJoinMin = mJoinNow; }
+ }
+
+ // If sufficiently nearby then join into one new parton.
+ // Note: error sensitivity to mJoin indicates unstable precedure??
+ hasJoined = false;
+ if (mJoinMin < mJoin) {
+ int iJoin1 = iPartonIn[iJoinMin];
+ int iJoin2 = iPartonIn[(iJoinMin + 1)%nSize];
+ int idNew = (event[iJoin1].isGluon()) ? event[iJoin2].id()
+ : event[iJoin1].id();
+ int colNew = event[iJoin1].col();
+ int acolNew = event[iJoin2].acol();
+ if (colNew == acolNew) {
+ colNew = event[iJoin2].col();
+ acolNew = event[iJoin1].acol();
+ }
+ Vec4 pNew = event[iJoin1].p() + event[iJoin2].p();
+
+ // Append joined parton to event record.
+ int iNew = event.append( idNew, 73, min(iJoin1, iJoin2),
+ max(iJoin1, iJoin2), 0, 0, colNew, acolNew, pNew, pNew.mCalc() );
+
+ // Mark joined partons and reduce remaining system.
+ event[iJoin1].statusNeg();
+ event[iJoin2].statusNeg();
+ event[iJoin1].daughter1(iNew);
+ event[iJoin2].daughter1(iNew);
+ if (iJoinMin == nSize - 1) iPartonIn[0] = iNew;
+ else {
+ iPartonIn[iJoinMin] = iNew;
+ for (int i = iJoinMin + 1; i < nSize - 1; ++i)
+ iPartonIn[i] = iPartonIn[i + 1];
+ }
+ iPartonIn.pop_back();
+
+ // If joined,then loopback to look for more.
+ hasJoined = true;
+ }
+ }
+
+ // Store new colour singlet system at the end.
+ singlets.push_back( ColSinglet(iPartonIn, pSumIn, massIn,
+ massExcessIn, hasJunctionIn, isClosedIn) );
+
+ // Now move around, so that smallest mass excesses come first.
+ int iInsert = singlets.size() - 1;
+ for (int iSub = singlets.size() - 2; iSub >= 0; --iSub) {
+ if (massExcessIn > singlets[iSub].massExcess) break;
+ singlets[iSub + 1] = singlets[iSub];
+ iInsert = iSub;
+ }
+ if (iInsert < int(singlets.size()) - 1) singlets[iInsert] =
+ ColSinglet(iPartonIn, pSumIn, massIn, massExcessIn,
+ hasJunctionIn, isClosedIn);
+
+}
+
+//*********
+
+// Join two legs of junction to a diquark for small invariant masses.
+// Note: for junction system, iPartonIn points to structure
+// (-code0) g...g.q0 (-code1) g...g.q1 (-code2) g...g.q2
+
+bool ColConfig::joinJunction( vector<int>& iPartonIn, Event& event,
+ double massExcessIn) {
+
+ // Find four-momentum and endpoint quarks and masses on the three legs.
+ Vec4 pLeg[3];
+ double mLeg[3];
+ int idAbsLeg[3];
+ int leg = -1;
+ for (int i = 0; i < int(iPartonIn.size()); ++ i) {
+ if (iPartonIn[i] < 0) ++leg;
+ else {
+ pLeg[leg] += event[ iPartonIn[i] ].p();
+ mLeg[leg] = event[ iPartonIn[i] ].m();
+ idAbsLeg[leg] = event[ iPartonIn[i] ].idAbs();
+ }
+ }
+
+ // Calculate invariant mass of three pairs, minus endpoint masses.
+ double m01 = (pLeg[0] + pLeg[1]).mCalc() - mLeg[0] - mLeg[1];
+ double m02 = (pLeg[0] + pLeg[2]).mCalc() - mLeg[0] - mLeg[2];
+ double m12 = (pLeg[1] + pLeg[2]).mCalc() - mLeg[1] - mLeg[2];
+
+ // Find lowest-mass pair not involving diquark.
+ double mMin = mJoinJunction + 1.;
+ int legA = -1;
+ int legB = -1;
+ if (m01 < mMin && idAbsLeg[0] < 9 && idAbsLeg[1] < 9) {
+ mMin = m01;
+ legA = 0;
+ legB = 1;
+ }
+ if (m02 < mMin && idAbsLeg[0] < 9 && idAbsLeg[2] < 9) {
+ mMin = m02;
+ legA = 0;
+ legB = 2;
+ }
+ if (m12 < mMin && idAbsLeg[1] < 9 && idAbsLeg[2] < 9) {
+ mMin = m12;
+ legA = 1;
+ legB = 2;
+ }
+ int legC = 3 - legA - legB;
+
+ // Nothing to do if no two legs have small invariant mass, and
+ // system as a whole is above MiniStringFragmentation threshold.
+ if (mMin > mJoinJunction && massExcessIn > mStringMin) return false;
+
+ // Construct separate index arrays for the three legs.
+ vector<int> iLegA, iLegB, iLegC;
+ leg = -1;
+ for (int i = 0; i < int(iPartonIn.size()); ++ i) {
+ if (iPartonIn[i] < 0) ++leg;
+ else if( leg == legA) iLegA.push_back( iPartonIn[i] );
+ else if( leg == legB) iLegB.push_back( iPartonIn[i] );
+ else if( leg == legC) iLegC.push_back( iPartonIn[i] );
+ }
+
+ // First step: successively combine any gluons on the two legs.
+ // (Presumably overkill; not likely to be (m)any extra gluons.)
+ // (Do as successive binary joinings, so only need two mothers.)
+ for (leg = 0; leg < 2; ++leg) {
+ vector<int>& iLegNow = (leg == 0) ? iLegA : iLegB;
+ int sizeNow = iLegNow.size();
+ for (int i = sizeNow - 2; i >= 0; --i) {
+ int iQ = iLegNow.back();
+ int iG = iLegNow[i];
+ int colNew = (event[iQ].id() > 0) ? event[iG].col() : 0;
+ int acolNew = (event[iQ].id() < 0) ? event[iG].acol() : 0;
+ Vec4 pNew = event[iQ].p() + event[iG].p();
+ int iNew = event.append( event[iQ].id(), 74, min(iQ, iG),
+ max(iQ, iG), 0, 0, colNew, acolNew, pNew, pNew.mCalc() );
+
+ // Mark joined partons and update iLeg end.
+ event[iQ].statusNeg();
+ event[iG].statusNeg();
+ event[iQ].daughter1(iNew);
+ event[iG].daughter1(iNew);
+ iLegNow.back() = iNew;
+ }
+ }
+
+ // Second step: combine two quarks into a diquark.
+ int iQA = iLegA.back();
+ int iQB = iLegB.back();
+ int idQA = event[iQA].id();
+ int idQB = event[iQB].id();
+ int idNew = flavSelPtr->makeDiquark( idQA, idQB );
+ // Diquark colour is opposite to parton closest to junction on third leg.
+ int colNew = (idNew > 0) ? 0 : event[ iLegC[0] ].acol();
+ int acolNew = (idNew > 0) ? event[ iLegC[0] ].col() : 0;
+ Vec4 pNew = pLeg[legA] + pLeg[legB];
+ int iNew = event.append( idNew, 74, min(iQA, iQB), max( iQA, iQB),
+ 0, 0, colNew, acolNew, pNew, pNew.mCalc() );
+
+ // Mark joined partons and reduce remaining system.
+ event[iQA].statusNeg();
+ event[iQB].statusNeg();
+ event[iQA].daughter1(iNew);
+ event[iQB].daughter1(iNew);
+ iPartonIn.resize(0);
+ iPartonIn.push_back( iNew);
+ for (int i = 0; i < int(iLegC.size()) ; ++i)
+ iPartonIn.push_back( iLegC[i]);
+
+ // Remove junction from event record list, identifying by colour.
+ int iJun = -1;
+ for (int i = 0; i < event.sizeJunction(); ++i)
+ for (int j = 0; j < 3; ++ j)
+ if ( event.colJunction(i,j) == max(colNew, acolNew) ) iJun = i;
+ if (iJun >= 0) event.eraseJunction(iJun);
+
+ // Done, having eliminated junction.
+ return true;
+
+}
+
+//*********
+
+// Collect all partons of singlet to be consecutively ordered.
+
+void ColConfig::collect(int iSub, Event& event) {
+
+ // Partons may already have been collected, e.g. at ministring collapse.
+ if (singlets[iSub].isCollected) return;
+ singlets[iSub].isCollected = true;
+
+ // Check if partons already "by chance" happen to be ordered.
+ bool inOrder = true;
+ for (int i = 0; i < singlets[iSub].size() - 1; ++i) {
+ int iFirst = singlets[iSub].iParton[i];
+ if (iFirst < 0) continue;
+ int iSecond = singlets[iSub].iParton[i + 1];
+ if (iSecond < 0) iSecond = singlets[iSub].iParton[i + 2];
+ if (iSecond != iFirst + 1) { inOrder = false; break;}
+ }
+ if (inOrder) return;
+
+ // Copy down system. Update current partons.
+ for (int i = 0; i < singlets[iSub].size(); ++i) {
+ int iOld = singlets[iSub].iParton[i];
+ if (iOld < 0) continue;
+ int iNew = event.copy(iOld, 71);
+ singlets[iSub].iParton[i] = iNew;
+ }
+
+ // Done.
+}
+
+//*********
+
+// List all currently identified singlets.
+
+void ColConfig::list(ostream& os) {
+
+ // Header. Loop over all individual singlets.
+ os << "\n -------- Colour Singlet Systems Listing -------------------\n";
+ for (int iSub = 0; iSub < int(singlets.size()); ++iSub) {
+
+ // List all partons belonging to each singlet.
+ os << " singlet " << iSub << " contains " ;
+ for (int i = 0; i < singlets[iSub].size(); ++i)
+ os << singlets[iSub].iParton[i] << " ";
+ os << "\n";
+
+ // Done.
+ }
+}
+
+//**************************************************************************
+
+// The StringRegion class.
+
+// Currently a number of simplifications, in particular ??
+// 1) No popcorn baryon production.
+// 2) Simplified treatment of pT in stepping and joining.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// If a string region is smaller thsan this it is assumed empty.
+const double StringRegion::MJOIN = 0.1;
+
+// Avoid division by zero.
+const double StringRegion::TINY = 1e-20;
+
+//*********
+
+// Set up four-vectors for longitudinal and transverse directions.
+
+void StringRegion::setUp(Vec4 p1, Vec4 p2, bool isMassless) {
+
+ // Simple case: the two incoming four-vectors guaranteed massless.
+ if (isMassless) {
+
+ // Calculate w2, minimum value. Lightcone directions = input.
+ w2 = 2. * (p1 * p2);
+ if (w2 < MJOIN*MJOIN) {isSetUp = true; isEmpty = true; return;}
+ pPos = p1;
+ pNeg = p2;
+
+ // Else allow possibility of masses for incoming partons (also gluons!).
+ } else {
+
+ // Generic four-momentum combinations.
+ double m1Sq = p1 * p1;
+ double m2Sq = p2 * p2;
+ double p1p2 = p1 * p2;
+ w2 = m1Sq + 2. * p1p2 + m2Sq;
+ double rootSq = pow2(p1p2) - m1Sq * m2Sq;
+
+ // If crazy kinematics (should not happen!) modify energies.
+ if (w2 <= 0. || rootSq <= 0.) {
+ if (m1Sq < 0.) m1Sq = 0.;
+ p1.e( sqrt(m1Sq + p1.pAbs2()) );
+ if (m2Sq < 0.) m2Sq = 0.;
+ p2.e( sqrt(m2Sq + p2.pAbs2()) );
+ p1p2 = p1 * p2;
+ w2 = m1Sq + 2. * p1p2 + m2Sq;
+ rootSq = pow2(p1p2) - m1Sq * m2Sq;
+ }
+
+ // If still small invariant mass then empty region (e.g. in gg system).
+ if (w2 < MJOIN*MJOIN) {isSetUp = true; isEmpty = true; return;}
+
+ // Find two lightconelike longitudinal four-vector directions.
+ double root = sqrt( max(TINY, rootSq) );
+ double k1 = 0.5 * ( (m2Sq + p1p2) / root - 1.);
+ double k2 = 0.5 * ( (m1Sq + p1p2) / root - 1.);
+ pPos = (1. + k1) * p1 - k2 * p2;
+ pNeg = (1. + k2) * p2 - k1 * p1;
+ }
+
+ // Find two spacelike transverse four-vector directions.
+ // Begin by picking two sensible trial directions.
+ Vec4 eDiff = pPos / pPos.e() - pNeg / pNeg.e();
+ double eDx = pow2( eDiff.px() );
+ double eDy = pow2( eDiff.py() );
+ double eDz = pow2( eDiff.pz() );
+ if (eDx < min(eDy, eDz)) {
+ eX = Vec4( 1., 0., 0., 0.);
+ eY = (eDy < eDz) ? Vec4( 0., 1., 0., 0.) : Vec4( 0., 0., 1., 0.);
+ } else if (eDy < eDz) {
+ eX = Vec4( 0., 1., 0., 0.);
+ eY = (eDx < eDz) ? Vec4( 1., 0., 0., 0.) : Vec4( 0., 0., 1., 0.);
+ } else {
+ eX = Vec4( 0., 0., 1., 0.);
+ eY = (eDx < eDy) ? Vec4( 1., 0., 0., 0.) : Vec4( 0., 1., 0., 0.);
+ }
+
+ // Then construct orthogonal linear combinations.
+ double pPosNeg = pPos * pNeg;
+ double kXPos = eX * pPos / pPosNeg;
+ double kXNeg = eX * pNeg / pPosNeg;
+ double kXX = 1. / sqrt( 1. + 2. * kXPos * kXNeg * pPosNeg );
+ double kYPos = eY * pPos / pPosNeg;
+ double kYNeg = eY * pNeg / pPosNeg;
+ double kYX = kXX * (kXPos * kYNeg + kXNeg * kYPos) * pPosNeg;
+ double kYY = 1. / sqrt(1. + 2. * kYPos * kYNeg * pPosNeg - pow2(kYX));
+ eX = kXX * (eX - kXNeg * pPos - kXPos * pNeg);
+ eY = kYY * (eY - kYNeg * pPos - kYPos * pNeg - kYX * eX);
+
+ // Done.
+ isSetUp = true;
+ isEmpty = false;
+
+}
+
+//*********
+
+// Project a four-momentum onto (x+, x-, px, py).
+
+void StringRegion::project(Vec4 pIn) {
+
+ // Perform projections by four-vector multiplication.
+ xPosProj = 2. * (pIn * pNeg) / w2;
+ xNegProj = 2. * (pIn * pPos) / w2;
+ pxProj = - (pIn * eX);
+ pyProj = - (pIn * eY);
+
+}
+
+//**************************************************************************
+
+// The StringSystem class.
+
+//*********
+
+// Set up system from parton list.
+
+void StringSystem::setUp(vector<int>& iSys, Event& event) {
+
+ // Figure out how big the system is. (Closed gluon loops?)
+ sizePartons = iSys.size();
+ sizeStrings = sizePartons - 1;
+ sizeRegions = (sizeStrings * (sizeStrings + 1)) / 2;
+ indxReg = 2 * sizeStrings + 1;
+ iMax = sizeStrings - 1;
+
+ // Reserve space for the required number of regions.
+ system.clear();
+ system.resize(sizeRegions);
+
+ // Set up the lowest-lying regions.
+ for (int i = 0; i < sizeStrings; ++i) {
+ Vec4 p1 = event[ iSys[i] ].p();
+ if ( event[ iSys[i] ].isGluon() ) p1 *= 0.5;
+ Vec4 p2 = event[ iSys[i+1] ].p();
+ if ( event[ iSys[i+1] ].isGluon() ) p2 *= 0.5;
+ system[ iReg(i, iMax - i) ].setUp( p1, p2, false);
+ }
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// HadronLevel.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the HadronLevel class.
+
+#include "HadronLevel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The HadronLevel class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// For breaking J-J string, pick a Gamma by taking a step with fictitious mass.
+const double HadronLevel::JJSTRINGM2MAX = 25.;
+const double HadronLevel::JJSTRINGM2FRAC = 0.1;
+
+// Iterate junction rest frame boost until convergence or too many tries.
+const double HadronLevel::CONVJNREST = 1e-5;
+const int HadronLevel::NTRYJNREST = 20;
+
+// Typical average transvere primary hadron mass <mThad>.
+const double HadronLevel::MTHAD = 0.9;
+
+//*********
+
+// Find settings. Initialize HadronLevel classes as required.
+
+bool HadronLevel::init(Info* infoPtrIn, TimeShower* timesDecPtr,
+ DecayHandler* decayHandlePtr, vector<int> handledParticles) {
+
+ // Save pointer.
+ infoPtr = infoPtrIn;
+
+ // Main flags.
+ doHadronize = Settings::flag("HadronLevel:Hadronize");
+ doDecay = Settings::flag("HadronLevel:Decay");
+ doBoseEinstein = Settings::flag("HadronLevel:BoseEinstein");
+
+ // Boundary mass between string and ministring handling.
+ mStringMin = Settings::parm("HadronLevel:mStringMin");
+
+ // For junction processing.
+ eNormJunction = Settings::parm("StringFragmentation:eNormJunction");
+
+ // Particles that should decay or not before Bose-Einstein stage.
+ widthSepBE = Settings::parm("BoseEinstein:widthSep");
+
+ // Initialize string and ministring fragmentation.
+ stringFrag.init(infoPtr, &flavSel, &pTSel, &zSel);
+ ministringFrag.init(infoPtr, &flavSel);
+
+ // Initialize particle decays.
+ decays.init(infoPtr, timesDecPtr, &flavSel, decayHandlePtr,
+ handledParticles);
+
+ // Initialize BoseEinstein.
+ boseEinstein.init(infoPtr);
+
+ // Initialize auxiliary administrative classes.
+ colConfig.init( &flavSel);
+
+ // Initialize auxiliary fragmentation classes.
+ flavSel.init();
+ pTSel.init();
+ zSel.init();
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Hadronize and decay the next parton-level.
+
+bool HadronLevel::next( Event& event) {
+
+ // Colour-octet onia states must be decayed to singlet + gluon.
+ if (!decayOctetOnia(event)) return false;
+
+ // Possibility of hadronization inside decay, but then no BE second time.
+ bool moreToDo;
+ bool doBoseEinsteinNow = doBoseEinstein;
+ do {
+ moreToDo = false;
+
+ // First part: string fragmentation.
+ if (doHadronize) {
+
+ // Find the complete colour singlet configuration of the event.
+ if (!findSinglets( event)) return false;
+
+ // Process all colour singlet (sub)system
+ for (int iSub = 0; iSub < colConfig.size(); ++iSub) {
+
+ // Collect sequentially all partons in a colour singlet subsystem.
+ colConfig.collect(iSub, event);
+
+ // String fragmentation of each colour singlet (sub)system.
+ if ( colConfig[iSub].massExcess > mStringMin ) {
+ if (!stringFrag.fragment( iSub, colConfig, event)) return false;
+
+ // Low-mass string treated separately. Tell if diffractive system.
+ } else {
+ bool isDiff = infoPtr->isDiffractiveA()
+ || infoPtr->isDiffractiveB();
+ if (!ministringFrag.fragment( iSub, colConfig, event, isDiff))
+ return false;
+ }
+ }
+ }
+
+ // Second part: sequential decays of short-lived particles (incl. K0).
+ if (doDecay) {
+
+ // Loop through all entries to find those that should decay.
+ int iDec = 0;
+ do {
+ if ( event[iDec].isFinal() && event[iDec].canDecay()
+ && event[iDec].mayDecay() && (event[iDec].idAbs() == 311
+ || event[iDec].mWidth() > widthSepBE) ) {
+ decays.decay( iDec, event);
+ if (decays.moreToDo()) moreToDo = true;
+ }
+ } while (++iDec < event.size());
+ }
+
+ // Third part: include Bose-Einstein effects among current particles.
+ if (doBoseEinsteinNow) {
+ if (!boseEinstein.shiftEvent(event)) return false;
+ doBoseEinsteinNow = false;
+ }
+
+ // Fourth part: sequential decays also of long-lived particles.
+ if (doDecay) {
+
+ // Loop through all entries to find those that should decay.
+ int iDec = 0;
+ do {
+ if ( event[iDec].isFinal() && event[iDec].canDecay()
+ && event[iDec].mayDecay() ) {
+ decays.decay( iDec, event);
+ if (decays.moreToDo()) moreToDo = true;
+ }
+ } while (++iDec < event.size());
+ }
+
+
+ // Normally done first time around, but sometimes not (e.g. Upsilon).
+ } while (moreToDo);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Allow more decays if on/off switches changed.
+// Note: does not do sequential hadronization, e.g. for Upsilon.
+
+bool HadronLevel::moreDecays( Event& event) {
+
+ // Colour-octet onia states must be decayed to singlet + gluon.
+ if (!decayOctetOnia(event)) return false;
+
+ // Loop through all entries to find those that should decay.
+ int iDec = 0;
+ do {
+ if ( event[iDec].isFinal() && event[iDec].canDecay()
+ && event[iDec].mayDecay() ) decays.decay( iDec, event);
+ } while (++iDec < event.size());
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Decay colour-octet onium states.
+
+bool HadronLevel::decayOctetOnia(Event& event) {
+
+ // Onium states to be decayed.
+ int idOnium[6] = { 9900443, 9900441, 9910441,
+ 9900553, 9900551, 9910551 };
+
+ // Loop over particles and identify onia.
+ for (int iDec = 0; iDec < event.size(); ++iDec)
+ if (event[iDec].isFinal()) {
+ int id = event[iDec].id();
+ bool isOnium = false;
+ for (int j = 0; j < 6; ++j) if (id == idOnium[j]) isOnium = true;
+
+ // Decay any onia encountered.
+ if (isOnium) {
+ if (!decays.decay( iDec, event)) return false;
+
+ // Set colour flow by hand: gluon inherits octet-onium state.
+ int iGlu = event.size() - 1;
+ event[iGlu].cols( event[iDec].col(), event[iDec].acol() );
+ }
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Trace colour flow in the event to form colour singlet subsystems.
+
+bool HadronLevel::findSinglets(Event& event) {
+
+ // Find a list of final partons and of all colour ends and gluons.
+ iColEnd.resize(0);
+ iAcolEnd.resize(0);
+ iColAndAcol.resize(0);
+ for (int i = 0; i < event.size(); ++ i) if (event[i].isFinal()) {
+ if (event[i].col() > 0 && event[i].acol() > 0) iColAndAcol.push_back(i);
+ else if (event[i].col() > 0) iColEnd.push_back(i);
+ else if (event[i].acol() > 0) iAcolEnd.push_back(i);
+ }
+
+ // Begin arrange the partons into separate colour singlets.
+ colConfig.clear();
+ iPartonJun.resize(0);
+ iPartonAntiJun.resize(0);
+
+ // Junctions: loop over them, and identify kind.
+ for (int iJun = 0; iJun < event.sizeJunction(); ++iJun)
+ if (event.remainsJunction(iJun)) {
+ event.remainsJunction(iJun, false);
+ int kindJun = event.kindJunction(iJun);
+ iParton.resize(0);
+
+ // First kind: three (anti)colours out from junction.
+ if (kindJun == 1 || kindJun == 2) {
+ for (int iCol = 0; iCol < 3; ++iCol) {
+ int indxCol = event.colJunction(iJun, iCol);
+ iParton.push_back( -(10 + 10 * iJun + iCol) );
+ if (kindJun == 1 && !traceFromAcol(indxCol, event, iJun, iCol))
+ return false;
+ if (kindJun == 2 && !traceFromCol(indxCol, event, iJun, iCol))
+ return false;
+ }
+ }
+
+ // Keep in memory a junction hooked up with an antijunction,
+ // else store found single-junction system.
+ int nNeg = 0;
+ for (int i = 0; i < int(iParton.size()); ++i) if (iParton[i] < 0)
+ ++nNeg;
+ if (nNeg > 3 && kindJun == 1) {
+ for (int i = 0; i < int(iParton.size()); ++i)
+ iPartonJun.push_back(iParton[i]);
+ } else if (nNeg > 3 && kindJun == 2) {
+ for (int i = 0; i < int(iParton.size()); ++i)
+ iPartonAntiJun.push_back(iParton[i]);
+ } else {
+ // A junction may be eliminated by insert if two quarks are nearby.
+ int nJunOld = event.sizeJunction();
+ colConfig.insert(iParton, event);
+ if (event.sizeJunction() < nJunOld) --iJun;
+ }
+ }
+
+ // Split junction-antijunction system into two, and store those.
+ // (Only one system in extreme cases, and then second empty.)
+ if (iPartonJun.size() > 0 && iPartonAntiJun.size() > 0) {
+ if (!splitJunctionPair(event)) return false;
+ colConfig.insert(iPartonJun, event);
+ if (iPartonAntiJun.size() > 0)
+ colConfig.insert(iPartonAntiJun, event);
+ // Error if only one of junction and antijuction left here.
+ } else if (iPartonJun.size() > 0 || iPartonAntiJun.size() > 0) {
+ infoPtr->errorMsg("Error in HadronLevel::findSinglets: "
+ "unmatched (anti)junction");
+ return false;
+ }
+
+ // Open strings: pick up each colour end and trace to its anticolor end.
+ for (int iEnd = 0; iEnd < int(iColEnd.size()); ++iEnd) {
+ iParton.resize(0);
+ iParton.push_back( iColEnd[iEnd] );
+ int indxCol = event[ iColEnd[iEnd] ].col();
+ if (!traceFromCol(indxCol, event)) return false;
+
+ // Store found open string system. Analyze its properties.
+ colConfig.insert(iParton, event);
+ }
+
+ // Closed strings : begin at any gluon and trace until back at it.
+ while (iColAndAcol.size() > 0) {
+ iParton.resize(0);
+ iParton.push_back( iColAndAcol[0] );
+ int indxCol = event[ iColAndAcol[0] ].col();
+ int indxAcol = event[ iColAndAcol[0] ].acol();
+ iColAndAcol[0] = iColAndAcol.back();
+ iColAndAcol.pop_back();
+ if (!traceInLoop(indxCol, indxAcol, event)) return false;
+
+ // Store found closed string system. Analyze its properties.
+ colConfig.insert(iParton, event);
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Trace a colour line, from a colour to an anticolour.
+
+bool HadronLevel::traceFromCol(int indxCol, Event& event, int iJun,
+ int iCol) {
+
+ // Junction kind, if any.
+ int kindJun = (iJun >= 0) ? event.kindJunction(iJun) : 0;
+
+ // Begin to look for a matching anticolour.
+ int loop = 0;
+ int loopMax = iColAndAcol.size() + 2;
+ bool hasFound = false;
+ do {
+ ++loop;
+ hasFound= false;
+
+ // First check list of matching anticolour ends.
+ for (int i = 0; i < int(iAcolEnd.size()); ++i)
+ if (event[ iAcolEnd[i] ].acol() == indxCol) {
+ iParton.push_back( iAcolEnd[i] );
+ indxCol = 0;
+ iAcolEnd[i] = iAcolEnd.back();
+ iAcolEnd.pop_back();
+ hasFound = true;
+ break;
+ }
+
+ // Then check list of intermediate gluons.
+ if (!hasFound)
+ for (int i = 0; i < int(iColAndAcol.size()); ++i)
+ if (event[ iColAndAcol[i] ].acol() == indxCol) {
+ iParton.push_back( iColAndAcol[i] );
+
+ // Update to new colour. Remove gluon.
+ indxCol = event[ iColAndAcol[i] ].col();
+ if (kindJun > 0) event.endColJunction(iJun, iCol, indxCol);
+ iColAndAcol[i] = iColAndAcol.back();
+ iColAndAcol.pop_back();
+ hasFound = true;
+ break;
+ }
+
+ // In a pinch, check list of end colours on other (anti)junction.
+ if (!hasFound && kindJun == 2 && event.sizeJunction() > 1)
+ for (int iAntiJun = 0; iAntiJun < event.sizeJunction(); ++iAntiJun)
+ if (iAntiJun != iJun && event.kindJunction(iAntiJun) == 1)
+ for (int iColAnti = 0; iColAnti < 3; ++iColAnti)
+ if (event.endColJunction(iAntiJun, iColAnti) == indxCol) {
+ iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
+ indxCol = 0;
+ hasFound = true;
+ break;
+ }
+
+ // Keep on tracing via gluons until reached end of leg.
+ } while (hasFound && indxCol > 0 && loop < loopMax);
+
+ // Something went wrong in colour tracing.
+ if (!hasFound || loop == loopMax) {
+ infoPtr->errorMsg("Error in HadronLevel::traceFromCol: "
+ "colour tracing failed");
+ return false;
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Trace a colour line, from an anticolour to a colour.
+
+bool HadronLevel::traceFromAcol(int indxCol, Event& event, int iJun,
+ int iCol) {
+
+ // Junction kind, if any.
+ int kindJun = (iJun >= 0) ? event.kindJunction(iJun) : 0;
+
+ // Begin to look for a matching colour.
+ int loop = 0;
+ int loopMax = iColAndAcol.size() + 2;
+ bool hasFound = false;
+ do {
+ ++loop;
+ hasFound= false;
+
+ // First check list of matching colour ends.
+ for (int i = 0; i < int(iColEnd.size()); ++i)
+ if (event[ iColEnd[i] ].col() == indxCol) {
+ iParton.push_back( iColEnd[i] );
+ indxCol = 0;
+ iColEnd[i] = iColEnd.back();
+ iColEnd.pop_back();
+ hasFound = true;
+ break;
+ }
+
+ // Then check list of intermediate gluons.
+ if (!hasFound)
+ for (int i = 0; i < int(iColAndAcol.size()); ++i)
+ if (event[ iColAndAcol[i] ].col() == indxCol) {
+ iParton.push_back( iColAndAcol[i] );
+
+ // Update to new colour. Remove gluon.
+ indxCol = event[ iColAndAcol[i] ].acol();
+ if (kindJun > 0) event.endColJunction(iJun, iCol, indxCol);
+ iColAndAcol[i] = iColAndAcol.back();
+ iColAndAcol.pop_back();
+ hasFound = true;
+ break;
+ }
+
+ // In a pinch, check list of colours on other (anti)junction.
+ if (!hasFound && kindJun == 1 && event.sizeJunction() > 1)
+ for (int iAntiJun = 0; iAntiJun < event.sizeJunction(); ++iAntiJun)
+ if (iAntiJun != iJun && event.kindJunction(iAntiJun) == 2)
+ for (int iColAnti = 0; iColAnti < 3; ++iColAnti)
+ if (event.endColJunction(iAntiJun, iColAnti) == indxCol) {
+ iParton.push_back( -(10 + 10 * iAntiJun + iColAnti) );
+ indxCol = 0;
+ hasFound = true;
+ break;
+ }
+
+ // Keep on tracing via gluons until reached end of leg.
+ } while (hasFound && indxCol > 0 && loop < loopMax);
+
+ // Something went wrong in colour tracing.
+ if (!hasFound || loop == loopMax) {
+ infoPtr->errorMsg("Error in HadronLevel::traceFromAcol: "
+ "colour tracing failed");
+ return false;
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Trace a colour loop, from a colour back to the anticolour of the same.
+
+bool HadronLevel::traceInLoop(int indxCol, int indxAcol, Event& event) {
+
+ // Move around until back where begun.
+ int loop = 0;
+ int loopMax = iColAndAcol.size() + 2;
+ bool hasFound = false;
+ do {
+ ++loop;
+ hasFound= false;
+
+ // Check list of gluons.
+ for (int i = 0; i < int(iColAndAcol.size()); ++i)
+ if (event[ iColAndAcol[i] ].acol() == indxCol) {
+ iParton.push_back( iColAndAcol[i] );
+ indxCol = event[ iColAndAcol[i] ].col();
+ iColAndAcol[i] = iColAndAcol.back();
+ iColAndAcol.pop_back();
+ hasFound = true;
+ break;
+ }
+ } while (hasFound && indxCol != indxAcol && loop < loopMax);
+
+ // Something went wrong in colour tracing.
+ if (!hasFound || loop == loopMax) {
+ infoPtr->errorMsg("Error in HadronLevel::traceInLoop: "
+ "colour tracing failed");
+ return false;
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Split junction-antijunction system into two, or simplify other way.
+
+bool HadronLevel::splitJunctionPair(Event& event) {
+
+ // Construct separate index arrays for the three junction legs.
+ int identJun = (-iPartonJun[0])/10;
+ iJunLegA.resize(0);
+ iJunLegB.resize(0);
+ iJunLegC.resize(0);
+ int leg = -1;
+ for (int i = 0; i < int(iPartonJun.size()); ++ i) {
+ if ( (-iPartonJun[i])/10 == identJun) ++leg;
+ if (leg == 0) iJunLegA.push_back( iPartonJun[i] );
+ else if (leg == 1) iJunLegB.push_back( iPartonJun[i] );
+ else iJunLegC.push_back( iPartonJun[i] );
+ }
+
+ // Construct separate index arrays for the three antijunction legs.
+ int identAnti = (-iPartonAntiJun[0])/10;
+ iAntiLegA.resize(0);
+ iAntiLegB.resize(0);
+ iAntiLegC.resize(0);
+ leg = -1;
+ for (int i = 0; i < int(iPartonAntiJun.size()); ++ i) {
+ if ( (-iPartonAntiJun[i])/10 == identAnti) ++leg;
+ if (leg == 0) iAntiLegA.push_back( iPartonAntiJun[i] );
+ else if (leg == 1) iAntiLegB.push_back( iPartonAntiJun[i] );
+ else iAntiLegC.push_back( iPartonAntiJun[i] );
+ }
+
+ // Find interjunction legs, i.e. between junction and antijunction.
+ int nMatch = 0;
+ int legJun[3], legAnti[3], nGluLeg[3];
+ if (iJunLegA.back() < 0) { legJun[nMatch] = 0;
+ legAnti[nMatch] = (-iJunLegA.back())%10; ++nMatch;}
+ if (iJunLegB.back() < 0) { legJun[nMatch] = 1;
+ legAnti[nMatch] = (-iJunLegB.back())%10; ++nMatch;}
+ if (iJunLegC.back() < 0) { legJun[nMatch] = 2;
+ legAnti[nMatch] = (-iJunLegC.back())%10; ++nMatch;}
+
+ // Loop over interjunction legs.
+ for (int iMatch = 0; iMatch < nMatch; ++iMatch) {
+ vector<int>& iJunLeg = (legJun[iMatch] == 0) ? iJunLegA
+ : ( (legJun[iMatch] == 1) ? iJunLegB : iJunLegC );
+ vector<int>& iAntiLeg = (legAnti[iMatch] == 0) ? iAntiLegA
+ : ( (legAnti[iMatch] == 1) ? iAntiLegB : iAntiLegC );
+
+ // Find number of gluons on each. Do nothing for now if none.
+ nGluLeg[iMatch] = iJunLeg.size() + iAntiLeg.size() - 4;
+ if (nGluLeg[iMatch] == 0) continue;
+
+ // Else pick up the gluons on the interjunction leg in order.
+ iGluLeg.resize(0);
+ for (int i = 1; i < int(iJunLeg.size()) - 1; ++i)
+ iGluLeg.push_back( iJunLeg[i] );
+ for (int i = int(iAntiLeg.size()) - 2; i > 0; --i)
+ iGluLeg.push_back( iAntiLeg[i] );
+
+ // Remove those gluons from the junction/antijunction leg lists.
+ iJunLeg.resize(1);
+ iAntiLeg.resize(1);
+
+ // Pick a new quark at random; for simplicity no diquarks.
+ int idQ = flavSel.pickLightQ();
+ int colQ, acolQ;
+
+ // If one gluon on leg, split it into a collinear q-qbar pair.
+ if (iGluLeg.size() == 1) {
+
+ // Store the new q qbar pair, sharing gluon colour and momentum.
+ colQ = event[ iGluLeg[0] ].col();
+ acolQ = event[ iGluLeg[0] ].acol();
+ Vec4 pQ = 0.5 * event[ iGluLeg[0] ].p();
+ double mQ = 0.5 * event[ iGluLeg[0] ].m();
+ int iQ = event.append( idQ, 75, iGluLeg[0], 0, 0, 0, colQ, 0, pQ, mQ );
+ int iQbar = event.append( -idQ, 75, iGluLeg[0], 0, 0, 0, 0, acolQ,
+ pQ, mQ );
+
+ // Mark split gluon and update junction and antijunction legs.
+ event[ iGluLeg[0] ].statusNeg();
+ event[ iGluLeg[0] ].daughters( iQ, iQbar);
+ iJunLeg.push_back(iQ);
+ iAntiLeg.push_back(iQbar);
+
+ // If several gluons on the string, decide which g-g region to split up.
+ } else {
+
+ // Evaluate mass-squared for all adjacent gluon pairs.
+ m2Pair.resize(0);
+ double m2Sum = 0.;
+ for (int i = 0; i < int(iGluLeg.size()) - 1; ++i) {
+ double m2Now = 0.5 * event[ iGluLeg[i] ].p()
+ * event[ iGluLeg[i + 1] ].p();
+ m2Pair.push_back(m2Now);
+ m2Sum += m2Now;
+ }
+
+ // Pick breakup region with probability proportional to mass-squared.
+ double m2Reg = m2Sum * Rndm::flat();
+ int iReg = -1;
+ do m2Reg -= m2Pair[++iReg];
+ while (m2Reg > 0. && iReg < int(iGluLeg.size()) - 1);
+ m2Reg = m2Pair[iReg];
+
+ // Pick breaking point of string in chosen region (symmetrically).
+ double m2Temp = min( JJSTRINGM2MAX, JJSTRINGM2FRAC * m2Reg);
+ double xPos = 0.5;
+ double xNeg = 0.5;
+ do {
+ double zTemp = zSel.zFrag( idQ, 0, m2Temp);
+ xPos = 1. - zTemp;
+ xNeg = m2Temp / (zTemp * m2Reg);
+ } while (xNeg > 1.);
+ if (Rndm::flat() > 0.5) swap(xPos, xNeg);
+
+ // Pick up two "mother" gluons of breakup. Mark them decayed.
+ Particle& gJun = event[ iGluLeg[iReg] ];
+ Particle& gAnti = event[ iGluLeg[iReg + 1] ];
+ gJun.statusNeg();
+ gAnti.statusNeg();
+ int dau1 = event.size();
+ gJun.daughters(dau1, dau1 + 3);
+ gAnti.daughters(dau1, dau1 + 3);
+ int mother1 = min( iGluLeg[iReg], iGluLeg[iReg + 1]);
+ int mother2 = max( iGluLeg[iReg], iGluLeg[iReg + 1]);
+
+ // Can keep one of old colours but need one new so unambiguous.
+ colQ = gJun.acol();
+ acolQ = event.nextColTag();
+
+ // Store copied gluons with reduced momenta.
+ int iGjun = event.append( 21, 75, mother1, mother2, 0, 0,
+ gJun.col(), gJun.acol(), (1. - 0.5 * xPos) * gJun.p(),
+ (1. - 0.5 * xPos) * gJun.m());
+ int iGanti = event.append( 21, 75, mother1, mother2, 0, 0,
+ acolQ, gAnti.acol(), (1. - 0.5 * xNeg) * gAnti.p(),
+ (1. - 0.5 * xNeg) * gAnti.m());
+
+ // Store the new q qbar pair with remaining momenta.
+ int iQ = event.append( idQ, 75, mother1, mother2, 0, 0,
+ colQ, 0, 0.5 * xNeg * gAnti.p(), 0.5 * xNeg * gAnti.m() );
+ int iQbar = event.append( -idQ, 75, mother1, mother2, 0, 0,
+ 0, acolQ, 0.5 * xPos * gJun.p(), 0.5 * xPos * gJun.m() );
+
+ // Update junction and antijunction legs with gluons and quarks.
+ for (int i = 0; i < iReg; ++i)
+ iJunLeg.push_back( iGluLeg[i] );
+ iJunLeg.push_back(iGjun);
+ iJunLeg.push_back(iQ);
+ for (int i = int(iGluLeg.size()) - 1; i > iReg + 1; --i)
+ iAntiLeg.push_back( iGluLeg[i] );
+ iAntiLeg.push_back(iGanti);
+ iAntiLeg.push_back(iQbar);
+ }
+
+ // Update end colours for both g -> q qbar and g g -> g g q qbar.
+ event.endColJunction(identJun - 1, legJun[iMatch], colQ);
+ event.endColJunction(identAnti - 1, legAnti[iMatch], acolQ);
+ }
+
+ // Update list of interjunction legs after splittings above.
+ int iMatchUp = 0;
+ while (iMatchUp < nMatch) {
+ if (nGluLeg[iMatchUp] > 0) {
+ for (int i = iMatchUp; i < nMatch - 1; ++i) {
+ legJun[i] = legJun[i + 1];
+ legAnti[i] = legAnti[i + 1];
+ nGluLeg[i] = nGluLeg[i + 1];
+ } --nMatch;
+ } else ++iMatchUp;
+ }
+
+ // Should not ever have three empty interjunction legs.
+ if (nMatch == 3) {
+ infoPtr->errorMsg("Error in HadronLevel::splitJunctionPair: "
+ "three empty junction-junction legs");
+ return false;
+ }
+
+ // If two legs are empty, then collapse system to a single string.
+ if (nMatch == 2) {
+ int legJunLeft = 3 - legJun[0] - legJun[1];
+ int legAntiLeft = 3 - legAnti[0] - legAnti[1];
+ vector<int>& iJunLeg = (legJunLeft == 0) ? iJunLegA
+ : ( (legJunLeft == 1) ? iJunLegB : iJunLegC );
+ vector<int>& iAntiLeg = (legAntiLeft == 0) ? iAntiLegA
+ : ( (legAntiLeft == 1) ? iAntiLegB : iAntiLegC );
+ iPartonJun.resize(0);
+ for (int i = int(iJunLeg.size()) - 1; i > 0; --i)
+ iPartonJun.push_back( iJunLeg[i] );
+ for (int i = 1; i < int(iAntiLeg.size()); ++i)
+ iPartonJun.push_back( iAntiLeg[i] );
+
+ // Other string system empty. Remove junctions from their list. Done.
+ iPartonAntiJun.resize(0);
+ event.eraseJunction( max(identJun, identAnti) - 1);
+ event.eraseJunction( min(identJun, identAnti) - 1);
+ return true;
+ }
+
+ // If one leg is empty then, depending on string length, either
+ // (a) annihilate junction and antijunction into two simple strings, or
+ // (b) split the empty leg by borrowing energy from nearby legs.
+ if (nMatch == 1) {
+
+ // Identify the two external legs of either junction.
+ vector<int>& iJunLeg0 = (legJun[0] == 0) ? iJunLegB : iJunLegA;
+ vector<int>& iJunLeg1 = (legJun[0] == 2) ? iJunLegB : iJunLegC;
+ vector<int>& iAntiLeg0 = (legAnti[0] == 0) ? iAntiLegB : iAntiLegA;
+ vector<int>& iAntiLeg1 = (legAnti[0] == 2) ? iAntiLegB : iAntiLegC;
+
+ // Simplified procedure: mainly study first parton on each leg.
+ Vec4 pJunLeg0 = event[ iJunLeg0[1] ].p();
+ Vec4 pJunLeg1 = event[ iJunLeg1[1] ].p();
+ Vec4 pAntiLeg0 = event[ iAntiLeg0[1] ].p();
+ Vec4 pAntiLeg1 = event[ iAntiLeg1[1] ].p();
+
+ // Starting frame hopefully intermediate to two junction directions.
+ Vec4 pStart = pJunLeg0 / pJunLeg0.e() + pJunLeg1 / pJunLeg1.e()
+ + pAntiLeg0 / pAntiLeg0.e() + pAntiLeg1 / pAntiLeg1.e();
+
+ // Loop over iteration to junction/antijunction rest frames (JRF/ARF).
+ RotBstMatrix MtoJRF, MtoARF;
+ Vec4 pInJRF[3], pInARF[3];
+ for (int iJun = 0; iJun < 2; ++iJun) {
+ int offset = (iJun == 0) ? 0 : 2;
+
+ // Iterate from system rest frame towards the junction rest frame.
+ RotBstMatrix MtoRF, Mstep;
+ MtoRF.bstback(pStart);
+ Vec4 pInRF[4];
+ int iter = 0;
+ do {
+ ++iter;
+
+ // Find rest-frame momenta on the three sides of the junction.
+ // Only consider first parton on each leg, for simplicity.
+ pInRF[0 + offset] = pJunLeg0;
+ pInRF[1 + offset] = pJunLeg1;
+ pInRF[2 - offset] = pAntiLeg0;
+ pInRF[3 - offset] = pAntiLeg1;
+ for (int i = 0; i < 4; ++i) pInRF[i].rotbst(MtoRF);
+
+ // For third side add both legs beyond other junction, weighted.
+ double wt2 = 1. - exp( -pInRF[2].e() / eNormJunction);
+ double wt3 = 1. - exp( -pInRF[3].e() / eNormJunction);
+ pInRF[2] = wt2 * pInRF[2] + wt3 * pInRF[3];
+
+ // Find new junction rest frame from the set of momenta.
+ Mstep = stringFrag.junctionRestFrame( pInRF[0], pInRF[1], pInRF[2]);
+ MtoRF.rotbst( Mstep );
+ } while (iter < 3 || (Mstep.deviation() > CONVJNREST
+ && iter < NTRYJNREST) );
+
+ // Store final boost and rest-frame (weighted) momenta.
+ if (iJun == 0) {
+ MtoJRF = MtoRF;
+ for (int i = 0; i < 3; ++i) pInJRF[i] = pInRF[i];
+ } else {
+ MtoARF = MtoRF;
+ for (int i = 0; i < 3; ++i) pInARF[i] = pInRF[i];
+ }
+ }
+
+ // Opposite operations: boost from JRF/ARF to original system.
+ RotBstMatrix MfromJRF = MtoJRF;
+ MfromJRF.invert();
+ RotBstMatrix MfromARF = MtoARF;
+ MfromARF.invert();
+
+ // Velocity vectors of junctions and momentum of legs in lab frame.
+ Vec4 vJun(0., 0., 0., 1.);
+ vJun.rotbst(MfromJRF);
+ Vec4 vAnti(0., 0., 0., 1.);
+ vAnti.rotbst(MfromARF);
+ Vec4 pLabJ[3], pLabA[3];
+ for (int i = 0; i < 3; ++i) {
+ pLabJ[i] = pInJRF[i];
+ pLabJ[i].rotbst(MfromJRF);
+ pLabA[i] = pInARF[i];
+ pLabA[i].rotbst(MfromARF);
+ }
+
+ // Calculate Lambda-measure length of three possible topologies.
+ double vJvA = vJun * vAnti;
+ double vJvAe2y = vJvA + sqrt(vJvA*vJvA - 1.);
+ double LambdaJA = (2. * pInJRF[0].e()) * (2. * pInJRF[1].e())
+ * (2. * pInARF[0].e()) * (2. * pInARF[1].e()) * vJvAe2y;
+ double Lambda00 = (2. * pLabJ[0] * pLabA[0])
+ * (2. * pLabJ[1] * pLabA[1]);
+ double Lambda01 = (2. * pLabJ[0] * pLabA[1])
+ * (2. * pLabJ[1] * pLabA[0]);
+
+ // Case when either topology without junctions is the shorter one.
+ if (LambdaJA > min( Lambda00, Lambda01)) {
+ vector<int>& iAntiMatch0 = (Lambda00 < Lambda01)
+ ? iAntiLeg0 : iAntiLeg1;
+ vector<int>& iAntiMatch1 = (Lambda00 < Lambda01)
+ ? iAntiLeg1 : iAntiLeg0;
+
+ // Define two quark-antiquark strings.
+ iPartonJun.resize(0);
+ for (int i = int(iJunLeg0.size()) - 1; i > 0; --i)
+ iPartonJun.push_back( iJunLeg0[i] );
+ for (int i = 1; i < int(iAntiMatch0.size()); ++i)
+ iPartonJun.push_back( iAntiMatch0[i] );
+ iPartonAntiJun.resize(0);
+ for (int i = int(iJunLeg1.size()) - 1; i > 0; --i)
+ iPartonAntiJun.push_back( iJunLeg1[i] );
+ for (int i = 1; i < int(iAntiMatch1.size()); ++i)
+ iPartonAntiJun.push_back( iAntiMatch1[i] );
+
+ // Remove junctions from their list. Done.
+ event.eraseJunction( max(identJun, identAnti) - 1);
+ event.eraseJunction( min(identJun, identAnti) - 1);
+ return true;
+ }
+
+ // Case where junction and antijunction to be separated.
+ // Shuffle (p+/p-) momentum of order <mThad> between systems,
+ // times 2/3 for 120 degree in JRF, times 1/2 for two legs,
+ // but not more than half of what nearest parton carries.
+ double eShift = MTHAD / (3. * sqrt(vJvAe2y));
+ double fracJ0 = min(0.5, eShift / pInJRF[0].e());
+ double fracJ1 = min(0.5, eShift / pInJRF[0].e());
+ Vec4 pFromJun = fracJ0 * pJunLeg0 + fracJ1 * pJunLeg1;
+ double fracA0 = min(0.5, eShift / pInARF[0].e());
+ double fracA1 = min(0.5, eShift / pInARF[0].e());
+ Vec4 pFromAnti = fracA0 * pAntiLeg0 + fracA1 * pAntiLeg1;
+
+ // Copy partons with scaled-down momenta and update legs.
+ int iNew = event.copy(iJunLeg0[1], 76);
+ event[iNew].rescale5(1. - fracJ0);
+ iJunLeg0[1] = iNew;
+ iNew = event.copy(iJunLeg1[1], 76);
+ event[iNew].rescale5(1. - fracJ1);
+ iJunLeg1[1] = iNew;
+ iNew = event.copy(iAntiLeg0[1], 76);
+ event[iNew].rescale5(1. - fracA0);
+ iAntiLeg0[1] = iNew;
+ iNew = event.copy(iAntiLeg1[1], 76);
+ event[iNew].rescale5(1. - fracA1);
+ iAntiLeg1[1] = iNew;
+
+ // Pick a new quark at random; for simplicity no diquarks.
+ int idQ = flavSel.pickLightQ();
+
+ // Update junction colours for new quark and antiquark.
+ int colQ = event.nextColTag();
+ int acolQ = event.nextColTag();
+ event.endColJunction(identJun - 1, legJun[0], colQ);
+ event.endColJunction(identAnti - 1, legAnti[0], acolQ);
+
+ // Store new quark and antiquark with momentum from other junction.
+ int mother1 = min(iJunLeg0[1], iJunLeg1[1]);
+ int mother2 = max(iJunLeg0[1], iJunLeg1[1]);
+ int iNewJ = event.append( idQ, 76, mother1, mother2, 0, 0,
+ colQ, 0, pFromAnti, pFromAnti.mCalc() );
+ mother1 = min(iAntiLeg0[1], iAntiLeg1[1]);
+ mother2 = max(iAntiLeg0[1], iAntiLeg1[1]);
+ int iNewA = event.append( -idQ, 76, mother1, mother2, 0, 0,
+ 0, acolQ, pFromJun, pFromJun.mCalc() );
+
+ // Bookkeep new quark and antiquark on third legs.
+ if (legJun[0] == 0) iJunLegA[1] = iNewJ;
+ else if (legJun[0] == 1) iJunLegB[1] = iNewJ;
+ else iJunLegC[1] = iNewJ;
+ if (legAnti[0] == 0) iAntiLegA[1] = iNewA;
+ else if (legAnti[0] == 1) iAntiLegB[1] = iNewA;
+ else iAntiLegC[1] = iNewA;
+
+ // Done with splitting junction from antijunction.
+ }
+
+ // Put together new junction parton list.
+ iPartonJun.resize(0);
+ for (int i = 0; i < int(iJunLegA.size()); ++i)
+ iPartonJun.push_back( iJunLegA[i] );
+ for (int i = 0; i < int(iJunLegB.size()); ++i)
+ iPartonJun.push_back( iJunLegB[i] );
+ for (int i = 0; i < int(iJunLegC.size()); ++i)
+ iPartonJun.push_back( iJunLegC[i] );
+
+ // Put together new antijunction parton list.
+ iPartonAntiJun.resize(0);
+ for (int i = 0; i < int(iAntiLegA.size()); ++i)
+ iPartonAntiJun.push_back( iAntiLegA[i] );
+ for (int i = 0; i < int(iAntiLegB.size()); ++i)
+ iPartonAntiJun.push_back( iAntiLegB[i] );
+ for (int i = 0; i < int(iAntiLegC.size()); ++i)
+ iPartonAntiJun.push_back( iAntiLegC[i] );
+
+ // Now the two junction systems are separated and can be stored.
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
--- /dev/null
+// Info.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the Info class.
+
+#include "Info.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Info class.
+// This class contains a mixed bag of information on the event generation
+// activity, especially on the current subprocess properties.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of times the same error message will be repeated at most.
+const int Info::TIMESTOPRINT = 1;
+
+//*********
+
+// List (almost) all information currently set.
+
+void Info::list(ostream& os) {
+
+ // Header and beam info.
+ os << "\n -------- PYTHIA Info Listing ------------------------"
+ << "---------------- \n \n"
+ << scientific << setprecision(3)
+ << " Beam A: id = " << setw(6) << idASave << ", pz = " << setw(10)
+ << pzASave << ", e = " << setw(10) << eASave << ", m = " << setw(10)
+ << mASave << ".\n"
+ << " Beam B: id = " << setw(6) << idBSave << ", pz = " << setw(10)
+ << pzBSave << ", e = " << setw(10) << eBSave << ", m = " << setw(10)
+ << mBSave << ".\n\n";
+
+ // Done if no subprocess has been defined.
+ if (codeSave == 0 && nFinalSave == 0) {
+ os << " No process has been set; something must have gone wrong! \n"
+ << "\n -------- End PYTHIA Info Listing --------------------"
+ << "----------------" << endl;
+ return;
+ }
+
+ // Colliding parton info.
+ if (isRes)
+ os << " In 1: id = " << setw(4) << id1Save << ", x = " << setw(10)
+ << x1Save << ", pdf = " << setw(10) << pdf1Save << " at Q2 = "
+ << setw(10) << Q2FacSave << ".\n"
+ << " In 2: id = " << setw(4) << id2Save << ", x = " << setw(10)
+ << x2Save << ", pdf = " << setw(10) << pdf2Save << " at same Q2.\n\n";
+
+ // Process name and code.
+ os << ((isRes && !hasSubSave) ? " Subprocess " : " Process ") << nameSave
+ << " with code " << codeSave << " is 2 -> " << nFinalSave << ".\n";
+
+ // Subprocess name and code for minimum bias processes.
+ if (hasSubSave)
+ os << " Subprocess " << nameSubSave << " with code " << codeSubSave
+ << " is 2 -> " << nFinalSubSave << ".\n";
+
+ // Process-type-specific kinematics information.
+ if (isRes && nFinalSave == 1)
+ os << " It has sHat = " << setw(10) << sH << ".\n";
+ else if ( isRes && nFinalSave == 2)
+ os << " It has sHat = " << setw(10) << sH << ", tHat = "
+ << setw(10) << tH << ", uHat = " << setw(10) << uH << ",\n"
+ << " pTHat = " << setw(10) << pTH << ", m3Hat = "
+ << setw(10) << m3H << ", m4Hat = " << setw(10) << m4H << ",\n"
+ << " thetaHat = " << setw(10) << thetaH << ", phiHat = "
+ << setw(10) << phiH << ".\n";
+ else if ( nFinalSave == 2)
+ os << " It has s = " << setw(10) << sH << ", t = " << setw(10)
+ << tH << ", u = " << setw(10) << uH << ",\n"
+ << " pT = " << setw(10) << pTH << ", m3 = " << setw(10)
+ << m3H << ", m4 = " << setw(10) << m4H << ",\n"
+ << " theta = " << setw(10) << thetaH << ", phi = " << setw(10)
+ << phiH << ".\n";
+ else if ( isRes && nFinalSave == 3)
+ os << " It has sHat = " << setw(10) << sH << ", <pTHat> = "
+ << setw(10) << pTH << ".\n";
+
+ // Couplings.
+ if (isRes) os << " alphaEM = " << setw(10) << alphaEMSave
+ << ", alphaS = " << setw(10) << alphaSSave << " at Q2 = "
+ << setw(10) << Q2RenSave << ".\n";
+
+ // Impact parameter.
+ if (bIsSet) os << "\n Impact parameter b =" << setw(10) << bMISave
+ << " gives enhancement factor = " << setw(10) << enhanceMISave
+ << ".\n";
+
+ // Multiple interactions and shower evolution.
+ if (evolIsSet) os << " Max pT scale for MI = " << setw(10) << pTmaxMISave
+ << ", ISR = " << setw(10) << pTmaxISRSave << ", FSR = " << setw(10)
+ << pTmaxISRSave << ".\n Number of MI = " << setw(5) << nMISave
+ << ", ISR = " << setw(5) << nISRSave << ", FSRproc = " << setw(5)
+ << nFSRinProcSave << ", FSRreson = " << setw(5) << nFSRinResSave
+ << ".\n";
+
+ // Listing finished.
+ os << "\n -------- End PYTHIA Info Listing --------------------"
+ << "----------------" << endl;
+
+}
+
+//*********
+
+// Print a message the first few times. Insert in database.
+
+void Info::errorMsg(string messageIn, string extraIn, ostream& os) {
+
+ // Recover number of times message occured. Also inserts new string.
+ int times = messages[messageIn];
+ ++messages[messageIn];
+
+ // Print message the first few times.
+ if (times < TIMESTOPRINT) os << " PYTHIA " << messageIn << " "
+ << extraIn << endl;
+
+}
+
+//*********
+
+// Provide total number of errors/aborts/warnings experienced to date.
+
+int Info::errorTotalNumber() {
+
+ int nTot = 0;
+ for ( map<string, int>::iterator messageEntry = messages.begin();
+ messageEntry != messages.end(); ++messageEntry)
+ nTot += messageEntry->second;
+ return nTot;
+
+}
+
+//*********
+
+// Print statistics on errors/aborts/warnings.
+
+void Info::errorStatistics(ostream& os) {
+
+ // Header.
+ os << "\n *------- PYTHIA Error and Warning Messages Statistics "
+ << "----------------------------------------------------------* \n"
+ << " | "
+ << " | \n"
+ << " | times message "
+ << " | \n"
+ << " | "
+ << " | \n";
+
+ // Loop over all messages
+ map<string, int>::iterator messageEntry = messages.begin();
+ if (messageEntry == messages.end())
+ os << " | 0 no errors or warnings to report "
+ << " | \n";
+ while (messageEntry != messages.end()) {
+ // Debug printout.
+ string temp = messageEntry->first;
+ int len = temp.length();
+ temp.insert( len, max(0, 102 - len), ' ');
+ os << " | " << setw(6) << messageEntry->second << " "
+ << temp << " | \n";
+ ++messageEntry;
+ }
+
+ // Done.
+ os << " | "
+ << " | \n"
+ << " *------- End PYTHIA Error and Warning Messages Statistics"
+ << " ------------------------------------------------------* "
+ << endl;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
--- /dev/null
+// LesHouches.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the LHAup and
+// LHAupLHEF classes.
+
+#include "LesHouches.h"
+
+// Access time information.
+#include <ctime>
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// LHAup class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// LHA convention with cross section in pb may require conversion from mb.
+const double LHAup::CONVERTMB2PB = 1e9;
+
+//*********
+
+// Print the initialization info; to check it worked.
+
+void LHAup::listInit(ostream& os) {
+
+ // Header.
+ os << "\n -------- LHA initialization information ------------ \n";
+
+ // Beam info.
+ os << fixed << setprecision(3)
+ << "\n beam kind energy pdfgrp pdfset \n"
+ << " A " << setw(6) << idBeamASave
+ << setw(12) << eBeamASave
+ << setw(8) << pdfGroupBeamASave
+ << setw(8) << pdfSetBeamASave << "\n"
+ << " B " << setw(6) << idBeamBSave
+ << setw(12) << eBeamBSave
+ << setw(8) << pdfGroupBeamBSave
+ << setw(8) << pdfSetBeamBSave << "\n";
+
+ // Event weighting strategy.
+ os << "\n Event weighting strategy = " << setw(2)
+ << strategySave << "\n" ;
+
+ // Process list.
+ os << scientific << setprecision(4)
+ << "\n Processes, with strategy-dependent cross section info \n"
+ << " number xsec (pb) xerr (pb) xmax (pb) \n" ;
+ for (int ip = 0; ip < int(processes.size()); ++ip) {
+ os << setw(8) << processes[ip].idProc
+ << setw(15) << processes[ip].xSecProc
+ << setw(15) << processes[ip].xErrProc
+ << setw(15) << processes[ip].xMaxProc << "\n";
+ }
+
+ // Finished.
+ os << "\n -------- End LHA initialization information -------- \n";
+
+}
+
+//*********
+
+// Print the event info; to check it worked.
+
+void LHAup::listEvent(ostream& os) {
+
+ // Header.
+ os << "\n -------- LHA event information and listing -------------"
+ << "--------------------------------------------------------- \n";
+
+ // Basic event info.
+ os << scientific << setprecision(4)
+ << "\n process = " << setw(8) << idProc
+ << " weight = " << setw(12) << weightProc
+ << " scale = " << setw(12) << scaleProc << " (GeV) \n"
+ << " "
+ << " alpha_em = " << setw(12) << alphaQEDProc
+ << " alpha_strong = " << setw(12) << alphaQCDProc << "\n";
+
+ // Particle list
+ os << fixed << setprecision(3)
+ << "\n Participating Particles \n"
+ << " no id stat mothers colours p_x "
+ << "p_y p_z e m tau spin \n" ;
+ for (int ip = 1; ip < int(particles.size()); ++ip) {
+ os << setw(6) << ip
+ << setw(10) << particles[ip].idPart
+ << setw(5) << particles[ip].statusPart
+ << setw(6) << particles[ip].mother1Part
+ << setw(6) << particles[ip].mother2Part
+ << setw(6) << particles[ip].col1Part
+ << setw(6) << particles[ip].col2Part
+ << setw(11) << particles[ip].pxPart
+ << setw(11) << particles[ip].pyPart
+ << setw(11) << particles[ip].pzPart
+ << setw(11) << particles[ip].ePart
+ << setw(11) << particles[ip].mPart
+ << setw(8) << particles[ip].tauPart
+ << setw(8) << particles[ip].spinPart << "\n";
+ }
+
+ // PDF info - optional.
+ if (pdfIsSetSave) os << "\n pdf: id1 =" << setw(5) << id1Save
+ << " id2 =" << setw(5) << id2Save
+ << " x1 =" << scientific << setw(10) << x1Save
+ << " x2 =" << setw(10) << x2Save
+ << " scalePDF =" << setw(10) << scalePDFSave
+ << " xpdf1 =" << setw(10) << xpdf1Save
+ << " xpdf2 =" << setw(10) << xpdf2Save << "\n";
+
+ // Finished.
+ os << "\n -------- End LHA event information and listing ---------"
+ << "--------------------------------------------------------- \n";
+
+}
+
+//*********
+
+// Open and write header to a Les Houches Event File.
+
+bool LHAup::openLHEF(string fileNameIn) {
+
+ // Open file for writing. Reset it to be empty.
+ fileName = fileNameIn;
+ const char* cstring = fileName.c_str();
+ osLHEF.open(cstring, ios::out | ios::trunc);
+ if (!osLHEF) {
+ infoPtr->errorMsg("Error in LHAup::openLHEF:"
+ " could not open file", fileName);
+ return false;
+ }
+
+ // Read out current date and time.
+ time_t t = time(0);
+ strftime(dateNow,12,"%d %b %Y",localtime(&t));
+ strftime(timeNow,9,"%H:%M:%S",localtime(&t));
+
+ // Write header.
+ osLHEF << "<LesHouchesEvents version=\"1.0\">\n"
+ << "<!--\n"
+ << " File written by Pythia8::LHAup on "
+ << dateNow << " at " << timeNow << "\n"
+ << "-->" << endl;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Write initialization information to a Les Houches Event File.
+
+bool LHAup::initLHEF() {
+
+ // Write information on beams.
+ osLHEF << "<init>\n" << scientific << setprecision(6)
+ << " " << idBeamASave << " " << idBeamBSave
+ << " " << eBeamASave << " " << eBeamBSave
+ << " " << pdfGroupBeamASave << " " << pdfGroupBeamBSave
+ << " " << pdfSetBeamASave << " " << pdfSetBeamBSave
+ << " " << strategySave << " " << processes.size() << "\n";
+
+ // Write information on all the subprocesses.
+ for (int ip = 0; ip < int(processes.size()); ++ip)
+ osLHEF << " " << setw(13) << processes[ip].xSecProc
+ << " " << setw(13) << processes[ip].xErrProc
+ << " " << setw(13) << processes[ip].xMaxProc
+ << " " << setw(6) << processes[ip].idProc << "\n";
+
+ // Done.
+ osLHEF << "</init>" << endl;
+ return true;
+
+}
+
+//*********
+
+// Write event information to a Les Houches Event File.
+
+bool LHAup::eventLHEF() {
+
+ // Write information on process as such.
+ osLHEF << "<event>\n" << scientific << setprecision(6)
+ << " " << setw(5) << particles.size() - 1
+ << " " << setw(5) << idProc
+ << " " << setw(13) << weightProc
+ << " " << setw(13) << scaleProc
+ << " " << setw(13) << alphaQEDProc
+ << " " << setw(13) << alphaQCDProc << "\n";
+
+ // Write information on the particles, excluding zeroth.
+ for (int ip = 1; ip < int(particles.size()); ++ip) {
+ osLHEF << " " << setw(8) << particles[ip].idPart
+ << " " << setw(5) << particles[ip].statusPart
+ << " " << setw(5) << particles[ip].mother1Part
+ << " " << setw(5) << particles[ip].mother2Part
+ << " " << setw(5) << particles[ip].col1Part
+ << " " << setw(5) << particles[ip].col2Part << setprecision(10)
+ << " " << setw(17) << particles[ip].pxPart
+ << " " << setw(17) << particles[ip].pyPart
+ << " " << setw(17) << particles[ip].pzPart
+ << " " << setw(17) << particles[ip].ePart
+ << " " << setw(17) << particles[ip].mPart << setprecision(6);
+ if (particles[ip].tauPart == 0.) osLHEF << " 0.";
+ else osLHEF << " " << setw(13) << particles[ip].tauPart;
+ if (particles[ip].spinPart == 9.) osLHEF << " 9.";
+ else osLHEF << " " << setw(13) << particles[ip].spinPart;
+ osLHEF << "\n";
+ }
+
+ // Optionally write information on PDF values at hard interaction.
+ if (pdfIsSetSave) osLHEF << "#pdf"
+ << " " << setw(4) << id1Save
+ << " " << setw(4) << id2Save
+ << " " << setw(13) << x1Save
+ << " " << setw(13) << x2Save
+ << " " << setw(13) << scalePDFSave
+ << " " << setw(13) << xpdf1Save
+ << " " << setw(13) << xpdf2Save << "\n";
+
+ // Done.
+ osLHEF << "</event>" << endl;
+ return true;
+
+}
+
+//*********
+
+// Write end of a Les Houches Event File and close it.
+
+bool LHAup::closeLHEF(bool updateInit) {
+
+ // Write an end to the file.
+ osLHEF << "</LesHouchesEvents>" << endl;
+ osLHEF.close();
+
+ // Optionally update the cross section information.
+ if (updateInit) {
+ const char* cstring = fileName.c_str();
+ osLHEF.open(cstring, ios::in | ios::out);
+
+ // Rewrite header; identically with what openLHEF did.
+ osLHEF << "<LesHouchesEvents version=\"1.0\">\n"
+ << "<!--\n"
+ << " File written by Pythia8::LHAup on "
+ << dateNow << " at " << timeNow << "\n"
+ << "-->" << endl;
+
+ // Redo initialization information.
+ initLHEF();
+ osLHEF.close();
+ }
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+// LHAupLHEF class.
+
+//*********
+
+// Read in initialization information from a Les Houches Event File.
+
+bool LHAupLHEF::setInit() {
+
+ // Check that first line is consistent with proper LHEF file.
+ string line;
+ if (!getline(is, line)) return false;
+ if (line.find("<LesHouchesEvents") == string::npos) return false;
+ if (line.find("version=\"1.0\"" ) == string::npos ) return false;
+
+ // Loop over lines until an <init tag is found first on a line.
+ string tag = " ";
+ do {
+ if (!getline(is, line)) return false;
+ if (line.find_first_not_of(" ") != string::npos) {
+ istringstream getfirst(line);
+ getfirst >> tag;
+ if (!getfirst) return false;
+ }
+ } while (tag != "<init>" && tag != "<init");
+
+ // Read in beam and strategy info, and store it.
+ int idbmupA, idbmupB;
+ double ebmupA, ebmupB;
+ int pdfgupA, pdfgupB, pdfsupA, pdfsupB, idwtup, nprup;
+ if (!getline(is, line)) return false;
+ istringstream getbms(line);
+ getbms >> idbmupA >> idbmupB >> ebmupA >> ebmupB >> pdfgupA
+ >> pdfgupB >> pdfsupA >> pdfsupB >> idwtup >> nprup;
+ if (!getbms) return false;
+ setBeamA(idbmupA, ebmupA, pdfgupA, pdfsupA);
+ setBeamB(idbmupB, ebmupB, pdfgupB, pdfsupB);
+ setStrategy(idwtup);
+
+ // Read in process info, one process at a time, and store it.
+ double xsecup, xerrup, xmaxup;
+ int lprup;
+ for (int ip = 0; ip < nprup; ++ip) {
+ if (!getline(is, line)) return false;
+ istringstream getpro(line);
+ getpro >> xsecup >> xerrup >> xmaxup >> lprup ;
+ if (!getpro) return false;
+ addProcess(lprup, xsecup, xerrup, xmaxup);
+ }
+
+ // Reading worked.
+ return true;
+
+}
+
+//*********
+
+// Read in event information from a Les Houches Event File.
+
+bool LHAupLHEF::setEvent( int ) {
+
+ // Loop over lines until an <event tag is found first on a line.
+ string line, tag;
+ do {
+ if (!getline(is, line)) return false;
+ if (line.find_first_not_of(" ") != string::npos) {
+ istringstream getfirst(line);
+ getfirst >> tag;
+ if (!getfirst) return false;
+ }
+ } while (tag != "<event>" && tag != "<event");
+
+ // Read in process info and store it.
+ int nup, idprup;
+ double xwgtup, scalup, aqedup, aqcdup;
+ if (!getline(is, line)) return false;
+ istringstream getpro(line);
+ getpro >> nup >> idprup >> xwgtup >> scalup >> aqedup >> aqcdup;
+ if (!getpro) return false;
+ setProcess(idprup, xwgtup, scalup, aqedup, aqcdup);
+
+ // Read in particle info one by one, and store it.
+ // Note unusual C++ loop range, to better reflect LHA/Fortran standard.
+ // (Recall that process(...) above added empty particle at index 0.)
+ int idup, istup, mothup1, mothup2, icolup1, icolup2;
+ double pup1, pup2, pup3, pup4, pup5, vtimup, spinup;
+ for (int ip = 1; ip <= nup; ++ip) {
+ if (!getline(is, line)) return false;
+ istringstream getall(line);
+ getall >> idup >> istup >> mothup1 >> mothup2 >> icolup1 >> icolup2
+ >> pup1 >> pup2 >> pup3 >> pup4 >> pup5 >> vtimup >> spinup;
+ if (!getall) return false;
+ addParticle(idup, istup, mothup1, mothup2, icolup1, icolup2,
+ pup1, pup2, pup3, pup4, pup5, vtimup, spinup) ;
+ }
+
+ // Continue parsing till </event>. Extract pdf info if present.
+ do {
+ if (!getline(is, line)) return false;
+ istringstream getpdf(line);
+ getpdf >> tag;
+ if (!getpdf) return false;
+ if (tag == "#pdf") {
+ int id1In, id2In;
+ double x1In, x2In, scalePDFIn, xpdf1In, xpdf2In;
+ getpdf >> id1In >> id2In >> x1In >> x2In >> scalePDFIn
+ >> xpdf1In >> xpdf2In;
+ if (!getpdf) return false;
+ setPdf(id1In, id2In, x1In, x2In, scalePDFIn, xpdf1In, xpdf2In);
+ }
+ } while (tag != "</event>" && tag != "</event");
+
+ // Reading worked.
+ return true;
+
+}
+
+//**************************************************************************
+
+// LHAupFromPYTHIA8 class.
+
+//*********
+
+// Read in initialization information from PYTHIA 8.
+
+bool LHAupFromPYTHIA8::setInit() {
+
+ // Read in beam from Info class. Parton density left empty.
+ int idbmupA = infoPtr->idA();
+ int idbmupB = infoPtr->idB();
+ double ebmupA = infoPtr->eA();
+ double ebmupB = infoPtr->eB();
+ int pdfgupA = 0;
+ int pdfgupB = 0;
+ int pdfsupA = 0;
+ int pdfsupB = 0;
+ setBeamA(idbmupA, ebmupA, pdfgupA, pdfsupA);
+ setBeamB(idbmupB, ebmupB, pdfgupB, pdfsupB);
+
+ // Currently only one allowed strategy.
+ int idwtup = 3;
+ setStrategy(idwtup);
+
+ // Only one process with dummy information. (Can overwrite at the end.)
+ int lprup = 9999;
+ double xsecup = 1.;
+ double xerrup = 0.;
+ double xmaxup = 1.;
+ addProcess(lprup, xsecup, xerrup, xmaxup);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Read in event information from PYTHIA 8.
+
+bool LHAupFromPYTHIA8::setEvent( int ) {
+
+ // Read process information from Info class, and store it.
+ // Note: renormalization scale here, factorization further down.
+ int idprup = infoPtr->code();
+ // For now always convert to process 9999.
+ idprup = 9999;
+ double xwgtup = infoPtr->weight();
+ double scalup = infoPtr->QRen();
+ double aqedup = infoPtr->alphaEM();
+ double aqcdup = infoPtr->alphaS();
+ setProcess(idprup, xwgtup, scalup, aqedup, aqcdup);
+
+ // Read in particle info one by one, excluding zero and beams, and store it.
+ // Note unusual C++ loop range, to better reflect LHA/Fortran standard.
+ int nup = processPtr->size() - 3;
+ int idup, statusup, istup, mothup1, mothup2, icolup1, icolup2;
+ double pup1, pup2, pup3, pup4, pup5, vtimup, spinup;
+ for (int ip = 1; ip <= nup; ++ip) {
+ Particle& particle = (*processPtr)[ip + 2];
+ idup = particle.id();
+ // Convert from PYTHIA8 to LHA status codes.
+ statusup = particle.status();
+ if (ip < 3) istup = -1;
+ else if (statusup < 0) istup = 2;
+ else istup = 1;
+ mothup1 = max(0, particle.mother1() - 2);
+ mothup2 = max(0, particle.mother2() - 2);
+ icolup1 = particle.col();
+ icolup2 = particle.acol();
+ pup1 = particle.px();
+ pup2 = particle.py();
+ pup3 = particle.pz();
+ pup4 = particle.e();
+ pup5 = particle.m();
+ vtimup = particle.tau();
+ spinup = 9.;
+ addParticle(idup, istup, mothup1, mothup2, icolup1, icolup2,
+ pup1, pup2, pup3, pup4, pup5, vtimup, spinup) ;
+ }
+
+ // Also extract pdf information from Info class, and store it.
+ int id1up = infoPtr->id1();
+ int id2up = infoPtr->id2();
+ double x1up = infoPtr->x1();
+ double x2up = infoPtr->x2();
+ double scalePDFup = infoPtr->QFac();
+ double xpdf1up = infoPtr->pdf1();
+ double xpdf2up = infoPtr->pdf2();
+ setPdf(id1up, id2up, x1up, x2up, scalePDFup, xpdf1up, xpdf2up);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Update cross-section information at the end of the run.
+
+bool LHAupFromPYTHIA8::updateSigma() {
+
+ // Read out information from PYTHIA 8 and send it in to LHA.
+ double sigGen = CONVERTMB2PB * infoPtr->sigmaGen();
+ double sigErr = CONVERTMB2PB * infoPtr->sigmaErr();
+ setXSec(0, sigGen);
+ setXErr(0, sigErr);
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// MiniStringFragmentation.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the .
+// MiniStringFragmentation class
+
+#include "MiniStringFragmentation.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The MiniStringFragmentation class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Since diffractive by definition is > 1 particle, try hard.
+const int MiniStringFragmentation::NTRYDIFFRACTIVE = 200;
+
+// After one-body fragmentation failed, try two-body once more.
+const int MiniStringFragmentation::NTRYLASTRESORT = 100;
+
+// To avoid division by zero one must have sigma > 0.
+const double MiniStringFragmentation::SIGMAMIN = 0.01;
+
+// Loop try to combine available endquarks to valid hadron.
+const int MiniStringFragmentation::NTRYFLAV = 10;
+
+//*********
+
+// Initialize and save pointers.
+
+void MiniStringFragmentation::init(Info* infoPtrIn,
+ StringFlav* flavSelPtrIn) {
+
+ // Save pointers.
+ infoPtr = infoPtrIn;
+ flavSelPtr = flavSelPtrIn;
+
+ // Initialize the MiniStringFragmentation class proper.
+ nTryMass = Settings::mode("MiniStringFragmentation:nTry");
+ sigma = Settings::parm("StringPT:sigma");
+ sigma2Had = 2. * pow2( max( SIGMAMIN, sigma) );
+
+ // Initialize the b parameter of the z spectrum, used when joining jets.
+ bLund = Settings::parm("StringZ:bLund");
+
+}
+
+//*********
+
+// Do the fragmentation: driver routine.
+
+bool MiniStringFragmentation::fragment(int iSub, ColConfig& colConfig,
+ Event& event, bool isDiff) {
+
+ // Read in info on system to be treated.
+ iParton = colConfig[iSub].iParton;
+ flav1.id = event[ iParton.front() ].id();
+ flav2.id = event[ iParton.back() ].id();
+ pSum = colConfig[iSub].pSum;
+ mSum = colConfig[iSub].mass;
+ m2Sum = mSum*mSum;
+ isClosed = colConfig[iSub].isClosed;
+
+ // Do not want diffractive systems to easily collapse to one particle.
+ int nTryFirst = (isDiff) ? NTRYDIFFRACTIVE : nTryMass;
+
+ // First try to produce two particles from the system.
+ if (ministring2two( nTryFirst, event)) return true;
+
+ // If this fails, then form one hadron and shuffle momentum.
+ if (ministring2one( iSub, colConfig, event)) return true;
+
+ // If also this fails, then try harder to produce two particles.
+ if (ministring2two( NTRYLASTRESORT, event)) return true;
+
+ // Else complete failure.
+ infoPtr->errorMsg("Error in MiniStringFragmentation::fragment: "
+ "no 1- or 2-body state found above mass threshold");
+ return false;
+
+}
+
+//*********
+
+ // Attempt to produce two particles from the ministring.
+
+bool MiniStringFragmentation::ministring2two( int nTry, Event& event) {
+
+ // Properties of the produced hadrons.
+ int idHad1 = 0;
+ int idHad2 = 0;
+ double mHad1 = 0.;
+ double mHad2 = 0.;
+ double mHadSum = 0.;
+
+ // Allow a few attempts to find a particle pair with low enough masses.
+ for (int iTry = 0; iTry < nTry; ++iTry) {
+
+ // For closed gluon loop need to pick an initial flavour.
+ if (isClosed) do {
+ int idStart = flavSelPtr->pickLightQ();
+ FlavContainer flavStart(idStart, 1);
+ flavStart = flavSelPtr->pick( flavStart);
+ flav1 = flavSelPtr->pick( flavStart);
+ flav2.anti(flav1);
+ } while (flav1.id == 0 || flav1.nPop > 0);
+
+ // Create a new q qbar flavour to form two hadrons.
+ // Start from a diquark, if any.
+ do {
+ FlavContainer flav3 =
+ (abs(flav1.id) > 8 || (abs(flav2.id) < 9 && Rndm::flat() < 0.5) )
+ ? flavSelPtr->pick( flav1) : flavSelPtr->pick( flav2).anti();
+ idHad1 = flavSelPtr->combine( flav1, flav3);
+ idHad2 = flavSelPtr->combine( flav2, flav3.anti());
+ } while (idHad1 == 0 || idHad2 == 0);
+
+ // Check whether the mass sum fits inside the available phase space.
+ mHad1 = ParticleDataTable::mass(idHad1);
+ mHad2 = ParticleDataTable::mass(idHad2);
+ mHadSum = mHad1 + mHad2;
+ if (mHadSum < mSum) break;
+ }
+ if (mHadSum >= mSum) return false;
+
+ // Define an effective two-parton string, by splitting intermediate
+ // gluon momenta in proportion to their closeness to either endpoint.
+ Vec4 pSum1 = event[ iParton.front() ].p();
+ Vec4 pSum2 = event[ iParton.back() ].p();
+ if (iParton.size() > 2) {
+ Vec4 pEnd1 = pSum1;
+ Vec4 pEnd2 = pSum2;
+ Vec4 pEndSum = pEnd1 + pEnd2;
+ for (int i = 1; i < int(iParton.size()) - 1 ; ++i) {
+ Vec4 pNow = event[ iParton[i] ].p();
+ double ratio = (pEnd2 * pNow) / (pEndSum * pNow);
+ pSum1 += ratio * pNow;
+ pSum2 += (1. - ratio) * pNow;
+ }
+ }
+
+ // Set up a string region based on the two effective endpoints.
+ StringRegion region;
+ region.setUp( pSum1, pSum2);
+
+ // Generate an isotropic decay in the ministring rest frame,
+ // suppressed at large pT by a fragmentation pT Gaussian.
+ double pAbs2 = 0.25 * ( pow2(m2Sum - mHad1*mHad1 - mHad2*mHad2)
+ - pow2(2. * mHad1 * mHad2) ) / m2Sum;
+ double pT2 = 0.;
+ do {
+ double cosTheta = Rndm::flat();
+ if (sigma < SIGMAMIN) cosTheta = 1.;
+ pT2 = (1. - pow2(cosTheta)) * pAbs2;
+ } while ( exp( -pT2 / sigma2Had) < Rndm::flat() );
+
+ // Construct the forward-backward asymmetry of the two particles.
+ double mT21 = mHad1*mHad1 + pT2;
+ double mT22 = mHad2*mHad2 + pT2;
+ double lambda = sqrtpos( pow2(m2Sum - mT21 - mT22) - 4. * mT21 * mT22 );
+ double probReverse = 1. / (1. + exp( min( 50., bLund * lambda) ) );
+
+ // Construct kinematics, as viewed in the transverse rest frame.
+ double xpz1 = 0.5 * lambda/ m2Sum;
+ if (probReverse > Rndm::flat()) xpz1 = -xpz1;
+ double xmDiff = (mT21 - mT22) / m2Sum;
+ double xe1 = 0.5 * (1. + xmDiff);
+ double xe2 = 0.5 * (1. - xmDiff );
+
+ // Distribute pT isotropically in angle.
+ double phi = 2. * M_PI * Rndm::flat();
+ double pT = sqrt(pT2);
+ double px = pT * cos(phi);
+ double py = pT * sin(phi);
+
+ // Translate this into kinematics in the string frame.
+ Vec4 pHad1 = region.pHad( xe1 + xpz1, xe1 - xpz1, px, py);
+ Vec4 pHad2 = region.pHad( xe2 - xpz1, xe2 + xpz1, -px, -py);
+
+ // Add produced particles to the event record.
+ int iFirst = event.append( idHad1, 82, iParton.front(), iParton.back(),
+ 0, 0, 0, 0, pHad1, mHad1);
+ int iLast = event.append( idHad2, 82, iParton.front(), iParton.back(),
+ 0, 0, 0, 0, pHad2, mHad2);
+
+ // Set decay vertex when this is displaced.
+ if (event[iParton.front()].hasVertex()) {
+ Vec4 vDec = event[iParton.front()].vDec();
+ event[iFirst].vProd( vDec );
+ event[iLast].vProd( vDec );
+ }
+
+ // Set lifetime of hadrons.
+ event[iFirst].tau( event[iFirst].tau0() * Rndm::exp() );
+ event[iLast].tau( event[iLast].tau0() * Rndm::exp() );
+
+ // Mark original partons as hadronized and set their daughter range.
+ for (int i = 0; i < int(iParton.size()); ++i) {
+ event[ iParton[i] ].statusNeg();
+ event[ iParton[i] ].daughters(iFirst, iLast);
+ }
+
+ // Successfully done.
+ return true;
+
+}
+
+//*********
+
+// Attempt to produce one particle from a ministring.
+// Current algorithm: find the system with largest invariant mass
+// relative to the existing one, and boost that system appropriately.
+// Try more sophisticated alternatives later?? (Z0 mass shifted??)
+// Also, if problems, attempt several times to obtain closer mass match??
+
+bool MiniStringFragmentation::ministring2one( int iSub,
+ ColConfig& colConfig, Event& event) {
+
+ // Cannot handle qq + qbarqbar system.
+ if (abs(flav1.id) > 100 && abs(flav2.id) > 100) return false;
+
+ // For closed gluon loop need to pick an initial flavour.
+ if (isClosed) do {
+ int idStart = flavSelPtr->pickLightQ();
+ FlavContainer flavStart(idStart, 1);
+ flav1 = flavSelPtr->pick( flavStart);
+ flav2 = flav1.anti();
+ } while (abs(flav1.id) > 100);
+
+ // Select hadron flavour from available quark flavours.
+ int idHad = 0;
+ for (int iTryFlav = 0; iTryFlav < NTRYFLAV; ++iTryFlav) {
+ idHad = flavSelPtr->combine( flav1, flav2);
+ if (idHad != 0) break;
+ }
+ if (idHad == 0) return false;
+
+ // Find mass.
+ double mHad = ParticleDataTable::mass(idHad);
+
+ // Find the untreated parton system which combines to the largest
+ // squared mass above mimimum required.
+ int iMax = -1;
+ double deltaM2 = mHad*mHad - mSum*mSum;
+ double delta2Max = 0.;
+ for (int iRec = iSub + 1; iRec < colConfig.size(); ++iRec) {
+ double delta2Rec = 2. * (pSum * colConfig[iRec].pSum) - deltaM2
+ - 2. * mHad * colConfig[iRec].mass;
+ if (delta2Rec > delta2Max) { iMax = iRec; delta2Max = delta2Rec;}
+ }
+ if (iMax == -1) return false;
+
+ // Construct kinematics of the hadron and recoiling system.
+ Vec4& pRec = colConfig[iMax].pSum;
+ double mRec = colConfig[iMax].mass;
+ double vecProd = pSum * pRec;
+ double coefOld = mSum*mSum + vecProd;
+ double coefNew = mHad*mHad + vecProd;
+ double coefRec = mRec*mRec + vecProd;
+ double coefSum = coefOld + coefNew;
+ double sHat = coefOld + coefRec;
+ double root = sqrtpos( (pow2(coefSum) - 4. * sHat * mHad*mHad)
+ / (pow2(vecProd) - pow2(mSum * mRec)) );
+ double k2 = 0.5 * (coefOld * root - coefSum) / sHat;
+ double k1 = (coefRec * k2 + 0.5 * deltaM2) / coefOld;
+ Vec4 pHad = (1. + k1) * pSum - k2 * pRec;
+ Vec4 pRecNew = (1. + k2) * pRec - k1 * pSum;
+
+ // Add the produced particle to the event record.
+ int iHad = event.append( idHad, 81, iParton.front(), iParton.back(),
+ 0, 0, 0, 0, pHad, mHad);
+
+ // Set decay vertex when this is displaced.
+ if (event[iParton.front()].hasVertex()) {
+ Vec4 vDec = event[iParton.front()].vDec();
+ event[iHad].vProd( vDec );
+ }
+
+ // Set lifetime of hadron.
+ event[iHad].tau( event[iHad].tau0() * Rndm::exp() );
+
+ // Mark original partons as hadronized and set their daughter range.
+ for (int i = 0; i < int(iParton.size()); ++i) {
+ event[ iParton[i] ].statusNeg();
+ event[ iParton[i] ].daughters(iHad, iHad);
+ }
+
+ // Copy down recoiling system, with boosted momentum. Update current partons.
+ RotBstMatrix M;
+ M.bst(pRec, pRecNew);
+ for (int i = 0; i < colConfig[iMax].size(); ++i) {
+ int iOld = colConfig[iMax].iParton[i];
+ // Do not touch negative iOld = beginning of new junction leg.
+ if (iOld >= 0) {
+ int iNew = event.copy(iOld, 72);
+ event[iNew].rotbst(M);
+ colConfig[iMax].iParton[i] = iNew;
+ }
+ }
+ colConfig[iMax].pSum = pRecNew;
+ colConfig[iMax].isCollected = true;
+
+ // Successfully done.
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// MultipleInteractions.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// SigmaMultiple and MultipleInteractions classes.
+
+#include "MultipleInteractions.h"
+
+// Internal headers for special processes.
+#include "SigmaQCD.h"
+#include "SigmaEW.h"
+#include "SigmaOnia.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The SigmaMultiple class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// The sum of outgoing masses must not be too close to the cm energy.
+const double SigmaMultiple::MASSMARGIN = 0.1;
+
+// Fraction of time not the dominant "gluon t-channel" process is picked.
+const double SigmaMultiple::OTHERFRAC = 0.2;
+
+//*********
+
+// Initialize the generation process for given beams.
+
+bool SigmaMultiple::init(int inState, int processLevel) {
+
+ // Reset vector sizes (necessary in case of re-initialization).
+ if (sigmaT.size() > 0) {
+ for (int i = 0; i < int(sigmaT.size()); ++i) delete sigmaT[i];
+ sigmaT.resize(0);
+ }
+ if (sigmaU.size() > 0) {
+ for (int i = 0; i < int(sigmaU.size()); ++i) delete sigmaU[i];
+ sigmaU.resize(0);
+ }
+
+ // Always store mimimal set of processes:QCD 2 -> 2 t-channel.
+
+ // Gluon-gluon instate.
+ if (inState == 0) {
+ sigmaT.push_back( new Sigma2gg2gg() );
+ sigmaU.push_back( new Sigma2gg2gg() );
+
+ // Quark-gluon instate.
+ } else if (inState == 1) {
+ sigmaT.push_back( new Sigma2qg2qg() );
+ sigmaU.push_back( new Sigma2qg2qg() );
+
+ // Quark-(anti)quark instate.
+ } else {
+ sigmaT.push_back( new Sigma2qq2qq() );
+ sigmaU.push_back( new Sigma2qq2qq() );
+ }
+
+ // Normally store QCD processes to new flavour.
+ if (processLevel > 0) {
+ if (inState == 0) {
+ sigmaT.push_back( new Sigma2gg2qqbar() );
+ sigmaU.push_back( new Sigma2gg2qqbar() );
+ sigmaT.push_back( new Sigma2gg2QQbar(4, 121) );
+ sigmaU.push_back( new Sigma2gg2QQbar(4, 121) );
+ sigmaT.push_back( new Sigma2gg2QQbar(5, 123) );
+ sigmaU.push_back( new Sigma2gg2QQbar(5, 123) );
+ } else if (inState == 2) {
+ sigmaT.push_back( new Sigma2qqbar2gg() );
+ sigmaU.push_back( new Sigma2qqbar2gg() );
+ sigmaT.push_back( new Sigma2qqbar2qqbarNew() );
+ sigmaU.push_back( new Sigma2qqbar2qqbarNew() );
+ sigmaT.push_back( new Sigma2qqbar2QQbar(4, 122) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar(4, 122) );
+ sigmaT.push_back( new Sigma2qqbar2QQbar(5, 124) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar(5, 124) );
+ }
+ }
+
+ // Optionally store electroweak processes, mainly photon production.
+ if (processLevel > 1) {
+ if (inState == 0) {
+ sigmaT.push_back( new Sigma2gg2ggamma() );
+ sigmaU.push_back( new Sigma2gg2ggamma() );
+ sigmaT.push_back( new Sigma2gg2gammagamma() );
+ sigmaU.push_back( new Sigma2gg2gammagamma() );
+ } else if (inState == 1) {
+ sigmaT.push_back( new Sigma2qg2qgamma() );
+ sigmaU.push_back( new Sigma2qg2qgamma() );
+ } else if (inState == 2) {
+ sigmaT.push_back( new Sigma2qqbar2ggamma() );
+ sigmaU.push_back( new Sigma2qqbar2ggamma() );
+ sigmaT.push_back( new Sigma2ffbar2gammagamma() );
+ sigmaU.push_back( new Sigma2ffbar2gammagamma() );
+ sigmaT.push_back( new Sigma2ffbar2ffbarsgm() );
+ sigmaU.push_back( new Sigma2ffbar2ffbarsgm() );
+ }
+ if (inState >= 2) {
+ sigmaT.push_back( new Sigma2ff2fftgmZ() );
+ sigmaU.push_back( new Sigma2ff2fftgmZ() );
+ sigmaT.push_back( new Sigma2ff2fftW() );
+ sigmaU.push_back( new Sigma2ff2fftW() );
+ }
+ }
+
+ // Optionally store charmonium and bottomonium production.
+ if (processLevel > 2) {
+ if (inState == 0) {
+ sigmaT.push_back( new Sigma2gg2QQbar3S11g(4, 401) );
+ sigmaU.push_back( new Sigma2gg2QQbar3S11g(4, 401) );
+ sigmaT.push_back( new Sigma2gg2QQbar3PJ1g(4, 0, 402) );
+ sigmaU.push_back( new Sigma2gg2QQbar3PJ1g(4, 0, 402) );
+ sigmaT.push_back( new Sigma2gg2QQbar3PJ1g(4, 1, 403) );
+ sigmaU.push_back( new Sigma2gg2QQbar3PJ1g(4, 1, 403) );
+ sigmaT.push_back( new Sigma2gg2QQbar3PJ1g(4, 2, 404) );
+ sigmaU.push_back( new Sigma2gg2QQbar3PJ1g(4, 2, 404) );
+ sigmaT.push_back( new Sigma2gg2QQbarX8g(4, 0, 411) );
+ sigmaU.push_back( new Sigma2gg2QQbarX8g(4, 0, 411) );
+ sigmaT.push_back( new Sigma2gg2QQbarX8g(4, 1, 412) );
+ sigmaU.push_back( new Sigma2gg2QQbarX8g(4, 1, 412) );
+ sigmaT.push_back( new Sigma2gg2QQbarX8g(4, 2, 413) );
+ sigmaU.push_back( new Sigma2gg2QQbarX8g(4, 2, 413) );
+ sigmaT.push_back( new Sigma2gg2QQbar3S11g(5, 501) );
+ sigmaU.push_back( new Sigma2gg2QQbar3S11g(5, 501) );
+ sigmaT.push_back( new Sigma2gg2QQbar3PJ1g(5, 0, 502) );
+ sigmaU.push_back( new Sigma2gg2QQbar3PJ1g(5, 0, 502) );
+ sigmaT.push_back( new Sigma2gg2QQbar3PJ1g(5, 1, 503) );
+ sigmaU.push_back( new Sigma2gg2QQbar3PJ1g(5, 1, 503) );
+ sigmaT.push_back( new Sigma2gg2QQbar3PJ1g(5, 2, 504) );
+ sigmaU.push_back( new Sigma2gg2QQbar3PJ1g(5, 2, 504) );
+ sigmaT.push_back( new Sigma2gg2QQbarX8g(5, 0, 511) );
+ sigmaU.push_back( new Sigma2gg2QQbarX8g(5, 0, 511) );
+ sigmaT.push_back( new Sigma2gg2QQbarX8g(5, 1, 512) );
+ sigmaU.push_back( new Sigma2gg2QQbarX8g(5, 1, 512) );
+ sigmaT.push_back( new Sigma2gg2QQbarX8g(5, 2, 513) );
+ sigmaU.push_back( new Sigma2gg2QQbarX8g(5, 2, 513) );
+ } else if (inState == 1) {
+ sigmaT.push_back( new Sigma2qg2QQbar3PJ1q(4, 0, 405) );
+ sigmaU.push_back( new Sigma2qg2QQbar3PJ1q(4, 0, 405) );
+ sigmaT.push_back( new Sigma2qg2QQbar3PJ1q(4, 1, 406) );
+ sigmaU.push_back( new Sigma2qg2QQbar3PJ1q(4, 1, 406) );
+ sigmaT.push_back( new Sigma2qg2QQbar3PJ1q(4, 2, 407) );
+ sigmaU.push_back( new Sigma2qg2QQbar3PJ1q(4, 2, 407) );
+ sigmaT.push_back( new Sigma2qg2QQbarX8q(4, 0, 414) );
+ sigmaU.push_back( new Sigma2qg2QQbarX8q(4, 0, 414) );
+ sigmaT.push_back( new Sigma2qg2QQbarX8q(4, 1, 415) );
+ sigmaU.push_back( new Sigma2qg2QQbarX8q(4, 1, 415) );
+ sigmaT.push_back( new Sigma2qg2QQbarX8q(4, 2, 416) );
+ sigmaU.push_back( new Sigma2qg2QQbarX8q(4, 2, 416) );
+ sigmaT.push_back( new Sigma2qg2QQbar3PJ1q(5, 0, 505) );
+ sigmaU.push_back( new Sigma2qg2QQbar3PJ1q(5, 0, 505) );
+ sigmaT.push_back( new Sigma2qg2QQbar3PJ1q(5, 1, 506) );
+ sigmaU.push_back( new Sigma2qg2QQbar3PJ1q(5, 1, 506) );
+ sigmaT.push_back( new Sigma2qg2QQbar3PJ1q(5, 2, 507) );
+ sigmaU.push_back( new Sigma2qg2QQbar3PJ1q(5, 2, 507) );
+ sigmaT.push_back( new Sigma2qg2QQbarX8q(5, 0, 514) );
+ sigmaU.push_back( new Sigma2qg2QQbarX8q(5, 0, 514) );
+ sigmaT.push_back( new Sigma2qg2QQbarX8q(5, 1, 515) );
+ sigmaU.push_back( new Sigma2qg2QQbarX8q(5, 1, 515) );
+ sigmaT.push_back( new Sigma2qg2QQbarX8q(5, 2, 516) );
+ sigmaU.push_back( new Sigma2qg2QQbarX8q(5, 2, 516) );
+ } else if (inState == 2) {
+ sigmaT.push_back( new Sigma2qqbar2QQbar3PJ1g(4, 0, 408) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar3PJ1g(4, 0, 408) );
+ sigmaT.push_back( new Sigma2qqbar2QQbar3PJ1g(4, 1, 409) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar3PJ1g(4, 1, 409) );
+ sigmaT.push_back( new Sigma2qqbar2QQbar3PJ1g(4, 2, 410) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar3PJ1g(4, 2, 410) );
+ sigmaT.push_back( new Sigma2qqbar2QQbarX8g(4, 0, 417) );
+ sigmaU.push_back( new Sigma2qqbar2QQbarX8g(4, 0, 417) );
+ sigmaT.push_back( new Sigma2qqbar2QQbarX8g(4, 1, 418) );
+ sigmaU.push_back( new Sigma2qqbar2QQbarX8g(4, 1, 418) );
+ sigmaT.push_back( new Sigma2qqbar2QQbarX8g(4, 2, 419) );
+ sigmaU.push_back( new Sigma2qqbar2QQbarX8g(4, 2, 419) );
+ sigmaT.push_back( new Sigma2qqbar2QQbar3PJ1g(5, 0, 508) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar3PJ1g(5, 0, 508) );
+ sigmaT.push_back( new Sigma2qqbar2QQbar3PJ1g(5, 1, 509) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar3PJ1g(5, 1, 509) );
+ sigmaT.push_back( new Sigma2qqbar2QQbar3PJ1g(5, 2, 510) );
+ sigmaU.push_back( new Sigma2qqbar2QQbar3PJ1g(5, 2, 510) );
+ sigmaT.push_back( new Sigma2qqbar2QQbarX8g(5, 0, 517) );
+ sigmaU.push_back( new Sigma2qqbar2QQbarX8g(5, 0, 517) );
+ sigmaT.push_back( new Sigma2qqbar2QQbarX8g(5, 1, 518) );
+ sigmaU.push_back( new Sigma2qqbar2QQbarX8g(5, 1, 518) );
+ sigmaT.push_back( new Sigma2qqbar2QQbarX8g(5, 2, 519) );
+ sigmaU.push_back( new Sigma2qqbar2QQbarX8g(5, 2, 519) );
+ }
+ }
+
+ // Resize arrays to match sizes above.
+ nChan = sigmaT.size();
+ needMasses.resize(nChan);
+ m3Fix.resize(nChan);
+ m4Fix.resize(nChan);
+ sHatMin.resize(nChan);
+ sigmaTval.resize(nChan);
+ sigmaUval.resize(nChan);
+
+ // Initialize the processes.
+ for (int i = 0; i < nChan; ++i) {
+ sigmaT[i]->initProc();
+ sigmaU[i]->initProc();
+
+ // Prepare for massive kinematics (but fixed masses!) where required.
+ needMasses[i] = false;
+ int id3Mass = sigmaT[i]->id3Mass();
+ int id4Mass = sigmaT[i]->id4Mass();
+ m3Fix[i] = 0.;
+ m4Fix[i] = 0.;
+ if (id3Mass > 0 || id4Mass > 0) {
+ needMasses[i] = true;
+ m3Fix[i] = ParticleDataTable::m0(id3Mass);
+ m4Fix[i] = ParticleDataTable::m0(id4Mass);
+ }
+ sHatMin[i] = pow2( m3Fix[i] + m4Fix[i] + MASSMARGIN);
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Calculate cross section summed over possibilities.
+
+double SigmaMultiple::sigma( int id1, int id2, double x1, double x2,
+ double sHat, double tHat, double uHat, double alpS, double alpEM) {
+
+ // Choose either the dominant process (in slot 0) or the rest of them.
+ bool pickOther = (Rndm::flat() < OTHERFRAC);
+
+ // Iterate over all subprocesses.
+ sigmaTsum = 0.;
+ sigmaUsum = 0.;
+ for (int i = 0; i < nChan; ++i) {
+ sigmaTval[i] = 0.;
+ sigmaUval[i] = 0.;
+
+ // Skip the not chosen processes.
+ if (i == 0 && pickOther) continue;
+ if (i > 0 && !pickOther) continue;
+
+ // t-channel-sampling contribution.
+ if (sHat > sHatMin[i]) {
+ sigmaT[i]->set2KinMI( x1, x2, sHat, tHat, uHat,
+ alpS, alpEM, needMasses[i], m3Fix[i], m4Fix[i]);
+ sigmaTval[i] = sigmaT[i]->sigmaHatWrap(id1, id2);
+ sigmaT[i]->pickInState(id1, id2);
+ // Correction factor for tHat rescaling in massive kinematics.
+ if (needMasses[i]) sigmaTval[i] *= sigmaT[i]->sHBetaMI() / sHat;
+ sigmaTsum += sigmaTval[i];
+ }
+
+ // u-channel-sampling contribution.
+ if (sHat > sHatMin[i]) {
+ sigmaU[i]->set2KinMI( x1, x2, sHat, uHat, tHat,
+ alpS, alpEM, needMasses[i], m3Fix[i], m4Fix[i]);
+ sigmaUval[i] = sigmaU[i]->sigmaHatWrap( id1, id2);
+ sigmaU[i]->pickInState(id1, id2);
+ // Correction factor for tHat rescaling in massive kinematics.
+ if (needMasses[i]) sigmaUval[i] *= sigmaU[i]->sHBetaMI() / sHat;
+ sigmaUsum += sigmaUval[i];
+ }
+
+ // Average of t- and u-channel sampling; corrected for not selected channels.
+ }
+ double sigmaAvg = 0.5 * (sigmaTsum + sigmaUsum);
+ if (pickOther) sigmaAvg /= OTHERFRAC;
+ if (!pickOther) sigmaAvg /= (1. - OTHERFRAC);
+ return sigmaAvg;
+
+}
+
+//*********
+
+// Return one subprocess, picked according to relative cross sections.
+
+SigmaProcess* SigmaMultiple::sigmaSel() {
+
+ // Decide between t- and u-channel-sampled kinematics.
+ pickedU = (Rndm::flat() * (sigmaTsum + sigmaUsum) < sigmaUsum);
+
+ // Pick one of t-channel-sampled processes.
+ if (!pickedU) {
+ double sigmaRndm = sigmaTsum * Rndm::flat();
+ int iPick = -1;
+ do sigmaRndm -= sigmaTval[++iPick];
+ while (sigmaRndm > 0.);
+ return sigmaT[iPick];
+
+ // Pick one of u-channel-sampled processes.
+ } else {
+ double sigmaRndm = sigmaUsum * Rndm::flat();
+ int iPick = -1;
+ do sigmaRndm -= sigmaUval[++iPick];
+ while (sigmaRndm > 0.);
+ return sigmaU[iPick];
+ }
+
+}
+
+//**************************************************************************
+
+// The MultipleInteractions class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Factorization scale pT2 by default, but could be shifted to pT2 + pT02.
+// (A priori possible, but problems for flavour threshold interpretation.)
+const bool MultipleInteractions::SHIFTFACSCALE = false;
+
+// Naive upper estimate of cross section too pessimistic, so reduce by this.
+const double MultipleInteractions::SIGMAFUDGE = 0.7;
+
+// Number of bins that the dpT2 / (pT2 + r * pT20)^2 range is split into.
+const int MultipleInteractions::NBINS = 100;
+
+// The r value above, picked to allow a flatter correct/trial cross section.
+const double MultipleInteractions::RPT20 = 0.25;
+
+// Reduce pT0 by factor pT0STEP if sigmaInt < SIGMASTEP * sigmaND.
+const double MultipleInteractions::PT0STEP = 0.9;
+const double MultipleInteractions::SIGMASTEP = 1.1;
+
+// Refuse too low expPow in impact parameter profile.
+const double MultipleInteractions::EXPPOWMIN = 0.4;
+
+// Define low-b region by interaction rate above given number.
+const double MultipleInteractions::PROBATLOWB = 0.6;
+
+// Basic step size for b integration; sometimes modified.
+const double MultipleInteractions::BSTEP = 0.01;
+
+// Stop b integration when integrand dropped enough.
+const double MultipleInteractions::BMAX = 1e-8;
+
+// Do not allow too large argument to exp function.
+const double MultipleInteractions::EXPMAX = 50.;
+
+// Convergence criterion for k iteration.
+const double MultipleInteractions::KCONVERGE = 1e-7;
+
+// Conversion of GeV^{-2} to mb for cross section.
+const double MultipleInteractions::CONVERT2MB = 0.389380;
+
+//*********
+
+// Initialize the generation process for given beams.
+
+bool MultipleInteractions::init( bool doMIinit, Info* infoPtrIn,
+ BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
+ SigmaTotal* sigmaTotPtrIn, ostream& os) {
+
+ // Store input pointers for future use. Done if no initialization.
+ infoPtr = infoPtrIn;
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+ sigmaTotPtr = sigmaTotPtrIn;
+ if (!doMIinit) return false;
+
+ // Matching in pT of hard interaction to further interactions.
+ pTmaxMatch = Settings::mode("MultipleInteractions:pTmaxMatch");
+
+ // Parameters of alphaStrong generation.
+ alphaSvalue = Settings::parm("MultipleInteractions:alphaSvalue");
+ alphaSorder = Settings::mode("MultipleInteractions:alphaSorder");
+
+ // Parameters of alphaEM generation.
+ alphaEMorder = Settings::mode("MultipleInteractions:alphaEMorder");
+
+ // Parameters of cross section generation.
+ Kfactor = Settings::parm("MultipleInteractions:Kfactor");
+
+ // Regularization of QCD evolution for pT -> 0.
+ pT0Ref = Settings::parm("MultipleInteractions:pT0Ref");
+ ecmRef = Settings::parm("MultipleInteractions:ecmRef");
+ ecmPow = Settings::parm("MultipleInteractions:ecmPow");
+ pTmin = Settings::parm("MultipleInteractions:pTmin");
+
+ // Impact parameter profile.
+ bProfile = Settings::mode("MultipleInteractions:bProfile");
+ coreRadius = Settings::parm("MultipleInteractions:coreRadius");
+ coreFraction = Settings::parm("MultipleInteractions:coreFraction");
+ expPow = Settings::parm("MultipleInteractions:expPow");
+ expPow = max(EXPPOWMIN, expPow);
+
+ // Process sets to include in machinery.
+ processLevel = Settings::mode("MultipleInteractions:processLevel");
+
+ // Various other parameters.
+ nQuarkIn = Settings::mode("MultipleInteractions:nQuarkIn");
+ nSample = Settings::mode("MultipleInteractions:nSample");
+
+ // Some common combinations for double Gaussian, as shorthand.
+ if (bProfile == 2) {
+ fracA = pow2(1. - coreFraction);
+ fracB = 2. * coreFraction * (1. - coreFraction);
+ fracC = pow2(coreFraction);
+ radius2B = 0.5 * (1. + pow2(coreRadius));
+ radius2C = pow2(coreRadius);
+
+ // Some common combinations for exp(b^pow), as shorthand.
+ } else if (bProfile == 3) {
+ hasLowPow = (expPow < 2.);
+ expRev = 2. / expPow - 1.;
+ }
+
+ // Initialize alpha_strong generation.
+ alphaS.init( alphaSvalue, alphaSorder);
+
+ // Initialize alphaEM generation.
+ alphaEM.init( alphaEMorder);
+
+ // Attach matrix-element calculation objects.
+ sigma2gg.init( 0, processLevel);
+ sigma2qg.init( 1, processLevel);
+ sigma2qqbarSame.init( 2, processLevel);
+ sigma2qq.init( 3, processLevel);
+
+ // Calculate invariant mass of system. Set current pT0 scale.
+ eCM = infoPtr->eCM();
+ sCM = eCM * eCM;
+ pT0 = pT0Ref * pow(eCM / ecmRef, ecmPow);
+
+ // Get the total inelastic and nondiffractive cross section. Output.
+ if (!sigmaTotPtr->hasSigmaTot()) return false;
+ sigmaND = sigmaTotPtr->sigmaND();
+ os << "\n *------- PYTHIA Multiple Interactions Initialization --"
+ << "-----* \n"
+ << " | "
+ << " | \n"
+ << " | sigmaNonDiffractive = " << fixed
+ << setprecision(2) << setw(7) << sigmaND << " mb | \n"
+ << " | "
+ << " | \n";
+
+ // The pT0 value may need to be decreased, if sigmaInt < sigmaND.
+ double pT4dSigmaMaxBeg = 0.;
+ for ( ; ; ) {
+
+ // Derived pT kinematics combinations.
+ pT20 = pT0*pT0;
+ pT2min = pTmin*pTmin;
+ pTmax = 0.5*eCM;
+ pT2max = pTmax*pTmax;
+ pT20R = RPT20 * pT20;
+ pT20minR = pT2min + pT20R;
+ pT20maxR = pT2max + pT20R;
+ pT20min0maxR = pT20minR * pT20maxR;
+ pT2maxmin = pT2max - pT2min;
+
+ // Provide upper estimate of interaction rate d(Prob)/d(pT2).
+ upperEnvelope();
+
+ // Integrate the parton-parton interaction cross section.
+ pT4dSigmaMaxBeg = pT4dSigmaMax;
+ jetCrossSection();
+
+ // Sufficiently big SigmaInt or reduce pT0. Output.
+ if (sigmaInt > SIGMASTEP * sigmaND) break;
+ os << " | pT0 = " << setw(5) << pT0 << " gives sigmaInteraction = "
+ << setw(7) << sigmaInt << " mb: rejected | \n";
+ pT0 *= PT0STEP;
+ }
+ os << " | pT0 = " << setw(5) << pT0 << " gives sigmaInteraction = "
+ << setw(7) << sigmaInt << " mb: accepted | \n"
+ << " | "
+ << " | \n"
+ << " *------- End PYTHIA Multiple Interactions Initialization"
+ << " ---* " << endl;
+
+ // Amount of violation from upperEnvelope to jetCrossSection.
+ if (pT4dSigmaMax > pT4dSigmaMaxBeg) {
+ ostringstream osWarn;
+ osWarn << "by factor " << fixed << setprecision(3)
+ << pT4dSigmaMax/pT4dSigmaMaxBeg;
+ infoPtr->errorMsg("Warning in MultipleInteractions::init:"
+ " maximum increased", osWarn.str());
+ }
+
+ // Calculate factor relating matter overlap and interaction rate.
+ overlapInit();
+
+ // Reset statistics.
+ SigmaMultiple* dSigma;
+ for (int i = 0; i < 4; ++i) {
+ if (i == 0) dSigma = &sigma2gg;
+ else if (i == 1) dSigma = &sigma2qg;
+ else if (i == 2) dSigma = &sigma2qqbarSame;
+ else dSigma = &sigma2qq;
+ int nProc = dSigma->nProc();
+ for (int iProc = 0; iProc < nProc; ++iProc)
+ nGen[ dSigma->codeProc(iProc) ] = 0;
+ }
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Select first = hardest pT in minbias process.
+// Requires separate treatment at low and high b values
+
+void MultipleInteractions::pTfirst() {
+
+ // Pick impact parameter and thereby interaction rate enhancement.
+ overlapFirst();
+ bSetInFirst = true;
+ double WTacc;
+
+ // At low b values evolve downwards with Sudakov.
+ if (isAtLowB) {
+ pT2 = pT2max;
+ do {
+
+ // Pick a pT using a quick-and-dirty cross section estimate.
+ pT2 = fastPT2(pT2);
+
+ // If fallen below lower cutoff then need to restart at top.
+ if (pT2 < pT2min) {
+ pT2 = pT2max;
+ WTacc = 0.;
+
+ // Else pick complete kinematics and evaluate cross-section correction.
+ } else WTacc = sigmaPT2(true) / dSigmaApprox;
+
+ // Loop until acceptable pT and acceptable kinematics.
+ } while (WTacc < Rndm::flat() || !dSigmaDtSel->final2KinMI());
+
+ // At high b values make preliminary pT choice without Sudakov factor.
+ } else {
+ do {
+ pT2 = pT20min0maxR / (pT20minR + Rndm::flat() * pT2maxmin) - pT20R;
+
+ // Evaluate upper estimate of cross section for this pT2 choice.
+ dSigmaApprox = pT4dSigmaMax / pow2(pT2 + pT20R);
+
+ // Pick complete kinematics and evaluate cross-section correction.
+ WTacc = sigmaPT2(true) / dSigmaApprox;
+
+ // Evaluate and include Sudakov factor.
+ WTacc *= sudakov( pT2, enhanceB);
+
+ // Loop until acceptable pT and acceptable kinematics.
+ } while (WTacc < Rndm::flat() || !dSigmaDtSel->final2KinMI());
+ }
+
+}
+
+//*********
+
+// Set up kinematics for first = hardest pT in minbias process.
+
+void MultipleInteractions::setupFirstSys( Event& process) {
+
+ // Remove any partons of previous failed interactions.
+ if (process.size() > 3) {
+ process.popBack( process.size() - 3);
+ process.initColTag();
+ }
+
+ // Loop over four partons and offset info relative to subprocess itself.
+ int colOffset = process.lastColTag();
+ double pTMI= 0.;
+ for (int i = 1; i <= 4; ++i) {
+ Particle parton = dSigmaDtSel->getParton(i);
+ if (i <= 2 ) parton.mothers( i, 0);
+ else parton.mothers( 3, 4);
+ if (i <= 2 ) parton.daughters( 5, 6);
+ else parton.daughters( 0, 0);
+ int col = parton.col();
+ if (col > 0) parton.col( col + colOffset);
+ int acol = parton.acol();
+ if (acol > 0) parton.acol( acol + colOffset);
+
+ // Put the partons into the event record.
+ process.append(parton);
+ if (i == 3) pTMI = parton.pT();
+ }
+
+ // Set scale from which to begin evolution.
+ process.scale( sqrt(pT2Fac) );
+
+ // Info on subprocess - specific to mimimum-bias events.
+ string nameSub = dSigmaDtSel->name();
+ int codeSub = dSigmaDtSel->code();
+ int nFinalSub = dSigmaDtSel->nFinal();
+ infoPtr->setSubType( nameSub, codeSub, nFinalSub);
+ infoPtr->setTypeMI( codeSub, pTMI);
+
+ // Further standard info on process.
+ infoPtr->setPDFalpha( id1, id2, xPDF1now, xPDF2now, pT2Fac, alpEM, alpS,
+ pT2Ren);
+ double m3 = dSigmaDtSel->m(3);
+ double m4 = dSigmaDtSel->m(4);
+ double theta = dSigmaDtSel->thetaMI();
+ double phi = dSigmaDtSel->phiMI();
+ infoPtr->setKin( x1, x2, sHat, tHat, uHat, sqrt(pT2), m3, m4, theta, phi);
+
+}
+
+//*********
+
+// Find whether to limit maximum scale of emissions.
+
+bool MultipleInteractions::limitPTmax( Event& event) {
+
+ // User-set cases.
+ if (pTmaxMatch == 1) return true;
+ if (pTmaxMatch == 2) return false;
+
+ // Look if only quarks (u, d, s, c, b), gluons and photons in final state.
+ bool onlyQGP = true;
+ for (int i = 5; i < event.size(); ++i)
+ if (event[i].status() != -21) {
+ int idAbs = event[i].idAbs();
+ if (idAbs > 5 && idAbs != 21 && idAbs != 22) onlyQGP = false;
+ }
+ return (onlyQGP);
+
+}
+
+//*********
+
+// Select next pT in downwards evolution.
+
+double MultipleInteractions::pTnext( double pTbegAll, double pTendAll) {
+
+ // Pick a pT using a quick-and-dirty cross section estimate.
+ double WTacc;
+ double pT2end = pow2( max(pTmin, pTendAll) );
+ pT2 = pow2(pTbegAll);
+ do {
+ pT2 = fastPT2(pT2);
+ if (pT2 < pT2end) return 0.;
+
+ // Pick complete kinematics and evaluate cross-section correction.
+ // Note: dSigmaApprox was set in fastPT2 above.
+ WTacc = sigmaPT2(false) / dSigmaApprox;
+ if (WTacc > 1.) infoPtr->errorMsg("Warning in MultipleInteractions::"
+ "pTnext: weight above unity");
+
+ // Decide whether to keep the event.
+ } while (WTacc < Rndm::flat() || !dSigmaDtSel->final2KinMI());
+
+ // Done.
+ return sqrt(pT2);
+
+}
+
+//*********
+
+// Set up the kinematics of the 2 -> 2 scattering process,
+// and store the scattering in the event record.
+
+void MultipleInteractions::scatter( Event& event) {
+
+ // Loop over four partons and offset info relative to subprocess itself.
+ int motherOffset = event.size();
+ int colOffset = event.lastColTag();
+ double pTMI= 0.;
+ for (int i = 1; i <= 4; ++i) {
+ Particle parton = dSigmaDtSel->getParton(i);
+ if (i <= 2 ) parton.mothers( i, 0);
+ else parton.mothers( motherOffset, motherOffset + 1);
+ if (i <= 2 ) parton.daughters( motherOffset + 2, motherOffset + 3);
+ else parton.daughters( 0, 0);
+ int col = parton.col();
+ if (col > 0) parton.col( col + colOffset);
+ int acol = parton.acol();
+ if (acol > 0) parton.acol( acol + colOffset);
+
+ // Put the partons into the event record.
+ event.append(parton);
+ if (i == 3) pTMI = parton.pT();
+ }
+
+ // Store participating partons as a new set in list of all systems.
+ int iSys = event.newSystem();
+ for (int i = 0; i < 4; ++i) event.addToSystem(iSys, motherOffset + i);
+
+ // Add scattered partons to list in beam remnants.
+ int iA = beamAPtr->append( motherOffset, id1, x1);
+ int iB = beamBPtr->append( motherOffset + 1, id2, x2);
+
+ // Find whether incoming partons are valence or sea, so prepared for ISR.
+ beamAPtr->xfISR( iA, id1, x1, pT2);
+ beamAPtr->pickValSeaComp();
+ beamBPtr->xfISR( iB, id2, x2, pT2);
+ beamBPtr->pickValSeaComp();
+
+ // Store info on subprocess code.
+ int codeMI = dSigmaDtSel->code();
+ infoPtr->setTypeMI( codeMI, pTMI);
+
+ // Done.
+}
+
+//*********
+
+// Determine constant in d(Prob)/d(pT2) < const / (pT2 + r * pT20)^2.
+
+void MultipleInteractions::upperEnvelope() {
+
+ // Initially determine constant in jet cross section upper estimate
+ // d(sigma_approx)/d(pT2) < const / (pT2 + r * pT20)^2.
+ pT4dSigmaMax = 0.;
+
+ // Loop thorough allowed pT range logarithmically evenly.
+ for (int iPT = 0; iPT < NBINS; ++iPT) {
+ double pT = pTmin * pow( pTmax/pTmin, (iPT + 0.5) / NBINS);
+ pT2 = pT*pT;
+ pT2shift = pT2 + pT20;
+ pT2Ren = pT2shift;
+ pT2Fac = (SHIFTFACSCALE) ? pT2shift : pT2;
+ xT = 2. * pT / eCM;
+
+ // Evaluate parton density sums at x1 = x2 = xT.
+ double xPDF1sumMax = (9./4.) * beamAPtr->xf(21, xT, pT2Fac);
+ for (int id = 1; id <= nQuarkIn; ++id)
+ xPDF1sumMax += beamAPtr->xf( id, xT, pT2Fac)
+ + beamAPtr->xf(-id, xT, pT2Fac);
+ double xPDF2sumMax = (9./4.) * beamBPtr->xf(21, xT, pT2Fac);
+ for (int id = 1; id <= nQuarkIn; ++id)
+ xPDF2sumMax += beamBPtr->xf( id, xT, pT2Fac)
+ + beamBPtr->xf(-id, xT, pT2Fac);
+
+ // Evaluate alpha_strong and _EM, matrix element and phase space volume.
+ alpS = alphaS.alphaS(pT2Ren);
+ alpEM = alphaEM.alphaEM(pT2Ren);
+ double dSigmaPartonApprox = CONVERT2MB * Kfactor * 0.5 * M_PI
+ * pow2(alpS / pT2shift);
+ double yMax = log(1./xT + sqrt(1./(xT*xT) - 1.));
+ double volumePhSp = pow2(2. * yMax);
+
+ // Final comparison to determine upper estimate.
+ double dSigmaApproxNow = SIGMAFUDGE * xPDF1sumMax * xPDF2sumMax
+ * dSigmaPartonApprox * volumePhSp;
+ double pT4dSigmaNow = pow2(pT2 + pT20R) * dSigmaApproxNow;
+ if ( pT4dSigmaNow > pT4dSigmaMax) pT4dSigmaMax = pT4dSigmaNow;
+ }
+
+ // Get wanted constant by dividing by the nondiffractive cross section.
+ pT4dProbMax = pT4dSigmaMax / sigmaND;
+
+}
+
+//*********
+
+// Integrate the parton-parton interaction cross section,
+// using stratified Monte Carlo sampling.
+// Store result in pT bins for use as Sudakov form factors.
+
+void MultipleInteractions::jetCrossSection() {
+
+ // Common factor from bin size in dpT2 / (pT2 + r * pT20)^2 and statistics.
+ double sigmaFactor = (1. / pT20minR - 1. / pT20maxR) / (NBINS * nSample);
+
+ // Loop through allowed pT range evenly in dpT2 / (pT2 + r * pT20)^2.
+ sigmaInt = 0.;
+ double dSigmaMax = 0.;
+ sudExpPT[NBINS] = 0.;
+ for (int iPT = NBINS - 1; iPT >= 0; --iPT) {
+ double sigmaSum = 0.;
+
+ // In each pT bin sample a number of random pT values.
+ for (int iSample = 0; iSample < nSample; ++iSample) {
+ double mappedPT2 = 1. - (iPT + Rndm::flat()) / NBINS;
+ pT2 = pT20min0maxR / (pT20minR + mappedPT2 * pT2maxmin) - pT20R;
+
+ // Evaluate cross section dSigma/dpT2 in phase space point.
+ double dSigma = sigmaPT2(true);
+
+ // Multiply by (pT2 + r * pT20)^2 to compensate for pT sampling. Sum.
+ dSigma *= pow2(pT2 + pT20R);
+ sigmaSum += dSigma;
+ if (dSigma > dSigmaMax) dSigmaMax = dSigma;
+ }
+
+ // Store total cross section and exponent of Sudakov.
+ sigmaSum *= sigmaFactor;
+ sigmaInt += sigmaSum;
+ sudExpPT[iPT] = sudExpPT[iPT + 1] + sigmaSum / sigmaND;
+
+ // End of loop over pT values.
+ }
+
+ // Update upper estimate of differential cross section. Done.
+ if (dSigmaMax > pT4dSigmaMax) {
+ pT4dSigmaMax = dSigmaMax;
+ pT4dProbMax = dSigmaMax / sigmaND;
+ }
+
+}
+
+//*********
+
+// Evaluate "Sudakov form factor" for not having a harder interaction
+// at the selected b value, given the pT scale of the event.
+
+double MultipleInteractions::sudakov(double pT2sud, double enhance) {
+
+ // Find bin the pT2 scale falls in.
+ double xBin = (pT2sud - pT2min) * pT20maxR
+ / (pT2maxmin * (pT2sud + pT20R));
+ xBin = max(1e-6, min(NBINS - 1e-6, NBINS * xBin) );
+ int iBin = int(xBin);
+
+ // Interpolate inside bin. Optionally include enhancement factor.
+ double sudExp = sudExpPT[iBin] + (xBin - iBin)
+ * (sudExpPT[iBin + 1] - sudExpPT[iBin]);
+ return exp( -enhance * sudExp);
+
+}
+
+//*********
+
+// Pick a trial next pT, based on a simple upper estimate of the
+// d(sigma)/d(pT2) spectrum.
+
+double MultipleInteractions::fastPT2( double pT2beg) {
+
+ // Use d(Prob)/d(pT2) < pT4dProbMax / (pT2 + r * pT20)^2.
+ double pT20begR = pT2beg + pT20R;
+ double pT4dProbMaxNow = pT4dProbMax * enhanceB;
+ double pT2try = pT4dProbMaxNow * pT20begR
+ / (pT4dProbMaxNow - pT20begR * log(Rndm::flat())) - pT20R;
+
+ // Save cross section associated with ansatz above. Done.
+ dSigmaApprox = pT4dSigmaMax / pow2(pT2try + pT20R);
+ return pT2try;
+
+}
+
+//*********
+
+// Calculate the actual cross section to decide whether fast choice is OK.
+// Select flavours and kinematics for interaction at given pT.
+// Slightly different treatment for first interaction and subsequent ones.
+
+double MultipleInteractions::sigmaPT2(bool isFirst) {
+
+ // Derive shifted pT2 and rapidity limits from chosen pT2.
+ pT2shift = pT2 + pT20;
+ pT2Ren = pT2shift;
+ pT2Fac = (SHIFTFACSCALE) ? pT2shift : pT2;
+ xT = 2. * sqrt(pT2) / eCM;
+ if (xT >= 1.) return 0.;
+ xT2 = xT*xT;
+ double yMax = log(1./xT + sqrt(1./xT2 - 1.));
+
+ // Select rapidities y3 and y4 of the two produced partons.
+ double y3 = yMax * (2. * Rndm::flat() - 1.);
+ double y4 = yMax * (2. * Rndm::flat() - 1.);
+ y = 0.5 * (y3 + y4);
+
+ // Reject some events at large rapidities to improve efficiency.
+ // (Don't have to evaluate PDF's and ME's.)
+ double WTy = (1. - pow2(y3/yMax)) * (1. - pow2(y4/yMax));
+ if (WTy < Rndm::flat()) return 0.;
+
+ // Failure if x1 or x2 exceed what is left in respective beam.
+ x1 = 0.5 * xT * (exp(y3) + exp(y4));
+ x2 = 0.5 * xT * (exp(-y3) + exp(-y4));
+ if (isFirst) {
+ if (x1 > 1. || x2 > 1.) return 0.;
+ } else {
+ if (x1 > beamAPtr->xMax() || x2 > beamBPtr->xMax()) return 0.;
+ }
+ tau = x1 * x2;
+
+ // Begin evaluate parton densities at actual x1 and x2.
+ double xPDF1[21];
+ double xPDF1sum = 0.;
+ double xPDF2[21];
+ double xPDF2sum = 0.;
+
+ // For first interaction use normal densities.
+ if (isFirst) {
+ for (int id = -nQuarkIn; id <= nQuarkIn; ++id) {
+ if (id == 0) xPDF1[10] = (9./4.) * beamAPtr->xf(21, x1, pT2Fac);
+ else xPDF1[id+10] = beamAPtr->xf(id, x1, pT2Fac);
+ xPDF1sum += xPDF1[id+10];
+ }
+ for (int id = -nQuarkIn; id <= nQuarkIn; ++id) {
+ if (id == 0) xPDF2[10] = (9./4.) * beamBPtr->xf(21, x2, pT2Fac);
+ else xPDF2[id+10] = beamBPtr->xf(id, x2, pT2Fac);
+ xPDF2sum += xPDF2[id+10];
+ }
+
+ // For subsequent interactions use rescaled densities.
+ } else {
+ for (int id = -nQuarkIn; id <= nQuarkIn; ++id) {
+ if (id == 0) xPDF1[10] = (9./4.) * beamAPtr->xfMI(21, x1, pT2Fac);
+ else xPDF1[id+10] = beamAPtr->xfMI(id, x1, pT2Fac);
+ xPDF1sum += xPDF1[id+10];
+ }
+ for (int id = -nQuarkIn; id <= nQuarkIn; ++id) {
+ if (id == 0) xPDF2[10] = (9./4.) * beamBPtr->xfMI(21, x2, pT2Fac);
+ else xPDF2[id+10] = beamBPtr->xfMI(id, x2, pT2Fac);
+ xPDF2sum += xPDF2[id+10];
+ }
+ }
+
+ // Select incoming flavours according to actual PDF's.
+ id1 = -nQuarkIn - 1;
+ double temp = xPDF1sum * Rndm::flat();
+ do { xPDF1now = xPDF1[(++id1) + 10]; temp -= xPDF1now; }
+ while (temp > 0. && id1 < nQuarkIn);
+ if (id1 == 0) id1 = 21;
+ id2 = -nQuarkIn-1;
+ temp = xPDF2sum * Rndm::flat();
+ do { xPDF2now = xPDF2[(++id2) + 10]; temp -= xPDF2now;}
+ while (temp > 0. && id2 < nQuarkIn);
+ if (id2 == 0) id2 = 21;
+
+ // Assign pointers to processes relevant for incoming flavour choice:
+ // g + g, q + g, q + qbar (same flavour), q + q(bar) (the rest).
+ // Factor 4./9. per incoming gluon to compensate for preweighting.
+ SigmaMultiple* dSigma;
+ double gluFac = 1.;
+ if (id1 == 21 && id2 == 21) {
+ dSigma = &sigma2gg;
+ gluFac = 16. / 81.;
+ } else if (id1 == 21 || id2 == 21) {
+ dSigma = &sigma2qg;
+ gluFac = 4. / 9.;
+ } else if (id1 == -id2) dSigma = &sigma2qqbarSame;
+ else dSigma = &sigma2qq;
+
+ // Prepare to generate differential cross sections.
+ alpS = alphaS.alphaS(pT2Ren);
+ alpEM = alphaEM.alphaEM(pT2Ren);
+ sHat = tau * sCM;
+ double root = sqrtpos(1. - xT2 / tau);
+ tHat = -0.5 * sHat * (1. - root);
+ uHat = -0.5 * sHat * (1. + root);
+
+ // Evaluate cross sections, include possibility of K factor.
+ // Use kinematics for two symmetrical configurations (tHat <-> uHat).
+ // (Not necessary, but makes for better MC efficiency.)
+ double dSigmaPartonCorr = Kfactor * gluFac
+ * dSigma->sigma( id1, id2, x1, x2, sHat, tHat, uHat, alpS, alpEM);
+
+ // Pick one of the possible channels summed above.
+ dSigmaDtSel = dSigma->sigmaSel();
+ if (dSigma->swapTU()) swap( tHat, uHat);
+
+ // Combine cross section, pdf's and phase space integral.
+ double volumePhSp = pow2(2. * yMax) / WTy;
+ double dSigmaCorr = dSigmaPartonCorr * xPDF1sum * xPDF2sum * volumePhSp;
+
+ // Dampen cross section at small pT values; part of formalism.
+ // Use pT2 corrected for massive kinematics at this step.
+ double pT2massive = dSigmaDtSel->pT2MI();
+ dSigmaCorr *= pow2( pT2massive / (pT2massive + pT20) );
+
+ // Done.
+ return dSigmaCorr;
+}
+
+
+//*********
+
+// Calculate factor relating matter overlap and interaction rate,
+// i.e. k in <n_interaction(b)> = k * overlap(b) (neglecting
+// n_int = 0 corrections and energy-momentum conservation effects).
+
+void MultipleInteractions::overlapInit() {
+
+ // Initial values for iteration. Step size of b integration.
+ nAvg = sigmaInt / sigmaND;
+ kNow = 0.5;
+ int stepDir = 1;
+ double deltaB = BSTEP;
+ if (bProfile == 2) deltaB *= min( 0.5, 2.5 * coreRadius);
+ if (bProfile == 3) deltaB *= max(1., pow(2. / expPow, 1. / expPow));
+
+ // Further variables, with dummy initial values.
+ double nNow = 0.;
+ double kLow = 0.;
+ double nLow = 0.;
+ double kHigh = 0.;
+ double nHigh = 0.;
+ double overlapNow = 0.;
+ double probNow = 0.;
+ double overlapInt = 0.5;
+ double probInt = 0.;
+ double probOverlapInt = 0.;
+ double bProbInt = 0.;
+ normPi = 1. / (2. * M_PI);
+
+ // Subdivision into low-b and high-b region by interaction rate.
+ bool pastBDiv = false;
+ double overlapHighB = 0.;
+
+ // First close k into an interval by binary steps,
+ // then find k by successive interpolation.
+ do {
+ if (stepDir == 1) kNow *= 2.;
+ else if (stepDir == -1) kNow *= 0.5;
+ else kNow = kLow + (nAvg - nLow) * (kHigh - kLow) / (nHigh - nLow);
+
+ // Overlap trivial if no impact parameter dependence.
+ if (bProfile <= 0 || bProfile > 3) {
+ probInt = 0.5 * M_PI * (1. - exp(-kNow));
+ probOverlapInt = probInt / M_PI;
+ bProbInt = probInt;
+
+ // Else integrate overlap over impact parameter.
+ } else {
+
+ // Reset integrals.
+ overlapInt = (bProfile == 3) ? 0. : 0.5;
+ probInt = 0.;
+ probOverlapInt = 0.;
+ bProbInt = 0.;
+ pastBDiv = false;
+ overlapHighB = 0.;
+
+ // Step in b space.
+ double b = -0.5 * deltaB;
+ double bArea = 0.;
+ do {
+ b += deltaB;
+ bArea = 2. * M_PI * b * deltaB;
+
+ // Evaluate overlap at current b value.
+ if (bProfile == 1) {
+ overlapNow = normPi * exp( -b*b);
+ } else if (bProfile == 2) {
+ overlapNow = normPi * ( fracA * exp( -min(EXPMAX, b*b))
+ + fracB * exp( -min(EXPMAX, b*b / radius2B)) / radius2B
+ + fracC * exp( -min(EXPMAX, b*b / radius2C)) / radius2C );
+ } else {
+ overlapNow = normPi * exp( -pow( b, expPow));
+ overlapInt += bArea * overlapNow;
+ }
+ if (pastBDiv) overlapHighB += bArea * overlapNow;
+
+ // Calculate interaction probability and integrate.
+ probNow = 1. - exp( -min(EXPMAX, M_PI * kNow * overlapNow));
+ probInt += bArea * probNow;
+ probOverlapInt += bArea * overlapNow * probNow;
+ bProbInt += b * bArea * probNow;
+
+ // Check when interaction probability has dropped sufficiently.
+ if (!pastBDiv && probNow < PROBATLOWB) {
+ bDiv = b + 0.5 * deltaB;
+ pastBDiv = true;
+ }
+
+ // Continue out in b until overlap too small.
+ } while (b < 1. || b * probNow > BMAX);
+ }
+
+ // Ratio of b-integrated k * overlap / (1 - exp( - k * overlap)).
+ nNow = M_PI * kNow * overlapInt / probInt;
+
+ // Replace lower or upper limit of k.
+ if (nNow < nAvg) {
+ kLow = kNow;
+ nLow = nNow;
+ if (stepDir == -1) stepDir = 0;
+ } else {
+ kHigh = kNow;
+ nHigh = nNow;
+ if (stepDir == 1) stepDir = -1;
+ }
+
+ // Continue iteration until convergence.
+ } while (abs(nNow - nAvg) > KCONVERGE * nAvg);
+
+ // Save relevant final numbers for overlap values.
+ double avgOverlap = probOverlapInt / probInt;
+ zeroIntCorr = probOverlapInt / overlapInt;
+ normOverlap = normPi * zeroIntCorr / avgOverlap;
+ bAvg = bProbInt / probInt;
+
+ // Relative rates for preselection of low-b and high-b region.
+ // Other useful combinations for subsequent selection.
+ if (bProfile > 0 && bProfile <= 3) {
+ probLowB = M_PI * bDiv*bDiv;
+ double probHighB = M_PI * kNow * overlapHighB;
+ if (bProfile == 1) probHighB = M_PI * kNow * 0.5 * exp( -bDiv*bDiv);
+ else if (bProfile == 2) {
+ fracAhigh = fracA * exp( -bDiv*bDiv);
+ fracBhigh = fracB * exp( -bDiv*bDiv / radius2B);
+ fracChigh = fracC * exp( -bDiv*bDiv / radius2C);
+ fracABChigh = fracAhigh + fracBhigh + fracChigh;
+ probHighB = M_PI * kNow * 0.5 * fracABChigh;
+ } else {
+ cDiv = pow( bDiv, expPow);
+ cMax = max(2. * expRev, cDiv);
+ }
+ probLowB /= (probLowB + probHighB);
+ }
+
+}
+
+//*********
+
+// Pick impact parameter and interaction rate enhancement beforehand,
+// i.e. before even the hardest interaction for minimum-bias events.
+
+void MultipleInteractions::overlapFirst() {
+
+ // Trivial values if no impact parameter dependence.
+ if (bProfile <= 0 || bProfile > 3) {
+ bNow = bAvg;
+ enhanceB = zeroIntCorr;
+ bIsSet = true;
+ isAtLowB = true;
+ return;
+ }
+
+ // Preliminary choice between and inside low-b and high-b regions.
+ double overlapNow = 0.;
+ double probAccept = 0.;
+ do {
+
+ // Treatment in low-b region: pick b flat in area.
+ if (Rndm::flat() < probLowB) {
+ isAtLowB = true;
+ bNow = bDiv * sqrt(Rndm::flat());
+ if (bProfile == 1) overlapNow = normPi * exp( -bNow*bNow);
+ else if (bProfile == 2) overlapNow = normPi *
+ ( fracA * exp( -bNow*bNow)
+ + fracB * exp( -bNow*bNow / radius2B) / radius2B
+ + fracC * exp( -bNow*bNow / radius2C) / radius2C );
+ else overlapNow = normPi * exp( -pow( bNow, expPow));
+ probAccept = 1. - exp( -min(EXPMAX, M_PI * kNow * overlapNow));
+
+ // Treatment in high-b region: pick b according to overlap.
+ } else {
+
+ // For simple and double Gaussian pick b according to exp(-b^2 / r^2).
+ if (bProfile == 1) {
+ bNow = sqrt(bDiv*bDiv - log(Rndm::flat()));
+ overlapNow = normPi * exp( -min(EXPMAX, bNow*bNow));
+ } else if (bProfile == 2) {
+ double pickFrac = Rndm::flat() * fracABChigh;
+ if (pickFrac < fracAhigh) bNow = sqrt(bDiv*bDiv - log(Rndm::flat()));
+ else if (pickFrac < fracAhigh + fracBhigh)
+ bNow = sqrt(bDiv*bDiv - radius2B * log(Rndm::flat()));
+ else bNow = sqrt(bDiv*bDiv - radius2C * log(Rndm::flat()));
+ overlapNow = normPi * ( fracA * exp( -min(EXPMAX, bNow*bNow))
+ + fracB * exp( -min(EXPMAX, bNow*bNow / radius2B)) / radius2B
+ + fracC * exp( -min(EXPMAX, bNow*bNow / radius2C)) / radius2C );
+
+ // For exp( - b^expPow) transform to variable c = b^expPow so that
+ // f(b) = b * exp( - b^expPow) -> f(c) = c^r * exp(-c) with r = expRev.
+ // case hasLowPow: expPow < 2 <=> r > 0: preselect according to
+ // f(c) < N exp(-c/2) and then accept with N' * c^r * exp(-c/2).
+ } else if (hasLowPow) {
+ double cNow, acceptC;
+ do {
+ cNow = cDiv - 2. * log(Rndm::flat());
+ acceptC = pow(cNow / cMax, expRev) * exp( -0.5 * (cNow - cMax));
+ } while (acceptC < Rndm::flat());
+ bNow = pow( cNow, 1. / expPow);
+ overlapNow = normPi * exp( -cNow);
+
+ // case !hasLowPow: expPow >= 2 <=> - 1 < r < 0: preselect according to
+ // f(c) < N exp(-c) and then accept with N' * c^r.
+ } else {
+ double cNow, acceptC;
+ do {
+ cNow = cDiv - log(Rndm::flat());
+ acceptC = pow(cNow / cDiv, expRev);
+ } while (acceptC < Rndm::flat());
+ bNow = pow( cNow, 1. / expPow);
+ overlapNow = normPi * exp( -cNow);
+ }
+ double temp = M_PI * kNow *overlapNow;
+ probAccept = (1. - exp( -min(EXPMAX, temp))) / temp;
+ }
+
+ // Confirm choice of b value. Derive enhancement factor.
+ } while (probAccept < Rndm::flat());
+ enhanceB = (normOverlap / normPi) * overlapNow ;
+
+ // Done.
+ bIsSet = true;
+
+}
+
+//*********
+
+// Pick impact parameter and interaction rate enhancement afterwards,
+// i.e. after a hard interaction is known but before rest of MI treatment.
+
+void MultipleInteractions::overlapNext(double pTscale) {
+
+ // Default, valid for bProfile = 0. Also initial Sudakov.
+ enhanceB = zeroIntCorr;
+ if (bProfile <= 0 || bProfile > 3) return;
+ double pT2scale = pTscale*pTscale;
+
+ // Begin loop over pT-dependent rejection of b value.
+ do {
+
+ // Flat enhancement distribution for simple Gaussian.
+ if (bProfile == 1) {
+ double expb2 = Rndm::flat();
+ enhanceB = normOverlap * expb2;
+ bNow = sqrt( -log(expb2));
+
+ // For double Gaussian go the way via b, according to each Gaussian.
+ } else if (bProfile == 2) {
+ double bType = Rndm::flat();
+ double b2 = -log( Rndm::flat() );
+ if (bType < fracA) ;
+ else if (bType < fracA + fracB) b2 *= radius2B;
+ else b2 *= radius2C;
+ enhanceB = normOverlap * ( fracA * exp( -min(EXPMAX, b2))
+ + fracB * exp( -min(EXPMAX, b2 / radius2B)) / radius2B
+ + fracC * exp( -min(EXPMAX, b2 / radius2C)) / radius2C );
+ bNow = sqrt(b2);
+
+ // For exp( - b^expPow) transform to variable c = b^expPow so that
+ // f(b) = b * exp( - b^expPow) -> f(c) = c^r * exp(-c) with r = expRev.
+ // case hasLowPow: expPow < 2 <=> r > 0:
+ // f(c) < r^r exp(-r) for c < 2r, < (2r)^r exp(-r-c/2) for c > 2r.
+ } else if (hasLowPow) {
+ double cNow, acceptC;
+ double probLowC = expRev / (expRev + pow(2., expRev) * exp( - expRev));
+ do {
+ if (Rndm::flat() < probLowC) {
+ cNow = 2. * expRev * Rndm::flat();
+ acceptC = pow( cNow / expRev, expRev) * exp(expRev - cNow);
+ } else {
+ cNow = 2. * (expRev - log( Rndm::flat() ));
+ acceptC = pow(0.5 * cNow / expRev, expRev) * exp(expRev - 0.5 * cNow);
+ }
+ } while (acceptC < Rndm::flat());
+ enhanceB = normOverlap *exp(-cNow);
+ bNow = pow( cNow, 1. / expPow);
+
+ // case !hasLowPow: expPow >= 2 <=> - 1 < r < 0:
+ // f(c) < c^r for c < 1, f(c) < exp(-c) for c > 1.
+ } else {
+ double cNow, acceptC;
+ double probLowC = expPow / (2. * exp(-1.) + expPow);
+ do {
+ if (Rndm::flat() < probLowC) {
+ cNow = pow( Rndm::flat(), 0.5 * expPow);
+ acceptC = exp(-cNow);
+ } else {
+ cNow = 1. - log( Rndm::flat() );
+ acceptC = pow( cNow, expRev);
+ }
+ } while (acceptC < Rndm::flat());
+ enhanceB = normOverlap * exp(-cNow);
+ bNow = pow( cNow, 1. / expPow);
+ }
+
+ // Evaluate "Sudakov form factor" for not having a harder interaction.
+ } while (sudakov(pT2scale, enhanceB) < Rndm::flat());
+
+ // Done.
+ bIsSet = true;
+}
+
+//*********
+
+// Printe statistics on number of multiple-interactions processes.
+
+void MultipleInteractions::statistics(bool reset, ostream& os) {
+
+ // Header.
+ os << "\n *------- PYTHIA Multiple Interactions Statistics --------"
+ << "---*\n"
+ << " | "
+ << " |\n"
+ << " | Note: excludes hardest subprocess if already listed above "
+ << " |\n"
+ << " | "
+ << " |\n"
+ << " | Subprocess Code | Times"
+ << " |\n"
+ << " | | "
+ << " |\n"
+ << " |------------------------------------------------------------"
+ << "-|\n"
+ << " | | "
+ << " |\n";
+
+ // Loop over existing processes. Sum of all subprocesses.
+ int numberSum = 0;
+ for ( map<int, int>::iterator iter = nGen.begin(); iter != nGen.end();
+ ++iter) {
+ int code = iter -> first;
+ int number = iter->second;
+ numberSum += number;
+
+ // Find process name that matches code.
+ string name = " ";
+ bool foundName = false;
+ SigmaMultiple* dSigma;
+ for (int i = 0; i < 4; ++i) {
+ if (i == 0) dSigma = &sigma2gg;
+ else if (i == 1) dSigma = &sigma2qg;
+ else if (i == 2) dSigma = &sigma2qqbarSame;
+ else dSigma = &sigma2qq;
+ int nProc = dSigma->nProc();
+ for (int iProc = 0; iProc < nProc; ++iProc)
+ if (dSigma->codeProc(iProc) == code) {
+ name = dSigma->nameProc(iProc);
+ foundName = true;
+ }
+ if (foundName) break;
+ }
+
+ // Print individual process info.
+ os << " | " << left << setw(40) << name << right << setw(5) << code
+ << " | " << setw(11) << number << " |\n";
+ }
+
+ // Print summed process info.
+ os << " | "
+ << " |\n"
+ << " | " << left << setw(45) << "sum" << right << " | " << setw(11)
+ << numberSum << " |\n";
+
+ // Listing finished.
+ os << " | | "
+ << " |\n"
+ << " *------- End PYTHIA Multiple Interactions Statistics -------"
+ << "-*" << endl;
+
+ // Optionally reset statistics contants.
+ if (reset) for ( map<int, int>::iterator iter = nGen.begin();
+ iter != nGen.end(); ++iter) iter->second = 0;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// ParticleData.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// DecayChannel, ParticleDataEntry and ParticleDataTable classes.
+
+#include "ParticleData.h"
+#include "StandardModel.h"
+
+// Allow string and character manipulation.
+#include <cctype>
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// DecayChannel class.
+// This class holds info on a single decay channel.
+
+//*********
+
+// Check whether id1 occurs anywhere in product list.
+
+bool DecayChannel::contains(int id1) const {
+
+ bool found1 = false;
+ for (int i = 0; i < nProd; ++i) if (prod[i] == id1) found1 = true;
+ return found1;
+
+}
+
+//*********
+
+// Check whether id1 and id2 occur anywhere in product list.
+// iF ID1 == ID2 then two copies of this particle must be present.
+
+bool DecayChannel::contains(int id1, int id2) const {
+
+ bool found1 = false;
+ bool found2 = false;
+ for (int i = 0; i < nProd; ++i) {
+ if (!found1 && prod[i] == id1) {found1 = true; continue;}
+ if (!found2 && prod[i] == id2) {found2 = true; continue;}
+ }
+ return found1 && found2;
+
+}
+
+//*********
+
+// Check whether id1, id2 and id3 occur anywhere in product list.
+// iF ID1 == ID2 then two copies of this particle must be present, etc.
+
+bool DecayChannel::contains(int id1, int id2, int id3) const {
+
+ bool found1 = false;
+ bool found2 = false;
+ bool found3 = false;
+ for (int i = 0; i < nProd; ++i) {
+ if (!found1 && prod[i] == id1) {found1 = true; continue;}
+ if (!found2 && prod[i] == id2) {found2 = true; continue;}
+ if (!found3 && prod[i] == id3) {found3 = true; continue;}
+ }
+ return found1 && found2 && found3;
+
+}
+
+//**************************************************************************
+
+// DecayTable class.
+// This class holds info on all decay channels of a particle.
+
+//*********
+
+// Rescale all branching ratios to assure normalization to unity.
+
+void DecayTable::rescaleBR(double newSumBR) {
+
+ // Sum up branching ratios. Find rescaling factor. Rescale.
+ double oldSumBR = 0.;
+ for ( int i = 0; i < size(); ++ i)
+ oldSumBR += channel[i].bRatio();
+ double rescaleFactor = newSumBR / oldSumBR;
+ for ( int i = 0; i < size(); ++ i) channel[i].rescaleBR(rescaleFactor);
+
+}
+
+//**************************************************************************
+
+// ParticleDataEntry class.
+// This class holds info on a single particle species.
+
+//*********
+
+// Definitions of static variables.
+// (Values will be overwritten in initStatic call, so are purely dummy.)
+
+int ParticleDataEntry::modeBreitWigner = 1;
+double ParticleDataEntry::maxEnhanceBW = 2.5;
+double ParticleDataEntry::mQRun[7]
+ = {0., 0.006, 0.003, 0.095, 1.25, 4.20, 165.};
+double ParticleDataEntry::Lambda5Run = 0.2;
+
+// Static copy of Info - not optimal solution??
+Info* ParticleDataEntry::infoPtr = 0;
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// A particle is invisible if it has neither strong nor electric charge,
+// and is not made up of constituents that have it. Only relevant for
+// long-lived particles. This list may need to be extended.
+const int ParticleDataEntry::INVISIBLENUMBER = 29;
+const int ParticleDataEntry::INVISIBLETABLE[29] = { 12, 14, 16, 18, 23, 25,
+ 32, 33, 35, 36, 39, 41, 1000012, 1000014, 1000016, 1000018, 1000022,
+ 1000023, 1000025, 1000035, 1000039, 2000012, 2000014, 2000016, 2000018,
+ 9900012, 9900014, 9900016, 9900023};
+
+// Particles with a read-in tau0 (in mm/c) below this mayDecay by default.
+const double ParticleDataEntry::MAXTAU0FORDECAY = 1000.;
+
+// Particles with a read-in m0 above this isResonance by default.
+const double ParticleDataEntry::MINMASSRESONANCE = 20.;
+
+// Narrow states are assigned nominal mass.
+const double ParticleDataEntry::NARROWMASS = 1e-6;
+
+// Constituent quark masses (d, u, s, c, b).
+const double ParticleDataEntry::CONSTITUENTMASSTABLE[6]
+ = {0., 0.325, 0.325, 0.50, 1.60, 5.00};
+
+//*********
+
+// Destructor: delete any ResonanceWidths object.
+
+ParticleDataEntry::~ParticleDataEntry() {
+ if (resonancePtr != 0) delete resonancePtr;
+}
+
+//*********
+
+// Initialize static data members.
+
+void ParticleDataEntry::initStatic() {
+
+ // Mass generation: fixed mass or linear/quadratic Breit-Wigner.
+ modeBreitWigner = Settings::mode("ParticleData:modeBreitWigner");
+
+ // Maximum tail enhancement when adding threshold factor to Breit-Wigner.
+ maxEnhanceBW = Settings::parm("ParticleData:maxEnhanceBW");
+
+ // Find initial MSbar masses for five light flavours.
+ mQRun[1] = Settings::parm("ParticleData:mdRun");
+ mQRun[2] = Settings::parm("ParticleData:muRun");
+ mQRun[3] = Settings::parm("ParticleData:msRun");
+ mQRun[4] = Settings::parm("ParticleData:mcRun");
+ mQRun[5] = Settings::parm("ParticleData:mbRun");
+ mQRun[6] = Settings::parm("ParticleData:mtRun");
+
+ // Find Lambda5 value to use in running of MSbar masses.
+ double alphaSvalue = Settings::parm("ParticleData:alphaSvalueMRun");
+ AlphaStrong alphaS;
+ alphaS.init( alphaSvalue, 1);
+ Lambda5Run = alphaS.Lambda5();
+
+}
+
+//*********
+
+// Set initial default values for some quantities.
+
+void ParticleDataEntry::setDefaults() {
+
+ // A particle is a resonance if it is heavy enough.
+ isResonanceSave = (m0Save > MINMASSRESONANCE);
+
+ // A particle may decay if it is shortlived enough.
+ mayDecaySave = (tau0Save < MAXTAU0FORDECAY);
+
+ // A particle by default has no external decays.
+ doExternalDecaySave = false;
+
+ // A particle is invisible if in current table of such.
+ isVisibleSave = true;
+ for (int i = 0; i < INVISIBLENUMBER; ++i)
+ if (idSave == INVISIBLETABLE[i]) isVisibleSave = false;
+
+ // Normally a resonance should not have width forced to fixed value.
+ doForceWidthSave = false;
+
+ // Set up constituent masses.
+ setConstituentMass();
+
+ // No Breit-Wigner mass selection before initialized.
+ modeBWnow = 0;
+
+}
+
+//*********
+
+// Prepare the Breit-Wigner mass selection by precalculating
+// frequently-used expressions.
+
+void ParticleDataEntry::initBWmass() {
+
+ // Find Breit-Wigner mode for current particle.
+ modeBWnow = modeBreitWigner;
+ if ( mWidthSave < NARROWMASS || (mMaxSave > mMinSave
+ && mMaxSave - mMinSave < NARROWMASS) ) modeBWnow = 0;
+ if (modeBWnow == 0) return;
+
+ // Find atan expressions to be used in random mass selection.
+ if (modeBWnow < 3) {
+ atanLow = atan( 2. * (mMinSave - m0Save) / mWidthSave );
+ double atanHigh = (mMaxSave > mMinSave)
+ ? atan( 2. * (mMaxSave - m0Save) / mWidthSave ) : 0.5 * M_PI;
+ atanDif = atanHigh - atanLow;
+ } else {
+ atanLow = atan( (pow2(mMinSave) - pow2(m0Save))
+ / (m0Save * mWidthSave) );
+ double atanHigh = (mMaxSave > mMinSave)
+ ? atan( (pow2(mMaxSave) - pow2(m0Save)) / (m0Save * mWidthSave) )
+ : 0.5 * M_PI;
+ atanDif = atanHigh - atanLow;
+ }
+
+ // Done if no threshold factor.
+ if (modeBWnow%2 == 1) return;
+
+ // Find average mass threshold for threshold-factor correction.
+ double bRatSum = 0.;
+ double mThrSum = 0;
+ for (int i = 0; i < decay.size(); ++i)
+ if (decay[i].onMode() >= 0) {
+ bRatSum += decay[i].bRatio();
+ double mChannelSum = 0.;
+ for (int j = 0; j < decay[i].multiplicity(); ++j)
+ mChannelSum += ParticleDataTable::m0( decay[i].product(j) );
+ mThrSum += decay[i].bRatio() * mChannelSum;
+ }
+ mThr = (bRatSum == 0.) ? 0. : mThrSum / bRatSum;
+
+ // Switch off Breit-Wigner if very close to threshold.
+ if (mThr + NARROWMASS > m0Save) {
+ ostringstream osWarn;
+ osWarn << "for id = " << idSave;
+ infoPtr->errorMsg("Warning in ParticleDataEntry::initBWmass:"
+ " switching off width", osWarn.str());
+ modeBWnow = 0;
+ }
+
+}
+
+//*********
+
+// Function to give mass of a particle, either at the nominal value
+// or picked according to a (linear or quadratic) Breit-Wigner.
+
+double ParticleDataEntry::mass() {
+
+ // Nominal value.
+ if (modeBWnow == 0) return m0Save;
+ double mNow, m2Now;
+
+ // Mass according to a Breit-Wigner linear in m.
+ if (modeBWnow == 1) {
+ mNow = m0Save + 0.5 * mWidthSave
+ * tan( atanLow + atanDif * Rndm::flat() );
+
+ // Ditto, but make Gamma proportional to sqrt(m^2 - m_threshold^2).
+ } else if (modeBWnow == 2) {
+ double mWidthNow, fixBW, runBW;
+ double m0ThrS = m0Save*m0Save - mThr*mThr;
+ do {
+ mNow = m0Save + 0.5 * mWidthSave
+ * tan( atanLow + atanDif * Rndm::flat() );
+ mWidthNow = mWidthSave * sqrtpos( (mNow*mNow - mThr*mThr) / m0ThrS );
+ fixBW = mWidthSave / (pow2(mNow - m0Save) + pow2(0.5 * mWidthSave));
+ runBW = mWidthNow / (pow2(mNow - m0Save) + pow2(0.5 * mWidthNow));
+ } while (runBW < Rndm::flat() * maxEnhanceBW * fixBW);
+
+ // Mass according to a Breit-Wigner quadratic in m.
+ } else if (modeBWnow == 3) {
+ m2Now = m0Save*m0Save + m0Save * mWidthSave
+ * tan( atanLow + atanDif * Rndm::flat() );
+ mNow = sqrtpos( m2Now);
+
+ // Ditto, but m_0 Gamma_0 -> m Gamma(m) with threshold factor as above.
+ } else {
+ double mwNow, fixBW, runBW;
+ double m2Ref = m0Save * m0Save;
+ double mwRef = m0Save * mWidthSave;
+ double m2Thr = mThr * mThr;
+ do {
+ m2Now = m2Ref + mwRef * tan( atanLow + atanDif * Rndm::flat() );
+ mNow = sqrtpos( m2Now);
+ mwNow = mNow * mWidthSave
+ * sqrtpos( (m2Now - m2Thr) / (m2Ref - m2Thr) );
+ fixBW = mwRef / (pow2(m2Now - m2Ref) + pow2(mwRef));
+ runBW = mwNow / (pow2(m2Now - m2Ref) + pow2(mwNow));
+ } while (runBW < Rndm::flat() * maxEnhanceBW * fixBW);
+ }
+
+ // Done.
+ return mNow;
+}
+
+//*********
+
+// Function to calculate running mass at given mass scale.
+
+double ParticleDataEntry::mRun(double mHat) {
+
+ // Except for six quarks return nominal mass.
+ if (idSave > 6) return m0Save;
+
+ // For d, u, s quarks start running at 2 GeV (RPP 2006 p. 505).
+ if (idSave < 4) return mQRun[idSave] * pow ( log(2. / Lambda5Run)
+ / log(max(2., mHat) / Lambda5Run), 12./23.);
+
+ // For c, b and t quarks start running at respective mass.
+ return mQRun[idSave] * pow ( log(mQRun[idSave] / Lambda5Run)
+ / log(max(mQRun[idSave], mHat) / Lambda5Run), 12./23.);
+
+}
+
+
+//*********
+
+// Prepare to pick a decay channel.
+
+bool ParticleDataEntry::preparePick(int idSgn, double mHat, int idInFlav) {
+
+ // Reset sum of allowed widths/branching ratios.
+ currentBRSum = 0.;
+
+ // For resonances the widths are calculated dynamically.
+ if (resonancePtr != 0) {
+ resonancePtr->widthStore(idSgn, mHat, idInFlav);
+ for (int i = 0; i < decay.size(); ++i)
+ currentBRSum += decay[i].currentBR();
+
+ // Else use normal fixed branching ratios.
+ } else {
+ int onMode;
+ double currentBRNow;
+ for (int i = 0; i < decay.size(); ++i) {
+ onMode = decay[i].onMode();
+ currentBRNow = 0.;
+ if ( idSgn > 0 && (onMode == 1 || onMode == 2) )
+ currentBRNow = decay[i].bRatio();
+ else if ( idSgn < 0 && (onMode == 1 || onMode == 3) )
+ currentBRNow = decay[i].bRatio();
+ decay[i].currentBR(currentBRNow);
+ currentBRSum += currentBRNow;
+ }
+ }
+
+ // Failure if no channels found with positive branching ratios.
+ return (currentBRSum > 0.);
+
+}
+
+//*********
+
+// Pick a decay channel according to branching ratios from preparePick.
+
+DecayChannel& ParticleDataEntry::pickChannel() {
+
+ // Find channel in table.
+ int size = decay.size();
+ double rndmBR = currentBRSum * Rndm::flat();
+ int i = -1;
+ do rndmBR -= decay[++i].currentBR();
+ while (rndmBR > 0. && i < size);
+
+ // Emergency if no channel found. Done.
+ if (i == size) i = 0;
+ return decay[i];
+
+}
+
+//*********
+
+// Find out if a particle is a hadron.
+// Only covers normal hadrons, not e.g. R-hadrons.
+
+bool ParticleDataEntry::isHadron() const {
+
+ if (idSave <= 100 || (idSave >= 1000000 && idSave <= 9000000)
+ || idSave >= 9900000) return false;
+ if (idSave == 130 || idSave == 310) return true;
+ if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0)
+ return false;
+ return true;
+
+}
+
+//*********
+
+// Find out if a particle is a meson.
+// Only covers normal hadrons, not e.g. R-hadrons.
+
+bool ParticleDataEntry::isMeson() const {
+
+ if (idSave <= 100 || (idSave >= 1000000 && idSave <= 9000000)
+ || idSave >= 9900000) return false;
+ if (idSave == 130 || idSave == 310) return true;
+ if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0
+ || (idSave/1000)%10 != 0) return false;
+ return true;
+
+}
+
+//*********
+
+// Find out if a particle is a baryon.
+// Only covers normal hadrons, not e.g. R-hadrons.
+
+bool ParticleDataEntry::isBaryon() const {
+
+ if (idSave <= 1000 || (idSave >= 1000000 && idSave <= 9000000)
+ || idSave >= 9900000) return false;
+ if (idSave%10 == 0 || (idSave/10)%10 == 0 || (idSave/100)%10 == 0
+ || (idSave/1000)%10 == 0) return false;
+ return true;
+
+
+}
+
+//*********
+
+// Extract the heaviest (= largest id) quark in a hadron.
+
+int ParticleDataEntry::heaviestQuark(int idIn) const {
+
+ if (!isHadron()) return 0;
+ int hQ = 0;
+
+ // Meson.
+ if ( (idSave/1000)%10 == 0 ) {
+ hQ = (idSave/100)%10;
+ if (idSave == 130) hQ = 3;
+ if (hQ%2 == 1) hQ = -hQ;
+
+ // Baryon.
+ } else hQ = (idSave/1000)%10;
+
+ // Done.
+ return (idIn > 0) ? hQ : -hQ;
+
+}
+
+//*********
+
+// Calculate three times baryon number, i.e. net quark - antiquark number.
+
+int ParticleDataEntry::baryonNumberType(int idIn) const {
+
+ // Quarks.
+ if (isQuark()) return (idIn > 0) ? 1 : -1;
+
+ // Diquarks
+ if (isDiquark()) return (idIn > 0) ? 2 : -2;
+
+ // Baryons.
+ if (isBaryon()) return (idIn > 0) ? 3 : -3;
+
+ // Done.
+ return 0;
+
+}
+
+//*********
+
+// Access methods stored in ResonanceWidths. Could have been
+// inline in .h, except for problems with forward declarations.
+
+void ParticleDataEntry::setResonancePtr(
+ ResonanceWidths* resonancePtrIn) {
+ if (resonancePtr == resonancePtrIn) return;
+ if (resonancePtr != 0) delete resonancePtr;
+ resonancePtr = resonancePtrIn;
+}
+
+void ParticleDataEntry::resInit() {
+ if (resonancePtr != 0) resonancePtr->init();
+}
+
+double ParticleDataEntry::resWidth(int idSgn, double mHat, int idIn,
+ bool openOnly, bool setBR) {
+ return (resonancePtr != 0) ? resonancePtr->width( idSgn, mHat,
+ idIn, openOnly, setBR) : 0.;
+}
+
+double ParticleDataEntry::resWidthOpen(int idSgn, double mHat, int idIn) {
+ return (resonancePtr != 0) ? resonancePtr->widthOpen( idSgn, mHat, idIn)
+ : 0.;
+}
+
+double ParticleDataEntry::resWidthStore(int idSgn, double mHat, int idIn) {
+ return (resonancePtr != 0) ? resonancePtr->widthStore( idSgn, mHat, idIn)
+ : 0.;
+}
+
+double ParticleDataEntry::resOpenFrac(int idSgn) {
+ return (resonancePtr != 0) ? resonancePtr->openFrac(idSgn) : 1.;
+}
+
+double ParticleDataEntry::resWidthRescaleFactor() {
+ return (resonancePtr != 0) ? resonancePtr->widthRescaleFactor() : 1.;
+}
+
+double ParticleDataEntry::resWidthChan(double mHat, int idAbs1,
+ int idAbs2) {
+ return (resonancePtr != 0) ? resonancePtr->widthChan( mHat, idAbs1,
+ idAbs2) : 0.;
+}
+
+//*********
+
+// Constituent masses for (d, u, s, c, b) quarks and diquarks.
+// Hardcoded in CONSTITUENTMASSTABLE so that they are not overwritten
+// by mistake, and separated from the "normal" masses.
+// Called both by setDefaults and setM0 so kept as separate method.
+
+void ParticleDataEntry::setConstituentMass() {
+
+ // Equate with the normal masses as default guess.
+ constituentMassSave = m0Save;
+
+ // Quark masses trivial.
+ if (idSave < 6) constituentMassSave = CONSTITUENTMASSTABLE[idSave];
+
+ // Diquarks as simple sum of constituent quarks.
+ if (idSave > 1000 && idSave < 10000 && (idSave/10)%10 == 0) {
+ int id1 = idSave/1000;
+ int id2 = (idSave/100)%10;
+ if (id1 <6 && id2 < 6) constituentMassSave
+ = CONSTITUENTMASSTABLE[id1] + CONSTITUENTMASSTABLE[id2];
+ }
+
+}
+
+//*********
+
+// Convert string to lowercase for case-insensitive comparisons.
+
+string ParticleDataEntry::toLower(const string& name) {
+
+ string temp(name);
+ for (int i = 0; i < int(temp.length()); ++i)
+ temp[i] = std::tolower(temp[i]);
+ return temp;
+
+}
+
+//**************************************************************************
+
+// ParticleDataTable class.
+// This class holds a map of all ParticleDataEntries,
+// each entry containing info on a particle species.
+
+//*********
+
+// Definitions of static variables.
+
+map<int, ParticleDataEntry> ParticleDataTable::pdt;
+bool ParticleDataTable::isInit = false;
+ParticleDataEntry* ParticleDataTable::particlePtr = 0;
+
+// Static copy of Info - not optimal solution??
+Info* ParticleDataTable::infoPtr = 0;
+
+//*********
+
+// Initialize the special handling of resonances in ResonanceWidths.
+// Note:order of initialization is essential to get secondary widths right.
+
+void ParticleDataTable::initResonances(
+ vector<ResonanceWidths*> resonancePtrs, bool reInit) {
+
+ // Initialize static resonance properties.
+ ResonanceWidths::initStatic(infoPtr);
+
+ // Set up new resonance objects. Not necessary if already done.
+ if (!reInit) {
+
+ // Z0, W+- and top are almost always needed.
+ new ResonanceGmZ(23);
+ new ResonanceW(24);
+ new ResonanceTop(6);
+
+ // Higgs in SM.
+ if (!Settings::flag("Higgs:useBSM")) {
+ new ResonanceH(0, 25);
+
+ // Higgses in BSM.
+ } else {
+ new ResonanceH(1, 25);
+ new ResonanceH(2, 35);
+ new ResonanceH(3, 36);
+ new ResonanceHchg(37);
+ }
+
+ // A fourth generation: b', t', tau', nu'_tau.
+ new ResonanceFour(7);
+ new ResonanceFour(8);
+ new ResonanceFour(17);
+ new ResonanceFour(18);
+
+ // New gauge bosons: Z', W', R.
+ new ResonanceZprime(32);
+ new ResonanceWprime(34);
+ new ResonanceRhorizontal(41);
+
+ // A leptoquark.
+ new ResonanceLeptoquark(42);
+
+ // Excited quarks and leptons.
+ for (int i = 1; i < 7; ++i) new ResonanceExcited(4000000 + i);
+ for (int i = 11; i < 17; ++i) new ResonanceExcited(4000000 + i);
+
+ // An excited graviton in extra-dimensional scenarios.
+ new ResonanceGraviton(5000039);
+
+ // A left-right-symmetric scenario with new righthanded neutrinos,
+ // righthanded gauge bosons and doubly charged Higgses.
+ new ResonanceNuRight(9900012);
+ new ResonanceNuRight(9900014);
+ new ResonanceNuRight(9900016);
+ new ResonanceZRight(9900023);
+ new ResonanceWRight(9900024);
+ new ResonanceHchgchgLeft(9900041);
+ new ResonanceHchgchgRight(9900042);
+
+ // Attach user-defined external resonances and initialize them.
+ for (int i = 0; i < int(resonancePtrs.size()); ++i)
+ resonancePtrs[i]->initBasic(resonancePtrs[i]->id());
+ }
+
+ // Set up lists to order resonances in ascending mass.
+ vector<int> idOrdered;
+ vector<double> m0Ordered;
+
+ // Put Z0 and W+- first, since known to be SM and often off-shell.
+ idOrdered.push_back(23);
+ m0Ordered.push_back(m0(23));
+ idOrdered.push_back(24);
+ m0Ordered.push_back(m0(24));
+
+ // Loop through particle table to find resonances.
+ for (map<int, ParticleDataEntry>::iterator pdtEntry = pdt.begin();
+ pdtEntry != pdt.end(); ++pdtEntry) {
+ ParticleDataEntry& pdtNow = pdtEntry->second;
+ int idNow = pdtNow.id();
+
+ // Set up a simple default object for uninitialized resonances.
+ if (pdtNow.isResonance() && pdtNow.getResonancePtr() == 0)
+ new ResonanceGeneric(idNow);
+
+ // Insert resonances in ascending mass, to respect decay hierarchies.
+ if (pdtNow.getResonancePtr() != 0 && idNow != 23 && idNow != 24) {
+ double m0Now = pdtNow.m0();
+ idOrdered.push_back(idNow);
+ m0Ordered.push_back(m0Now);
+ for (int i = int(idOrdered.size()) - 2; i > 1; --i) {
+ if (m0Ordered[i] < m0Now) break;
+ swap( idOrdered[i], idOrdered[i + 1]);
+ swap( m0Ordered[i], m0Ordered[i + 1]);
+ }
+ }
+ }
+
+ // Initialize the resonances in order.
+ for (int i = 0; i < int(idOrdered.size()); ++i)
+ resInit( idOrdered[i] );
+
+}
+
+//*********
+
+// Read in database from specific XML file (which may refer to others).
+
+bool ParticleDataTable::readXML(string inFile, bool reset) {
+
+ // Normally reset whole database before beginning.
+ if (reset) {pdt.clear(); isInit = false;}
+
+ // List of files to be checked.
+ vector<string> files;
+ files.push_back(inFile);
+
+ // Loop over files. Open them for read.
+ for (int i = 0; i < int(files.size()); ++i) {
+ const char* cstring = files[i].c_str();
+ ifstream is(cstring);
+
+ // Check that instream is OK.
+ if (!is) {
+ infoPtr->errorMsg("Error in ParticleDataTable::readXML:"
+ " did not find file", files[i]);
+ return false;
+ }
+
+ // Read in one line at a time.
+ particlePtr = 0;
+ string line;
+ while ( getline(is, line) ) {
+
+ // Get first word of a line.
+ istringstream getfirst(line);
+ string word1;
+ getfirst >> word1;
+
+ // Check for occurence of a particle. Add any continuation lines.
+ if (word1 == "<particle") {
+ while (line.find(">") == string::npos) {
+ string addLine;
+ getline(is, addLine);
+ line += addLine;
+ }
+
+ // Read in particle properties.
+ int id = intAttributeValue( line, "id");
+ string name = attributeValue( line, "name");
+ string antiName = attributeValue( line, "antiName");
+ if (antiName == "") antiName = "void";
+ int spinType = intAttributeValue( line, "spinType");
+ int chargeType = intAttributeValue( line, "chargeType");
+ int colType = intAttributeValue( line, "colType");
+ double m0 = doubleAttributeValue( line, "m0");
+ double mWidth = doubleAttributeValue( line, "mWidth");
+ double mMin = doubleAttributeValue( line, "mMin");
+ double mMax = doubleAttributeValue( line, "mMax");
+ double tau0 = doubleAttributeValue( line, "tau0");
+
+ // Erase if particle already exists.
+ if (isParticle(id)) pdt.erase(id);
+
+ // Store new particle. Save pointer, to be used for decay channels.
+ addParticle( id, name, antiName, spinType, chargeType, colType,
+ m0, mWidth, mMin, mMax, tau0);
+ particlePtr = particleDataPtr(id);
+
+ // Check for occurence of a decay channel. Add any continuation lines.
+ } else if (word1 == "<channel") {
+ while (line.find(">") == string::npos) {
+ string addLine;
+ getline(is, addLine);
+ line += addLine;
+ }
+
+ // Read in channel properties - products so far only as a string.
+ int onMode = intAttributeValue( line, "onMode");
+ double bRatio = doubleAttributeValue( line, "bRatio");
+ int meMode = intAttributeValue( line, "meMode");
+ string products = attributeValue( line, "products");
+
+ // Read in decay products from stream. Must have at least one.
+ istringstream prodStream(products);
+ int prod0 = 0; int prod1 = 0; int prod2 = 0; int prod3 = 0;
+ int prod4 = 0; int prod5 = 0; int prod6 = 0; int prod7 = 0;
+ prodStream >> prod0 >> prod1 >> prod2 >> prod3 >> prod4 >> prod5
+ >> prod6 >> prod7;
+ if (prod0 == 0) {
+ infoPtr->errorMsg("Error in ParticleDataTable::readXML:"
+ " incomplete decay channel", line);
+ return false;
+ }
+
+ // Store new channel (if particle already known).
+ if (particlePtr == 0) {
+ infoPtr->errorMsg("Error in ParticleDataTable::readXML:"
+ " orphan decay channel", line);
+ return false;
+ }
+ particlePtr->decay.addChannel(onMode, bRatio, meMode, prod0, prod1,
+ prod2, prod3, prod4, prod5, prod6, prod7);
+
+ // Check for occurence of a file also to be read.
+ } else if (word1 == "<file") {
+ string file = attributeValue(line, "name");
+ if (file == "") {
+ infoPtr->errorMsg("Warning in ParticleDataTable::readXML:"
+ " skip unrecognized file name", line);
+ } else files.push_back(file);
+ }
+
+ // End of loop over lines in input file and loop over files.
+ };
+ };
+
+ // All particle data at this stage defines baseline original.
+ if (reset) for (map<int, ParticleDataEntry>::iterator pdtEntry
+ = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
+ particlePtr = &pdtEntry->second;
+ particlePtr->setHasChanged(false);
+ }
+
+ // Done.
+ isInit = true;
+ return true;
+
+}
+
+//*********
+
+// Print out complete database in numerical order as an XML file.
+
+void ParticleDataTable::listXML(string outFile) {
+
+ // Convert file name to ofstream.
+ const char* cstring = outFile.c_str();
+ ofstream os(cstring);
+
+ // Iterate through the particle data table.
+ for (map<int, ParticleDataEntry>::iterator pdtEntry
+ = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
+ particlePtr = &pdtEntry->second;
+
+ // Print particle properties.
+ os << "<particle id=\"" << particlePtr->id() << "\""
+ << " name=\"" << particlePtr->name() << "\"";
+ if (particlePtr->hasAnti())
+ os << " antiName=\"" << particlePtr->name(-1) << "\"";
+ os << " spinType=\"" << particlePtr->spinType() << "\""
+ << " chargeType=\"" << particlePtr->chargeType() << "\""
+ << " colType=\"" << particlePtr->colType() << "\"\n";
+ // Pick format for mass and width based on mass value.
+ double m0Now = particlePtr->m0();
+ if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
+ os << fixed << setprecision(5);
+ else os << scientific << setprecision(3);
+ os << " m0=\"" << m0Now << "\"";
+ if (particlePtr->mWidth() > 0.)
+ os << " mWidth=\"" << particlePtr->mWidth() << "\""
+ << " mMin=\"" << particlePtr->mMin() << "\""
+ << " mMax=\"" << particlePtr->mMax() << "\"";
+ if (particlePtr->tau0() > 0.) os << scientific << setprecision(5)
+ << " tau0=\"" << particlePtr->tau0() << "\"";
+ os << ">\n";
+
+ // Loop through the decay channel table for each particle.
+ if (particlePtr->decay.size() > 0) {
+ for (int i = 0; i < int(particlePtr->decay.size()); ++i) {
+ const DecayChannel& channel = particlePtr->decay[i];
+ int mult = channel.multiplicity();
+
+ // Print decay channel properties.
+ os << " <channel onMode=\"" << channel.onMode() << "\""
+ << fixed << setprecision(7)
+ << " bRatio=\"" << channel.bRatio() << "\"";
+ if (channel.meMode() > 0)
+ os << " meMode=\"" << channel.meMode() << "\"";
+ os << " products=\"";
+ for (int j = 0; j < mult; ++j) {
+ os << channel.product(j);
+ if (j < mult - 1) os << " ";
+ }
+
+ // Finish off line and loop over allowed decay channels.
+ os << "\"/>\n";
+ }
+ }
+
+ // Finish off existing particle.
+ os << "</particle>\n\n";
+
+ }
+
+}
+
+//*********
+
+// Read in database from specific free format file.
+
+bool ParticleDataTable::readFF(string inFile, bool reset) {
+
+ // Normally reset whole database before beginning.
+ if (reset) {pdt.clear(); isInit = false;}
+
+ // Open file for read and check that instream is OK.
+ const char* cstring = inFile.c_str();
+ ifstream is(cstring);
+ if (!is) {
+ infoPtr->errorMsg("Error in ParticleDataTable::readFF:"
+ " did not find file", inFile);
+ return false;
+ }
+
+ // Read in one line at a time.
+ particlePtr = 0;
+ string line;
+ bool readParticle = false;
+ while ( getline(is, line) ) {
+
+ // Empty lines begins new particle.
+ if (line.find_first_not_of(" ") == string::npos) {
+ readParticle = true;
+ continue;
+ }
+
+ // Prepare to use standard read from line.
+ istringstream readLine(line);
+
+ // Read in a line with particle information.
+ if (readParticle) {
+
+ // Properties to be read.
+ int id;
+ string name, antiName;
+ int spinType, chargeType, colType;
+ double m0, mWidth, mMin, mMax, tau0;
+ string may;
+
+ // Do the reading.
+ readLine >> id >> name >> antiName >> spinType >> chargeType
+ >> colType >> m0 >> mWidth >> mMin >> mMax >> tau0;
+
+ // Error printout if something went wrong.
+ if (!readLine) {
+ infoPtr->errorMsg("Error in ParticleDataTable::readFF:"
+ " incomplete particle", line);
+ return false;
+ }
+
+ // Erase if particle already exists.
+ if (isParticle(id)) pdt.erase(id);
+
+ // Store new particle. Save pointer, to be used for decay channels.
+ addParticle( id, name, antiName, spinType, chargeType, colType,
+ m0, mWidth, mMin, mMax, tau0);
+ particlePtr = particleDataPtr(id);
+ readParticle = false;
+
+ // Read in a line with decay channel information.
+ } else {
+
+ // Properties to be read.
+ int onMode = 0;
+ double bRatio = 0.;
+ int meMode = 0;
+ int prod0 = 0; int prod1 = 0; int prod2 = 0; int prod3 = 0;
+ int prod4 = 0; int prod5 = 0; int prod6 = 0; int prod7 = 0;
+
+ // Read in data from stream. Need at least one decay product.
+ readLine >> onMode >> bRatio >> meMode >> prod0;
+ if (!readLine) {
+ infoPtr->errorMsg("Error in ParticleDataTable::readFF:"
+ " incomplete decay channel", line);
+ return false;
+ }
+ readLine >> prod1 >> prod2 >> prod3 >> prod4 >> prod5
+ >> prod6 >> prod7;
+
+ // Store new channel.
+ if (particlePtr == 0) {
+ infoPtr->errorMsg("Error in ParticleDataTable::readFF:"
+ " orphan decay channel", line);
+ return false;
+ }
+ particlePtr->decay.addChannel(onMode, bRatio, meMode, prod0, prod1,
+ prod2, prod3, prod4, prod5, prod6, prod7);
+
+ }
+
+ // End of while loop over lines in the file.
+ }
+
+
+ // Done.
+ isInit = true;
+ return true;
+
+}
+
+//*********
+
+// Print out complete database in numerical order as a free format file.
+
+void ParticleDataTable::listFF(string outFile) {
+
+ // Convert file name to ofstream.
+ const char* cstring = outFile.c_str();
+ ofstream os(cstring);
+
+ // Iterate through the particle data table.
+ for (map<int, ParticleDataEntry>::iterator pdtEntry
+ = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
+ particlePtr = &pdtEntry->second;
+
+ // Pick format for mass and width based on mass value.
+ double m0Now = particlePtr->m0();
+ if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
+ os << fixed << setprecision(5);
+ else os << scientific << setprecision(3);
+
+ // Print particle properties.
+ os << "\n" << setw(8) << particlePtr->id() << " "
+ << left << setw(16) << particlePtr->name() << " "
+ << setw(16) << particlePtr->name(-1) << " "
+ << right << setw(2) << particlePtr->spinType() << " "
+ << setw(2) << particlePtr->chargeType() << " "
+ << setw(2) << particlePtr->colType() << " "
+ << setw(10) << particlePtr->m0() << " "
+ << setw(10) << particlePtr->mWidth() << " "
+ << setw(10) << particlePtr->mMin() << " "
+ << setw(10) << particlePtr->mMax() << " "
+ << scientific << setprecision(5)
+ << setw(12) << particlePtr->tau0() << "\n";
+
+ // Loop through the decay channel table for each particle.
+ if (particlePtr->decay.size() > 0) {
+ for (int i = 0; i < int(particlePtr->decay.size()); ++i) {
+ const DecayChannel& channel = particlePtr->decay[i];
+ os << " " << setw(6) << channel.onMode()
+ << " " << fixed << setprecision(7) << setw(10)
+ << channel.bRatio() << " "
+ << setw(3) << channel.meMode() << " ";
+ for (int j = 0; j < channel.multiplicity(); ++j)
+ os << setw(8) << channel.product(j) << " ";
+ os << "\n";
+ }
+ }
+
+ }
+
+}
+
+//*********
+
+// Read in updates from a character string, like a line of a file.
+// Is used by readString (and readFile) in Pythia.
+
+bool ParticleDataTable::readString(string lineIn, bool warn,
+ ostream& os) {
+
+ // If empty line then done.
+ if (lineIn.find_first_not_of(" ") == string::npos) return true;
+
+ // Take copy that will be modified.
+ string line = lineIn;
+
+ // If first character is not a digit then taken to be a comment.
+ int firstChar = line.find_first_not_of(" ");
+ if (!isdigit(line[firstChar])) return true;
+
+ // Replace colons and equal signs by blanks to make parsing simpler.
+ for ( int j = 0; j < int(line.size()); ++ j)
+ if (line[j] == ':' || line[j] == '=') line[j] = ' ';
+
+ // Get particle id and property name.
+ int id;
+ string property;
+ istringstream getWord(line);
+ getWord >> id >> property;
+ property = toLower(property);
+
+ // Check that valid particle.
+ if ( (!isParticle(id) && property != "all" && property != "new")
+ || id <= 0) {
+ if (warn) os << "\n Warning: input particle not found in Particle"
+ << " Data Table; skip:\n " << lineIn << "\n";
+ return false;
+ }
+
+ // Identify particle property and read + set its value, case by case.
+ if (property == "name") {
+ string name;
+ getWord >> name;
+ pdt[id].setName(name);
+ return true;
+ }
+ if (property == "antiname") {
+ string antiName;
+ getWord >> antiName;
+ pdt[id].setAntiName(antiName);
+ return true;
+ }
+ if (property == "names") {
+ string name, antiName;
+ getWord >> name >> antiName;
+ pdt[id].setNames(name, antiName);
+ return true;
+ }
+ if (property == "spintype") {
+ int spinType;
+ getWord >> spinType;
+ pdt[id].setSpinType(spinType);
+ return true;
+ }
+ if (property == "chargetype") {
+ int chargeType;
+ getWord >> chargeType;
+ pdt[id].setChargeType(chargeType);
+ return true;
+ }
+ if (property == "coltype") {
+ int colType;
+ getWord >> colType;
+ pdt[id].setColType(colType);
+ return true;
+ }
+ if (property == "m0") {
+ double m0;
+ getWord >> m0;
+ pdt[id].setM0(m0);
+ return true;
+ }
+ if (property == "mwidth") {
+ double mWidth;
+ getWord >> mWidth;
+ pdt[id].setMWidth(mWidth);
+ return true;
+ }
+ if (property == "mmin") {
+ double mMin;
+ getWord >> mMin;
+ pdt[id].setMMin(mMin);
+ return true;
+ }
+ if (property == "mmax") {
+ double mMax;
+ getWord >> mMax;
+ pdt[id].setMMax(mMax);
+ return true;
+ }
+ if (property == "tau0") {
+ double tau0;
+ getWord >> tau0;
+ pdt[id].setTau0(tau0);
+ return true;
+ }
+ if (property == "isresonance") {
+ string isres;
+ getWord >> isres;
+ bool isResonance = boolString(isres);
+ pdt[id].setIsResonance(isResonance);
+ return true;
+ }
+ if (property == "maydecay") {
+ string may;
+ getWord >> may;
+ bool mayDecay = boolString(may);
+ pdt[id].setMayDecay(mayDecay);
+ return true;
+ }
+ if (property == "doexternaldecay") {
+ string extdec;
+ getWord >> extdec;
+ bool doExternalDecay = boolString(extdec);
+ pdt[id].setDoExternalDecay(doExternalDecay);
+ return true;
+ }
+ if (property == "isvisible") {
+ string isvis;
+ getWord >> isvis;
+ bool isVisible = boolString(isvis);
+ pdt[id].setIsVisible(isVisible);
+ return true;
+ }
+ if (property == "doforcewidth") {
+ string doforce;
+ getWord >> doforce;
+ bool doForceWidth = boolString(doforce);
+ pdt[id].setDoForceWidth(doForceWidth);
+ return true;
+ }
+
+ // Addition or complete replacement of a particle.
+ if (property == "all" || property == "new") {
+
+ // Default values for properties to be read.
+ string name = "void";
+ string antiName = "void";
+ int spinType = 0;
+ int chargeType = 0;
+ int colType = 0;
+ double m0 = 0.;
+ double mWidth = 0.;
+ double mMin = 0.;
+ double mMax = 0.;
+ double tau0 = 0.;
+
+ // Read in data from stream.
+ getWord >> name >> antiName >> spinType >> chargeType >> colType
+ >> m0 >> mWidth >> mMin >> mMax >> tau0;
+
+ // To keep existing decay channels, only overwrite particle data.
+ if (property == "all" && isParticle(id)) {
+ setAll( id, name, antiName, spinType, chargeType, colType,
+ m0, mWidth, mMin, mMax, tau0);
+
+ // Else start over completely from scratch.
+ } else {
+ if (isParticle(id)) pdt.erase(id);
+ addParticle( id, name, antiName, spinType, chargeType, colType,
+ m0, mWidth, mMin, mMax, tau0);
+ }
+ return true;
+ }
+
+ // Set onMode of all decay channels in one go.
+ if (property == "onmode") {
+ int onMode = 0;
+ string onModeIn;
+ getWord >> onModeIn;
+ // For onMode allow the optional possibility of Bool input.
+ if (isdigit(onModeIn[0])) {
+ istringstream getOnMode(onModeIn);
+ getOnMode >> onMode;
+ } else onMode = (boolString(onModeIn)) ? 1 : 0;
+ for (int i = 0; i < pdt[id].decay.size(); ++i)
+ pdt[id].decay[i].onMode(onMode);
+ return true;
+ }
+
+ // Selective search for matching decay channels.
+ int matchKind = 0;
+ if (property == "offifany" || property == "onifany" ||
+ property == "onposifany" || property == "onnegifany") matchKind = 1;
+ if (property == "offifall" || property == "onifall" ||
+ property == "onposifall" || property == "onnegifall") matchKind = 2;
+ if (property == "offifmatch" || property == "onifmatch" ||
+ property == "onposifmatch" || property == "onnegifmatch") matchKind = 3;
+ if (matchKind > 0) {
+ int onMode = 0;
+ if (property == "onifany" || property == "onifall"
+ || property == "onifmatch") onMode = 1;
+ if (property == "onposifany" || property == "onposifall"
+ || property == "onposifmatch") onMode = 2;
+ if (property == "onnegifany" || property == "onnegifall"
+ || property == "onnegifmatch") onMode = 3;
+
+ // Read in particles to match.
+ vector<int> idToMatch;
+ int idRead;
+ for ( ; ; ) {
+ getWord >> idRead;
+ if (!getWord) break;
+ idToMatch.push_back(abs(idRead));
+ }
+ int nToMatch = idToMatch.size();
+
+ // Loop over all decay channels.
+ for (int i = 0; i < pdt[id].decay.size(); ++i) {
+ int multi = pdt[id].decay[i].multiplicity();
+
+ // Look for any match at all.
+ if (matchKind == 1) {
+ bool foundMatch = false;
+ for (int j = 0; j < multi; ++j) {
+ int idNow = abs(pdt[id].decay[i].product(j));
+ for (int k = 0; k < nToMatch; ++k)
+ if (idNow == idToMatch[k]) {foundMatch = true; break;}
+ if (foundMatch) break;
+ }
+ if (foundMatch) pdt[id].decay[i].onMode(onMode);
+
+ // Look for match of all products provided.
+ } else {
+ int nUnmatched = nToMatch;
+ if (multi < nToMatch);
+ else if (multi > nToMatch && matchKind == 3);
+ else {
+ vector<int> idUnmatched;
+ for (int k = 0; k < nToMatch; ++k)
+ idUnmatched.push_back(idToMatch[k]);
+ for (int j = 0; j < multi; ++j) {
+ int idNow = abs(pdt[id].decay[i].product(j));
+ for (int k = 0; k < nUnmatched; ++k)
+ if (idNow == idUnmatched[k]) {
+ idUnmatched[k] = idUnmatched[--nUnmatched];
+ break;
+ }
+ if (nUnmatched == 0) break;
+ }
+ }
+ if (nUnmatched == 0) pdt[id].decay[i].onMode(onMode);
+ }
+ }
+ return true;
+ }
+
+ // Rescale all branching ratios by common factor.
+ if (property == "rescalebr") {
+ double factor;
+ getWord >> factor;
+ pdt[id].rescaleBR(factor);
+ return true;
+ }
+
+ // Reset decay table in preparation for new input.
+ if (property == "onechannel") pdt[id].decay.clear();
+
+ // Add or change a decay channel: get channel number and new property.
+ if (property == "addchannel" || property == "onechannel"
+ || isdigit(property[0])) {
+ int channel;
+ if (property == "addchannel" || property == "onechannel") {
+ pdt[id].decay.addChannel();
+ channel = pdt[id].decay.size() - 1;
+ property = "all";
+ } else{
+ istringstream getChannel(property);
+ getChannel >> channel;
+ getWord >> property;
+ property = toLower(property);
+ }
+
+ // Check that channel exists.
+ if (channel < 0 || channel >= pdt[id].decay.size()) return false;
+
+ // Find decay channel property and value, case by case.
+ // At same time also do case where all should be replaced.
+ if (property == "onmode" || property == "all") {
+ int onMode = 0;
+ string onModeIn;
+ getWord >> onModeIn;
+ // For onMode allow the optional possibility of Bool input.
+ if (isdigit(onModeIn[0])) {
+ istringstream getOnMode(onModeIn);
+ getOnMode >> onMode;
+ } else onMode = (boolString(onModeIn)) ? 1 : 0;
+ pdt[id].decay[channel].onMode(onMode);
+ if (property == "onmode") return true;
+ }
+ if (property == "bratio" || property == "all") {
+ double bRatio;
+ getWord >> bRatio;
+ pdt[id].decay[channel].bRatio(bRatio);
+ if (property == "bratio") return true;
+ }
+ if (property == "memode" || property == "all") {
+ int meMode;
+ getWord >> meMode;
+ pdt[id].decay[channel].meMode(meMode);
+ if (property == "memode") return true;
+ }
+
+ // Scan for products until end of line.
+ if (property == "products" || property == "all") {
+ int nProd = 0;
+ for (int iProd = 0; iProd < 8; ++iProd) {
+ int idProd;
+ getWord >> idProd;
+ if (!getWord) break;
+ pdt[id].decay[channel].product(iProd, idProd);
+ ++nProd;
+ }
+ for (int iProd = nProd; iProd < 8; ++iProd)
+ pdt[id].decay[channel].product(iProd, 0);
+ pdt[id].decay[channel].multiplicity(nProd);
+ return true;
+ }
+
+ // Rescale an existing branching ratio.
+ if (property == "rescalebr") {
+ double factor;
+ getWord >> factor;
+ pdt[id].decay[channel].rescaleBR(factor);
+ return true;
+ }
+ }
+
+ // Return false if failed to recognize property.
+ if (warn) os << "\n Warning: input property not found in Particle"
+ << " Data Table; skip:\n " << lineIn << "\n";
+ return false;
+
+}
+
+//*********
+
+// Print out complete or changed table of database in numerical order.
+
+void ParticleDataTable::list(bool changedOnly, bool changedRes, ostream& os) {
+
+ // Table header; output for bool as off/on.
+ if (!changedOnly) {
+ os << "\n -------- PYTHIA Particle Data Table (complete) --------"
+ << "------------------------------------------------------------"
+ << "--------------\n \n";
+
+ } else {
+ os << "\n -------- PYTHIA Particle Data Table (changed only) ----"
+ << "------------------------------------------------------------"
+ << "--------------\n \n";
+ }
+ os << " id name antiName spn chg col m0"
+ << " mWidth mMin mMax tau0 res dec ext "
+ << "vis wid\n no onMode bRatio meMode products \n";
+
+ // Iterate through the particle data table. Option to skip unchanged.
+ int nList = 0;
+ for (map<int, ParticleDataEntry>::iterator pdtEntry
+ = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
+ particlePtr = &pdtEntry->second;
+ if ( !changedOnly || particlePtr->hasChanged() ||
+ ( changedRes && particlePtr->getResonancePtr() != 0 ) ) {
+
+ // Pick format for mass and width based on mass value.
+ double m0Now = particlePtr->m0();
+ if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
+ os << fixed << setprecision(5);
+ else os << scientific << setprecision(3);
+
+ // Print particle properties.
+ ++nList;
+ string antiName = particlePtr->name(-1);
+ if (antiName == "void") antiName = " ";
+ os << "\n" << setw(8) << particlePtr->id() << " "
+ << left << setw(16) << particlePtr->name() << " "
+ << setw(16) << antiName << " "
+ << right << setw(2) << particlePtr->spinType() << " "
+ << setw(2) << particlePtr->chargeType() << " "
+ << setw(2) << particlePtr->colType() << " "
+ << setw(10) << particlePtr->m0() << " "
+ << setw(10) << particlePtr->mWidth() << " "
+ << setw(10) << particlePtr->mMin() << " "
+ << setw(10) << particlePtr->mMax() << " "
+ << scientific << setprecision(5)
+ << setw(12) << particlePtr->tau0() << " " << setw(2)
+ << particlePtr->isResonance() << " " << setw(2)
+ << (particlePtr->mayDecay() && particlePtr->canDecay())
+ << " " << setw(2) << particlePtr->doExternalDecay() << " "
+ << setw(2) << particlePtr->isVisible()<< " "
+ << setw(2) << particlePtr->doForceWidth() << "\n";
+
+ // Loop through the decay channel table for each particle.
+ if (particlePtr->decay.size() > 0) {
+ for (int i = 0; i < int(particlePtr->decay.size()); ++i) {
+ const DecayChannel& channel = particlePtr->decay[i];
+ os << " " << setprecision(7)
+ << setw(5) << i
+ << setw(6) << channel.onMode()
+ << fixed<< setw(12) << channel.bRatio()
+ << setw(5) << channel.meMode() << " ";
+ for (int j = 0; j < channel.multiplicity(); ++j)
+ os << setw(8) << channel.product(j) << " ";
+ os << "\n";
+ }
+ }
+ }
+
+ }
+
+ // End of loop over database contents.
+ if (changedOnly && nList == 0) os << "\n no particle data has been "
+ << "changed from its default value \n";
+ os << "\n -------- End PYTHIA Particle Data Table -----------------"
+ << "--------------------------------------------------------------"
+ << "----------\n" << endl;
+
+}
+
+//*********
+
+// Print out partial table of database in input order.
+
+void ParticleDataTable::list(vector<int> idList, ostream& os) {
+
+ // Table header; output for bool as off/on.
+ os << "\n -------- PYTHIA Particle Data Table (partial) ---------"
+ << "------------------------------------------------------------"
+ << "--------------\n \n";
+ os << " id name antiName spn chg col m0"
+ << " mWidth mMin mMax tau0 res dec ext "
+ << "vis wid\n no onMode bRatio meMode products \n";
+
+ // Iterate through the given list of input particles.
+ for (int i = 0; i < int(idList.size()); ++i) {
+ particlePtr = particleDataPtr(idList[i]);
+
+ // Pick format for mass and width based on mass value.
+ double m0Now = particlePtr->m0();
+ if (m0Now == 0 || (m0Now > 0.1 && m0Now < 1000.))
+ os << fixed << setprecision(5);
+ else os << scientific << setprecision(3);
+
+ // Print particle properties.
+ string antiName = particlePtr->name(-1);
+ if (antiName == "void") antiName = " ";
+ os << "\n" << setw(8) << particlePtr->id() << " "
+ << left << setw(16) << particlePtr->name() << " "
+ << setw(16) << antiName << " "
+ << right << setw(2) << particlePtr->spinType() << " "
+ << setw(2) << particlePtr->chargeType() << " "
+ << setw(2) << particlePtr->colType() << " "
+ << setw(10) << particlePtr->m0() << " "
+ << setw(10) << particlePtr->mWidth() << " "
+ << setw(10) << particlePtr->mMin() << " "
+ << setw(10) << particlePtr->mMax() << " "
+ << scientific << setprecision(5)
+ << setw(12) << particlePtr->tau0() << " " << setw(2)
+ << particlePtr->isResonance() << " " << setw(2)
+ << (particlePtr->mayDecay() && particlePtr->canDecay())
+ << " " << setw(2) << particlePtr->doExternalDecay() << " "
+ << setw(2) << particlePtr->isVisible() << " "
+ << setw(2) << particlePtr->doForceWidth() << "\n";
+
+ // Loop through the decay channel table for each particle.
+ if (particlePtr->decay.size() > 0) {
+ for (int j = 0; j < int(particlePtr->decay.size()); ++j) {
+ const DecayChannel& channel = particlePtr->decay[j];
+ os << " " << setprecision(7)
+ << setw(5) << j
+ << setw(6) << channel.onMode()
+ << fixed<< setw(12) << channel.bRatio()
+ << setw(5) << channel.meMode() << " ";
+ for (int k = 0; k < channel.multiplicity(); ++k)
+ os << setw(8) << channel.product(k) << " ";
+ os << "\n";
+ }
+ }
+
+ }
+
+ // End of loop over database contents.
+ os << "\n -------- End PYTHIA Particle Data Table -----------------"
+ << "--------------------------------------------------------------"
+ << "----------\n" << endl;
+
+}
+
+//*********
+
+// Check that table makes sense: e.g. consistent names and mass ranges,
+// that branching ratios sum to unity, that charge is conserved and
+// that phase space is open in each channel.
+// verbosity = 0: mimimal amount of checks, e.g. that no channels open.
+// = 1: further warning if individual channels closed
+// (except for resonances).
+// = 2: also print branching-ratio-averaged threshold mass.
+// = 11, 12: as 1, 2, but include resonances in detailed checks.
+
+void ParticleDataTable::checkTable(int verbosity, ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA Check of Particle Data Table ------------"
+ <<"------\n\n";
+ int nErr = 0;
+
+ // Loop through all particles.
+ for (map<int, ParticleDataEntry>::iterator pdtEntry
+ = pdt.begin(); pdtEntry != pdt.end(); ++pdtEntry) {
+ particlePtr = &pdtEntry->second;
+
+ // Extract some particle properties. Set some flags;
+ int id = particlePtr->id();
+ bool hasAnti = particlePtr->hasAnti();
+ int spinTypeNow = particlePtr->spinType();
+ int chargeTypeNow = particlePtr->chargeType();
+ int baryonTypeNow = particlePtr->baryonNumberType();
+ double m0Now = particlePtr->m0();
+ double mMinNow = particlePtr->mMin();
+ double mMaxNow = particlePtr->mMax();
+ double mWidthNow = particlePtr->mWidth();
+ double tau0Now = particlePtr->tau0();
+ bool isResonanceNow = particlePtr->isResonance();
+ bool hasPrinted = false;
+ bool studyCloser = verbosity > 10 || !isResonanceNow;
+
+ // Check that particle name consistent with charge information.
+ string particleName = particlePtr->name(1);
+ if (particleName.size() > 16) {
+ os << " Warning: particle " << id << " has name " << particleName
+ << " of length " << particleName.size() << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+ int nPlus = 0;
+ int nMinus = 0;
+ for (int i = 0; i < int(particleName.size()); ++i) {
+ if (particleName[i] == '+') ++nPlus;
+ if (particleName[i] == '-') ++nMinus;
+ }
+ if ( (nPlus > 0 && nMinus > 0) || ( nPlus + nMinus > 0
+ && 3 * (nPlus - nMinus) != chargeTypeNow )) {
+ os << " Warning: particle " << id << " has name " << particleName
+ << " inconsistent with charge type " << chargeTypeNow << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+
+ // Check that antiparticle name consistent with charge information.
+ if (hasAnti) {
+ particleName = particlePtr->name(-1);
+ if (particleName.size() > 16) {
+ os << " Warning: particle " << id << " has name " << particleName
+ << " of length " << particleName.size() << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+ nPlus = 0;
+ nMinus = 0;
+ for (int i = 0; i < int(particleName.size()); ++i) {
+ if (particleName[i] == '+') ++nPlus;
+ if (particleName[i] == '-') ++nMinus;
+ }
+ if ( (nPlus > 0 && nMinus > 0) || ( nPlus + nMinus > 0
+ && 3 * (nPlus - nMinus) != -chargeTypeNow )) {
+ os << " Warning: particle " << -id << " has name "
+ << particleName << " inconsistent with charge type "
+ << -chargeTypeNow << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+ }
+
+ // Check that mass, mass range and width are consistent.
+ if (particlePtr->useBreitWigner()) {
+ if (mMinNow > m0Now) {
+ os << " Error: particle " << id << " has mMin "
+ << fixed << setprecision(5) << mMinNow
+ << " larger than m0 " << m0Now << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+ if (mMaxNow > mMinNow && mMaxNow < m0Now) {
+ os << " Error: particle " << id << " has mMax "
+ << fixed << setprecision(5) << mMaxNow
+ << " smaller than m0 " << m0Now << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+ if (mMaxNow > mMinNow && mMaxNow - mMinNow < mWidthNow) {
+ os << " Warning: particle " << id << " has mMax - mMin "
+ << fixed << setprecision(5) << mMaxNow - mMinNow
+ << " smaller than mWidth " << mWidthNow << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+ }
+
+ // Check that particle does not both have width and lifetime.
+ if (mWidthNow > 0. && tau0Now > 0.) {
+ os << " Warning: particle " << id << " has both nonvanishing width "
+ << scientific << setprecision(5) << mWidthNow << " and lifetime "
+ << tau0Now << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+
+ // Begin study decay channels.
+ if (particlePtr->decay.size() > 0) {
+
+ // Loop through all decay channels.
+ double bRatioSum = 0.;
+ double bRatioPos = 0.;
+ double bRatioNeg = 0.;
+ bool hasPosBR = false;
+ bool hasNegBR = false;
+ double threshMass = 0.;
+ bool openChannel = false;
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+
+ // Extract channel properties.
+ int onMode = particlePtr->decay[i].onMode();
+ double bRatio = particlePtr->decay[i].bRatio();
+ int meMode = particlePtr->decay[i].meMode();
+ int mult = particlePtr->decay[i].multiplicity();
+ int prod[8];
+ for (int j = 0; j < 8; ++j)
+ prod[j] = particlePtr->decay[i].product(j);
+
+ // Sum branching ratios. Include off-channels.
+ if (onMode == 0 || onMode == 1) bRatioSum += bRatio;
+ else if (onMode == 2) {bRatioPos += bRatio; hasPosBR = true;}
+ else if (onMode == 3) {bRatioNeg += bRatio; hasNegBR = true;}
+
+ // Error printout when unknown decay product code.
+ for (int j = 0; j < 8; ++j) {
+ if ( prod[j] != 0 && !isParticle(prod[j]) ) {
+ os << " Error: unknown decay product for " << id
+ << " -> " << prod[j] << "\n";
+ hasPrinted = true;
+ ++nErr;
+ continue;
+ }
+ }
+
+ // Error printout when no decay products or 0 interspersed.
+ int nLast = 0;
+ for (int j = 0; j < 8; ++j)
+ if (prod[j] != 0) nLast = j + 1;
+ if (mult == 0 || mult != nLast) {
+ os << " Error: corrupted decay product list for "
+ << particlePtr->id() << " -> ";
+ for (int j = 0; j < 8; ++j) os << prod[j] << " ";
+ os << "\n";
+ hasPrinted = true;
+ ++nErr;
+ continue;
+ }
+
+ // Check charge conservation and open phase space in decay channel.
+ int chargeTypeSum = -chargeTypeNow;
+ int baryonTypeSum = -baryonTypeNow;
+ double avgFinalMass = 0.;
+ double minFinalMass = 0.;
+ bool canHandle = true;
+ for (int j = 0; j < mult; ++j) {
+ chargeTypeSum += chargeType( prod[j] );
+ baryonTypeSum += baryonNumberType( prod[j] );
+ avgFinalMass += m0( prod[j] );
+ minFinalMass += m0Min( prod[j] );
+ if (prod[j] == 81 || prod[j] == 82 || prod[j] == 83)
+ canHandle = false;
+ }
+ threshMass += bRatio * avgFinalMass;
+
+ // Error printout when charge or baryon number not conserved.
+ if (chargeTypeSum != 0 && canHandle) {
+ os << " Error: 3*charge changed by " << chargeTypeSum
+ << " in " << id << " -> ";
+ for (int j = 0; j < mult; ++j) os << prod[j] << " ";
+ os << "\n";
+ hasPrinted = true;
+ ++nErr;
+ continue;
+ }
+ if ( baryonTypeSum != 0 && canHandle && particlePtr->isHadron() ) {
+ os << " Error: 3*baryon number changed by " << baryonTypeSum
+ << " in " << id << " -> ";
+ for (int j = 0; j < mult; ++j) os << prod[j] << " ";
+ os << "\n";
+ hasPrinted = true;
+ ++nErr;
+ continue;
+ }
+
+ // Begin check that some matrix elements are used correctly.
+ bool correctME = true;
+
+ // Check matrix element mode 0: recommended not into partons.
+ if (meMode == 0 && !isResonanceNow) {
+ bool hasPartons = false;
+ for (int j = 0; j < mult; ++j) {
+ int idAbs = abs(prod[j]);
+ if ( idAbs < 10 || idAbs == 21 || idAbs == 81 || idAbs == 82
+ || idAbs == 83 || (idAbs > 1000 && idAbs < 10000
+ && (idAbs/10)%10 == 0) ) hasPartons = true;
+ }
+ if (hasPartons) correctME = false;
+ }
+
+ // Check matrix element mode 1: rho/omega -> pi+ pi- pi0.
+ bool useME1 = ( mult == 3 && spinTypeNow == 3 && id > 100
+ && id < 1000 && particlePtr->decay[i].contains(211, -211, 111) );
+ if ( meMode == 1 && !useME1 ) correctME = false;
+ if ( meMode != 1 && useME1 ) correctME = false;
+
+ // Check matrix element mode 2: polarization in V -> PS + PS.
+ bool useME2 = ( mult == 2 && spinTypeNow == 3 && id > 100
+ && id < 1000 && spinType(prod[0]) == 1
+ && spinType(prod[1]) == 1 );
+ if ( meMode == 2 && !useME2 ) correctME = false;
+ if ( meMode != 2 && useME2 ) correctME = false;
+
+ // Check matrix element mode 11, 12 and 13: Dalitz decay with
+ // one or more particles in addition to the lepton pair,
+ // or double Dalitz decay.
+ bool useME11 = ( mult == 3 && !isResonanceNow
+ && (prod[1] == 11 || prod[1] == 13 || prod[1] == 15)
+ && prod[2] == -prod[1] );
+ bool useME12 = ( mult > 3 && !isResonanceNow
+ && (prod[mult - 2] == 11 || prod[mult - 2] == 13
+ || prod[mult - 2] == 15) && prod[mult - 1] == -prod[mult - 2] );
+ bool useME13 = ( mult == 4 && !isResonanceNow
+ && (prod[0] == 11 || prod[0] == 13) && prod[1] == -prod[0]
+ && (prod[2] == 11 || prod[2] == 13) && prod[3] == -prod[2] );
+ if (useME13) useME12 = false;
+ if ( meMode == 11 && !useME11 ) correctME = false;
+ if ( meMode != 11 && useME11 ) correctME = false;
+ if ( meMode == 12 && !useME12 ) correctME = false;
+ if ( meMode != 12 && useME12 ) correctME = false;
+ if ( meMode == 13 && !useME13 ) correctME = false;
+ if ( meMode != 13 && useME13 ) correctME = false;
+
+ // Check matrix element mode 21: tau -> nu_tau hadrons.
+ bool useME21 = (id == 15 && mult > 2 && prod[0] == 16
+ && abs(prod[1]) > 100);
+ if ( meMode == 21 && !useME21 ) correctME = false;
+ if ( meMode != 21 && useME21 ) correctME = false;
+
+ // Check matrix element mode 22, but only for semileptonic decay.
+ // For a -> b c d require types u = 2, ubar = -2, d = 1, dbar = -1.
+ if ( isLepton(prod[0]) && isLepton(prod[1]) ) {
+ bool useME22 = false;
+ int typeA = 0;
+ int typeB = 0;
+ int typeC = 0;
+ if (particlePtr->isLepton()) {
+ typeA = (id > 0) ? 1 + (id-1)%2 : -1 - (1-id)%2;
+ } else if (particlePtr->isHadron()) {
+ int hQ = particlePtr->heaviestQuark();
+ // Special case: for B_c either bbar or c decays.
+ if (id == 541 && heaviestQuark(prod[2]) == -5) hQ = 4;
+ typeA = (hQ > 0) ? 1 + (hQ-1)%2 : -1 - (1-hQ)%2;
+ }
+ typeB = (prod[0] > 0) ? 1 + (prod[0]-1)%2 : -1 - (1-prod[0])%2;
+ typeC = (prod[1] > 0) ? 1 + (prod[1]-1)%2 : -1 - (1-prod[1])%2;
+ // Special cases.
+ if ( (id == 130 || id == 310) && typeC * typeA < 0) typeA = -typeA;
+ if (mult == 3 && id == 2112 && prod[2] == 2212) typeA = 3 - typeA;
+ if (mult == 3 && id == 3222 && prod[2] == 3122) typeA = 3 - typeA;
+ if (mult > 2 && typeC == typeA && typeB * typeC < 0
+ && (typeB + typeC)%2 != 0) useME22 = true;
+ if ( meMode == 22 && !useME22 ) correctME = false;
+ if ( meMode != 22 && useME22 ) correctME = false;
+ }
+
+ // Check for matrix element mode 31.
+ if (meMode == 31) {
+ int nGamma = 0;
+ for (int j = 0; j < mult; ++j) if (prod[j] == 22) ++nGamma;
+ if (nGamma != 1) correctME = false;
+ }
+
+ // Check for unknown mode, or resonance-only mode.
+ if ( !isResonanceNow && (meMode < 0 || (meMode > 2 && meMode <= 10)
+ || (meMode > 13 && meMode <= 20) || (meMode > 23 && meMode <= 30)
+ || (meMode > 31 && meMode <= 41) || meMode == 51 || meMode == 61
+ || meMode == 71 || (meMode > 80 && meMode <= 90)
+ || (!particlePtr->isOctetHadron() && meMode > 92) ) )
+ correctME = false;
+
+ // Print if incorrect matrix element mode.
+ if ( !correctME ) {
+ os << " Warning: meMode " << meMode << " used for "
+ << id << " -> ";
+ for (int j = 0; j < mult; ++j) os << prod[j] << " ";
+ os << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+
+ // Warning printout when no phase space for decay.
+ if ( studyCloser && verbosity > 0 && canHandle && onMode > 0
+ && particlePtr->m0Min() - minFinalMass < 0. ) {
+ if (particlePtr->m0Max() - minFinalMass < 0.)
+ os << " Error: decay never possible for ";
+ else os << " Warning: decay sometimes not possible for ";
+ os << id << " -> ";
+ for (int j = 0; j < mult; ++j) os << prod[j] << " ";
+ os << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+
+ // End loop over decay channels.
+ if (onMode > 0 && bRatio > 0.) openChannel = true;
+ }
+
+ // Optional printout of threshold.
+ if (verbosity%10 > 1 && particlePtr->useBreitWigner()) {
+ threshMass /= bRatioSum;
+ os << " Info: particle " << id << fixed << setprecision(5)
+ << " has average mass threshold " << threshMass
+ << " while mMin is " << mMinNow << "\n";
+ hasPrinted = true;
+ }
+
+ // Error printout when no acceptable decay channels found.
+ if (studyCloser && !openChannel) {
+ os << " Error: no acceptable decay channel found for particle "
+ << id << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+
+ // Warning printout when branching ratios do not sum to unity.
+ if (studyCloser && (!hasAnti || (!hasPosBR && !hasNegBR))
+ && abs(bRatioSum + bRatioPos - 1.) > 1e-8) {
+ os << " Warning: particle " << id << fixed << setprecision(8)
+ << " has branching ratio sum " << bRatioSum << "\n";
+ hasPrinted = true;
+ ++nErr;
+ } else if (studyCloser && hasAnti
+ && (abs(bRatioSum + bRatioPos - 1.) > 1e-8
+ || abs(bRatioSum + bRatioNeg - 1.) > 1e-8)) {
+ os << " Warning: particle " << id << fixed << setprecision(8)
+ << " has branching ratio sum " << bRatioSum + bRatioPos
+ << " while its antiparticle has " << bRatioSum + bRatioNeg
+ << "\n";
+ hasPrinted = true;
+ ++nErr;
+ }
+
+ // End study of decay channels and loop over particles.
+ }
+ if (hasPrinted) os << "\n";
+ }
+
+ // Final output. Done.
+ os << " Total number of errors and warnings is " << nErr << "\n";
+ os << "\n -------- End PYTHIA Check of Particle Data Table --------"
+ << "------\n" << endl;
+
+}
+
+//*********
+
+// Return the id of the sequentially next particle stored in table.
+
+int ParticleDataTable::nextId(int idIn) {
+
+ // Return 0 for negative or unknown codes. Return first for 0.
+ if (idIn < 0 || (idIn > 0 && !isParticle(idIn))) return 0;
+ if (idIn == 0) return pdt.begin()->first;
+
+ // Find pointer to current particle and step up. Return 0 if impossible.
+ map<int, ParticleDataEntry>::const_iterator pdtIn = pdt.find(idIn);
+ if (pdtIn == pdt.end()) return 0;
+ return (++pdtIn)->first;
+
+}
+
+//*********
+
+// Fractional width associated with open channels of one or two resonances.
+
+double ParticleDataTable::resOpenFrac(int id1In, int id2In, int id3In) {
+
+ // Default value.
+ double answer = 1.;
+
+ // First resonance.
+ if (isParticle(id1In)) answer = pdt[abs(id1In)].resOpenFrac(id1In);
+
+ // Possibly second resonance.
+ if (isParticle(id2In)) answer *= pdt[abs(id2In)].resOpenFrac(id2In);
+
+ // Possibly third resonance.
+ if (isParticle(id3In)) answer *= pdt[abs(id2In)].resOpenFrac(id3In);
+
+ // Done.
+ return answer;
+
+}
+
+//*********
+
+// Convert string to lowercase for case-insensitive comparisons.
+
+string ParticleDataTable::toLower(const string& name) {
+
+ string temp(name);
+ for (int i = 0; i < int(temp.length()); ++i)
+ temp[i] = std::tolower(temp[i]);
+ return temp;
+
+}
+
+//*********
+
+// Allow several alternative inputs for true/false.
+
+bool ParticleDataTable::boolString(string tag) {
+
+ string tagLow = toLower(tag);
+ return ( tagLow == "true" || tagLow == "1" || tagLow == "on"
+ || tagLow == "yes" || tagLow == "ok" );
+
+}
+
+//*********
+
+// Extract XML value string following XML attribute.
+
+string ParticleDataTable::attributeValue(string line, string attribute) {
+
+ if (line.find(attribute) == string::npos) return "";
+ int iBegAttri = line.find(attribute);
+ int iBegQuote = line.find("\"", iBegAttri + 1);
+ int iEndQuote = line.find("\"", iBegQuote + 1);
+ return line.substr(iBegQuote + 1, iEndQuote - iBegQuote - 1);
+
+}
+
+//*********
+
+// Extract XML bool value following XML attribute.
+
+bool ParticleDataTable::boolAttributeValue(string line, string attribute) {
+
+ string valString = attributeValue(line, attribute);
+ if (valString == "") return false;
+ return boolString(valString);
+
+}
+
+//*********
+
+// Extract XML int value following XML attribute.
+
+int ParticleDataTable::intAttributeValue(string line, string attribute) {
+ string valString = attributeValue(line, attribute);
+ if (valString == "") return 0;
+ istringstream valStream(valString);
+ int intVal;
+ valStream >> intVal;
+ return intVal;
+
+}
+
+//*********
+
+// Extract XML double value following XML attribute.
+
+double ParticleDataTable::doubleAttributeValue(string line, string attribute) {
+ string valString = attributeValue(line, attribute);
+ if (valString == "") return 0.;
+ istringstream valStream(valString);
+ double doubleVal;
+ valStream >> doubleVal;
+ return doubleVal;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// ParticleDecays.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// ParticleDecays class.
+
+#include "ParticleDecays.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ParticleDecays class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of times one tries to let decay happen (for 2 nested loops).
+const int ParticleDecays::NTRYDECAY = 10;
+
+// Number of times one tries to pick valid hadronic content in decay.
+const int ParticleDecays::NTRYPICK = 100;
+
+// Minimal Dalitz pair mass this factor above threshold.
+const double ParticleDecays::MSAFEDALITZ = 1.000001;
+
+// These numbers are hardwired empirical parameters,
+// intended to speed up the M-generator.
+const double ParticleDecays::WTCORRECTION[11] = { 1., 1., 1.,
+ 2., 5., 15., 60., 250., 1250., 7000., 50000. };
+
+//*********
+
+// Initialize and save pointers.
+
+void ParticleDecays::init(Info* infoPtrIn, TimeShower* timesDecPtrIn,
+ StringFlav* flavSelPtrIn, DecayHandler* decayHandlePtrIn,
+ vector<int> handledParticles) {
+
+ // Save pointers to error messages handling and flavour generation.
+ infoPtr = infoPtrIn;
+ flavSelPtr = flavSelPtrIn;
+
+ // Save pointer to timelike shower, as needed in some few decays.
+ timesDecPtr = timesDecPtrIn;
+
+ // Save pointer for external handling of some decays.
+ decayHandlePtr = decayHandlePtrIn;
+
+ // Set which particles should be handled externally.
+ if (decayHandlePtr != 0)
+ for (int i = 0; i < int(handledParticles.size()); ++i)
+ ParticleDataTable::doExternalDecay(handledParticles[i], true);
+
+ // Safety margin in mass to avoid troubles.
+ mSafety = Settings::parm("ParticleDecays:mSafety");
+
+ // Lifetime and vertex rules for determining whether decay allowed.
+ limitTau0 = Settings::flag("ParticleDecays:limitTau0");
+ tau0Max = Settings::parm("ParticleDecays:tau0Max");
+ limitTau = Settings::flag("ParticleDecays:limitTau");
+ tauMax = Settings::parm("ParticleDecays:tauMax");
+ limitRadius = Settings::flag("ParticleDecays:limitRadius");
+ rMax = Settings::parm("ParticleDecays:rMax");
+ limitCylinder = Settings::flag("ParticleDecays:limitCylinder");
+ xyMax = Settings::parm("ParticleDecays:xyMax");
+ zMax = Settings::parm("ParticleDecays:zMax");
+ limitDecay = limitTau0 || limitTau || limitRadius || limitCylinder;
+
+ // B-Bbar mixing parameters.
+ mixB = Settings::flag("ParticleDecays:mixB");
+ xBdMix = Settings::parm("ParticleDecays:xBdMix");
+ xBsMix = Settings::parm("ParticleDecays:xBsMix");
+
+ // Suppression of extra-hadron momenta in semileptonic decays.
+ sigmaSoft = Settings::parm("ParticleDecays:sigmaSoft");
+
+ // Selection of multiplicity and colours in "phase space" model.
+ multIncrease = Settings::parm("ParticleDecays:multIncrease");
+ multRefMass = Settings::parm("ParticleDecays:multRefMass");
+ multGoffset = Settings::parm("ParticleDecays:multGoffset");
+ colRearrange = Settings::parm("ParticleDecays:colRearrange");
+
+ // Minimum energy in system (+ m_q) from StringFragmentation.
+ stopMass = Settings::parm("StringFragmentation:stopMass");
+
+ // Parameters for Dalitz decay virtual gamma mass spectrum.
+ sRhoDal = pow2(ParticleDataTable::m0(113));
+ wRhoDal = pow2(ParticleDataTable::mWidth(113));
+
+ // Allow showers in decays to qqbar/gg/ggg/gammagg.
+ doFSRinDecays = Settings::flag("ParticleDecays:FSRinDecays");
+
+}
+
+//*********
+
+// Decay a particle; main method.
+
+bool ParticleDecays::decay( int iDec, Event& event) {
+
+ // Check whether a decay is allowed, given the upcoming decay vertex.
+ Particle& decayer = event[iDec];
+ if (limitDecay && !checkVertex(decayer)) return true;
+
+ // Fill the decaying particle in slot 0 of arrays.
+ idDec = decayer.id();
+ iProd.resize(0);
+ idProd.resize(0);
+ mProd.resize(0);
+ iProd.push_back( iDec );
+ idProd.push_back( idDec );
+ mProd.push_back( decayer.m() );
+ bool foundChannel = false;
+
+ // Check for oscillations B0 <-> B0bar or B_s0 <-> B_s0bar.
+ bool hasOscillated = (abs(idDec) == 511 || abs(idDec) == 531)
+ ? oscillateB(decayer) : false;
+ if (hasOscillated) {idDec = - idDec; idProd[0] = idDec;}
+
+ // Particle data for decaying particle.
+ decDataPtr = &decayer.particleData();
+
+ // Optionally send on to external decay program.
+ bool doneExternally = false;
+ if (decDataPtr->doExternalDecay()) {
+ pProd.resize(0);
+ pProd.push_back(decayer.p());
+ doneExternally = decayHandlePtr->decay(idProd, mProd, pProd,
+ iDec, event);
+
+ // If it worked, then store the decay products in the event record.
+ if (doneExternally) {
+ mult = idProd.size() - 1;
+ int status = (hasOscillated) ? 94 : 93;
+ for (int i = 1; i <= mult; ++i) {
+ int iPos = event.append( idProd[i], status, iDec, 0, 0, 0,
+ 0, 0, pProd[i], mProd[i]);
+ iProd.push_back( iPos);
+ }
+
+ // Also mark mother decayed and store daughters.
+ event[iDec].statusNeg();
+ event[iDec].daughters( iProd[1], iProd[mult]);
+ }
+ }
+
+ // Now begin normal internal decay treatment.
+ if (!doneExternally) {
+
+ // Pick a decay channel; allow up to ten tries.
+ if (!decDataPtr->preparePick(idDec)) return false;
+ for (int iTryChannel = 0; iTryChannel < NTRYDECAY; ++iTryChannel) {
+ DecayChannel& channel = decDataPtr->pickChannel();
+ meMode = channel.meMode();
+ keepPartons = (meMode > 90 && meMode <= 100);
+ mult = channel.multiplicity();
+
+ // Allow up to ten tries for each channel (e.g with different masses).
+ for (int iTryMode = 0; iTryMode < NTRYDECAY; ++iTryMode) {
+ idProd.resize(1);
+ mProd.resize(1);
+
+ // Extract and store the decay products.
+ hasPartons = false;
+ for (int i = 0; i < mult; ++i) {
+ int idNow = channel.product(i);
+ int idAbs = abs(idNow);
+ if ( idAbs < 10 || idAbs == 21 || idAbs == 81 || idAbs == 82
+ || idAbs == 83 || (idAbs > 1000 && idAbs < 10000
+ && (idAbs/10)%10 == 0) ) hasPartons = true;
+ if (idDec < 0 && ParticleDataTable::hasAnti(idNow)) idNow = -idNow;
+ double mNow = ParticleDataTable::mass(idNow);
+ idProd.push_back( idNow);
+ mProd.push_back( mNow);
+ }
+
+ // Decays into partons usually translate into hadrons.
+ if (hasPartons && !keepPartons && !pickHadrons()) continue;
+
+ // Need to set colour flow if explicit decay to partons.
+ cols.resize(0);
+ acols.resize(0);
+ for (int i = 0; i <= mult; ++i) {
+ cols.push_back(0);
+ acols.push_back(0);
+ }
+ if (hasPartons && keepPartons && !setColours(event)) continue;
+
+ // Check that enough phase space for decay.
+ if (mult > 1) {
+ double mDiff = mProd[0];
+ for (int i = 1; i <= mult; ++i) mDiff -= mProd[i];
+ if (mDiff < mSafety) continue;
+ }
+
+ // End of two trial loops. Check if succeeded or not.
+ foundChannel = true;
+ break;
+ }
+ if (foundChannel) break;
+ }
+ if (!foundChannel) {
+ infoPtr->errorMsg("Error in ParticleDecays::decay: "
+ "failed to find workable decay channel");
+ return false;
+ }
+
+ // Store decay products in the event record.
+ int status = (hasOscillated) ? 92 : 91;
+ for (int i = 1; i <= mult; ++i) {
+ int iPos = event.append( idProd[i], status, iDec, 0, 0, 0,
+ cols[i], acols[i], Vec4(0., 0., 0., 0.), mProd[i]);
+ iProd.push_back( iPos);
+ }
+
+ // Pick mass of Dalitz decay. Temporarily change multiplicity.
+ if (meMode == 11 || meMode == 12 || meMode == 13) {
+ bool foundMass = dalitzMass();
+ if (!foundMass) {
+ event.popBack(mult);
+ return false;
+ }
+ }
+
+ // Do a decay, split by multiplicity.
+ bool decayed = false;
+ if (mult == 1) decayed = oneBody(event);
+ else if (mult == 2) decayed = twoBody(event);
+ else if (mult == 3) decayed = threeBody(event);
+ else decayed = mGenerator(event);
+
+ // Kinematics of gamma* -> l- l+ in Dalitz decay. Restore multiplicity.
+ if (meMode == 11 || meMode == 12 || meMode == 13)
+ dalitzKinematics(event);
+
+ // If the decay worked, then mark mother decayed and store daughters.
+ if (decayed) {
+ event[iDec].statusNeg();
+ event[iDec].daughters( iProd[1], iProd[mult]);
+
+ // Else remove unused daughters and return failure.
+ } else {
+ event.popBack(mult);
+ return false;
+ }
+
+ // Now finished normal internal decay treatment.
+ }
+
+ // Set decay vertex when this is displaced.
+ if (event[iDec].hasVertex() || event[iDec].tau() > 0.) {
+ Vec4 vDec = event[iDec].vDec();
+ for (int i = 1; i <= mult; ++i) event[iProd[i]].vProd( vDec );
+ }
+
+ // Set lifetime of hadrons.
+ for (int i = 1; i <= mult; ++i)
+ event[iProd[i]].tau( event[iProd[i]].tau0() * Rndm::exp() );
+
+ // In a decay explicitly to partons then optionally do a shower,
+ // and always flag that partonic system should be fragmented.
+ if (hasPartons && keepPartons && doFSRinDecays)
+ timesDecPtr->shower( iProd[1], iProd.back(), event, mProd[0]);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Check whether a decay is allowed, given the upcoming decay vertex.
+
+bool ParticleDecays::checkVertex(Particle& decayer) {
+
+ // Check whether any of the conditions are not fulfilled.
+ if (limitTau0 && decayer.tau0() > tau0Max) return false;
+ if (limitTau && decayer.tau() > tauMax) return false;
+ if (limitRadius && pow2(decayer.xDec()) + pow2(decayer.yDec())
+ + pow2(decayer.zDec()) > pow2(rMax)) return false;
+ if (limitCylinder && (pow2(decayer.xDec()) + pow2(decayer.yDec())
+ > pow2(xyMax) || abs(decayer.zDec()) > zMax) ) return false;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Check for oscillations B0 <-> B0bar or B_s0 <-> B_s0bar.
+
+bool ParticleDecays::oscillateB(Particle& decayer) {
+
+ // Extract relevant information and decide.
+ double xBmix = (abs(decayer.id()) == 511) ? xBdMix : xBsMix;
+ double tau = decayer.tau();
+ double tau0 = decayer.tau0();
+ double probosc = pow2(sin(0.5 * xBmix * tau / tau0));
+ return (probosc > Rndm::flat());
+
+}
+
+//*********
+
+// Do a one-body decay. (Rare; e.g. for K0 -> K0_short.)
+
+bool ParticleDecays::oneBody(Event& event) {
+
+ // References to the particles involved.
+ Particle& decayer = event[iProd[0]];
+ Particle& prod = event[iProd[1]];
+
+ // Set momentum and expand mother information.
+ prod.p( decayer.p() );
+ prod.m( decayer.m() );
+ prod.mother2( iProd[0] );
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Do a two-body decay.
+
+bool ParticleDecays::twoBody(Event& event) {
+
+ // References to the particles involved.
+ Particle& decayer = event[iProd[0]];
+ Particle& prod1 = event[iProd[1]];
+ Particle& prod2 = event[iProd[2]];
+
+ // Masses.
+ double m0 = mProd[0];
+ double m1 = mProd[1];
+ double m2 = mProd[2];
+
+ // Energies and absolute momentum in the rest frame.
+ if (m1 + m2 + mSafety > m0) return false;
+ double e1 = 0.5 * (m0*m0 + m1*m1 - m2*m2) / m0;
+ double e2 = 0.5 * (m0*m0 + m2*m2 - m1*m1) / m0;
+ double pAbs = 0.5 * sqrtpos( (m0 - m1 - m2) * (m0 + m1 + m2)
+ * (m0 + m1 - m2) * (m0 - m1 + m2) ) / m0;
+
+ // When meMode = 2, for V -> PS2 + PS3 (V = vector, pseudoscalar),
+ // need to check if production is PS0 -> PS1/gamma + V.
+ int iMother = event[iProd[0]].mother1();
+ int idSister = 0;
+ if (meMode == 2) {
+ if (iMother <= 0 || iMother >= iProd[0]) meMode = 0;
+ else {
+ int iDaughter1 = event[iMother].daughter1();
+ int iDaughter2 = event[iMother].daughter2();
+ if (iDaughter2 != iDaughter1 + 1) meMode = 0;
+ else {
+ int idMother = abs( event[iMother].id() );
+ if (idMother <= 100 || idMother%10 !=1
+ || (idMother/1000)%10 != 0) meMode = 0;
+ else {
+ int iSister = (iProd[0] == iDaughter1) ? iDaughter2 : iDaughter1;
+ idSister = abs( event[iSister].id() );
+ if ( (idSister <= 100 || idSister%10 !=1
+ || (idSister/1000)%10 != 0) && idSister != 22) meMode = 0;
+ }
+ }
+ }
+ }
+
+ // Begin loop over matrix-element corrections.
+ double wtME, wtMEmax;
+ do {
+ wtME = 1.;
+ wtMEmax = 1.;
+
+ // Isotropic angles give three-momentum.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi = 2. * M_PI * Rndm::flat();
+ double pX = pAbs * sinTheta * cos(phi);
+ double pY = pAbs * sinTheta * sin(phi);
+ double pZ = pAbs * cosTheta;
+
+ // Fill four-momenta and boost them away from mother rest frame.
+ prod1.p( pX, pY, pZ, e1);
+ prod2.p( -pX, -pY, -pZ, e2);
+ prod1.bst( decayer.p(), decayer.m() );
+ prod2.bst( decayer.p(), decayer.m() );
+
+ // Matrix element for PS0 -> PS1 + V1 -> PS1 + PS2 + PS3 of form
+ // cos**2(theta02) in V1 rest frame, and for PS0 -> gamma + V1
+ // -> gamma + PS2 + PS3 of form sin**2(theta02).
+ if (meMode == 2) {
+ double p10 = decayer.p() * event[iMother].p();
+ double p12 = decayer.p() * prod1.p();
+ double p02 = event[iMother].p() * prod1.p();
+ double s0 = pow2(event[iMother].m());
+ double s1 = pow2(decayer.m());
+ double s2 = pow2(prod1.m());
+ if (idSister != 22) wtME = pow2(p10 * p12 - s1 * p02);
+ else wtME = s1 * (2. * p10 * p12 * p02 - s1 * p02*p02
+ - s0 * p12*p12 - s2 * p10*p10 + s1 * s0 * s2);
+ wtME = max( wtME, 1e-6 * s1*s1 * s0 * s2);
+ wtMEmax = (p10*p10 - s1 * s0) * (p12*p12 - s1 * s2);
+ }
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtME < Rndm::flat() * wtMEmax );
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Do a three-body decay (except Dalitz decays).
+
+bool ParticleDecays::threeBody(Event& event) {
+
+ // References to the particles involved.
+ Particle& decayer = event[iProd[0]];
+ Particle& prod1 = event[iProd[1]];
+ Particle& prod2 = event[iProd[2]];
+ Particle& prod3 = event[iProd[3]];
+
+ // Mother and sum daughter masses. Fail if too close.
+ double m0 = mProd[0];
+ double m1 = mProd[1];
+ double m2 = mProd[2];
+ double m3 = mProd[3];
+ double mSum = m1 + m2 + m3;
+ double mDiff = m0 - mSum;
+ if (mDiff < mSafety) return false;
+
+ // Kinematical limits for 2+3 mass. Maximum phase-space weight.
+ double m23Min = m2 + m3;
+ double m23Max = m0 - m1;
+ double p1Max = 0.5 * sqrtpos( (m0 - m1 - m23Min) * (m0 + m1 + m23Min)
+ * (m0 + m1 - m23Min) * (m0 - m1 + m23Min) ) / m0;
+ double p23Max = 0.5 * sqrtpos( (m23Max - m2 - m3) * (m23Max + m2 + m3)
+ * (m23Max + m2 - m3) * (m23Max - m2 + m3) ) / m23Max;
+ double wtPSmax = 0.5 * p1Max * p23Max;
+
+ // Begin loop over matrix-element corrections.
+ double wtME, wtMEmax, wtPS, m23, p1Abs, p23Abs;
+ do {
+ wtME = 1.;
+ wtMEmax = 1.;
+
+ // Pick an intermediate mass m23 flat in the allowed range.
+ do {
+ m23 = m23Min + Rndm::flat() * mDiff;
+
+ // Translate into relative momenta and find phase-space weight.
+ p1Abs = 0.5 * sqrtpos( (m0 - m1 - m23) * (m0 + m1 + m23)
+ * (m0 + m1 - m23) * (m0 - m1 + m23) ) / m0;
+ p23Abs = 0.5 * sqrtpos( (m23 - m2 - m3) * (m23 + m2 + m3)
+ * (m23 + m2 - m3) * (m23 - m2 + m3) ) / m23;
+ wtPS = p1Abs * p23Abs;
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtPS < Rndm::flat() * wtPSmax );
+
+ // Set up m23 -> m2 + m3 isotropic in its rest frame.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi = 2. * M_PI * Rndm::flat();
+ double pX = p23Abs * sinTheta * cos(phi);
+ double pY = p23Abs * sinTheta * sin(phi);
+ double pZ = p23Abs * cosTheta;
+ double e2 = sqrt( m2*m2 + p23Abs*p23Abs);
+ double e3 = sqrt( m3*m3 + p23Abs*p23Abs);
+ prod2.p( pX, pY, pZ, e2);
+ prod3.p( -pX, -pY, -pZ, e3);
+
+ // Set up m0 -> m1 + m23 isotropic in its rest frame.
+ cosTheta = 2. * Rndm::flat() - 1.;
+ sinTheta = sqrt(1. - cosTheta*cosTheta);
+ phi = 2. * M_PI * Rndm::flat();
+ pX = p1Abs * sinTheta * cos(phi);
+ pY = p1Abs * sinTheta * sin(phi);
+ pZ = p1Abs * cosTheta;
+ double e1 = sqrt( m1*m1 + p1Abs*p1Abs);
+ double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
+ prod1.p( pX, pY, pZ, e1);
+
+ // Boost 2 + 3 to the 0 rest frame.
+ Vec4 p23( -pX, -pY, -pZ, e23);
+ prod2.bst( p23, m23 );
+ prod3.bst( p23, m23 );
+
+ // Matrix-element weight for omega/phi -> pi+ pi- pi0.
+ if (meMode == 1) {
+ double p1p2 = prod1.p() * prod2.p();
+ double p1p3 = prod1.p() * prod3.p();
+ double p2p3 = prod2.p() * prod3.p();
+ wtME = pow2(m1 * m2 * m3) - pow2(m1 * p2p3) - pow2(m2 * p1p3)
+ - pow2(m3 * p1p2) + 2. * p1p2 * p1p3 * p2p3;
+ wtMEmax = pow3(m0 * m0) / 150.;
+
+ // Effective matrix element for nu spectrum in tau -> nu + hadrons.
+ } else if (meMode == 21) {
+ double x1 = 2. * prod1.e() / m0;
+ wtME = x1 * (3. - 2. * x1);
+ double xMax = min( 0.75, 2. * (1. - mSum / m0) );
+ wtMEmax = xMax * (3. - 2. * xMax);
+
+ // Matrix element for weak decay (only semileptonic for c and b).
+ } else if ((meMode == 22 || meMode == 23) && prod1.isLepton()) {
+ wtME = m0 * prod1.e() * (prod2.p() * prod3.p());
+ wtMEmax = min( pow4(m0) / 16., m0 * (m0 - m1 - m2) * (m0 - m1 - m3)
+ * (m0 - m2 - m3) );
+
+ // Effective matrix element for weak decay to hadrons (B -> D, D -> K).
+ } else if (meMode == 22 || meMode == 23) {
+ double x1 = 2. * prod1.pAbs() / m0;
+ wtME = x1 * (3. - 2. * x1);
+ double xMax = min( 0.75, 2. * (1. - mSum / m0) );
+ wtMEmax = xMax * (3. - 2. * xMax);
+
+ // Effective matrix element for gamma spectrum in B -> gamma + hadrons.
+ } else if (meMode == 31) {
+ double x1 = 2. * prod1.e() / m0;
+ wtME = pow3(x1);
+ double x1Max = 1. - pow2(mSum / m0);
+ wtMEmax = pow3(x1Max);
+
+ // Matrix-element weight for "onium" -> g + g + g or gamma + g + g.
+ } else if (meMode == 92) {
+ double x1 = 2. * prod1.e() / m0;
+ double x2 = 2. * prod2.e() / m0;
+ double x3 = 2. * prod3.e() / m0;
+ wtME = pow2( (1. - x1) / (x2 * x3) ) + pow2( (1. - x2) / (x1 * x3) )
+ + pow2( (1. - x3) / (x1 * x2) );
+ wtMEmax = 2.;
+ // For gamma + g + g require minimum mass for g + g system.
+ if (prod1.id() == 22 && sqrt(1. - x1) * m0 < 2. * stopMass) wtME = 0.;
+ if (prod2.id() == 22 && sqrt(1. - x2) * m0 < 2. * stopMass) wtME = 0.;
+ if (prod3.id() == 22 && sqrt(1. - x3) * m0 < 2. * stopMass) wtME = 0.;
+ }
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtME < Rndm::flat() * wtMEmax );
+
+ // Boost 1 + 2 + 3 to the current frame.
+ prod1.bst( decayer.p(), decayer.m() );
+ prod2.bst( decayer.p(), decayer.m() );
+ prod3.bst( decayer.p(), decayer.m() );
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Do a multibody decay using the M-generator algorithm.
+
+bool ParticleDecays::mGenerator(Event& event) {
+
+ // Mother and sum daughter masses. Fail if too close or inconsistent.
+ double m0 = mProd[0];
+ double mSum = mProd[1];
+ for (int i = 2; i <= mult; ++i) mSum += mProd[i];
+ double mDiff = m0 - mSum;
+ if (mDiff < mSafety) return false;
+
+ // Begin setup of intermediate invariant masses.
+ mInv.resize(0);
+ for (int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
+
+ // Calculate the maximum weight in the decay.
+ double wtPS, wtME, wtMEmax;
+ double wtPSmax = 1. / WTCORRECTION[mult];
+ double mMax = mDiff + mProd[mult];
+ double mMin = 0.;
+ for (int i = mult - 1; i > 0; --i) {
+ mMax += mProd[i];
+ mMin += mProd[i+1];
+ double mNow = mProd[i];
+ wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
+ * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
+ }
+
+ // Begin loop over matrix-element corrections.
+ do {
+ wtME = 1.;
+ wtMEmax = 1.;
+
+ // Begin loop to find the set of intermediate invariant masses.
+ do {
+ wtPS = 1.;
+
+ // Find and order random numbers in descending order.
+ rndmOrd.resize(0);
+ rndmOrd.push_back(1.);
+ for (int i = 1; i < mult - 1; ++i) {
+ double rndm = Rndm::flat();
+ rndmOrd.push_back(rndm);
+ for (int j = i - 1; j > 0; --j) {
+ if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
+ else break;
+ }
+ }
+ rndmOrd.push_back(0.);
+
+ // Translate into intermediate masses and find weight.
+ for (int i = mult - 1; i > 0; --i) {
+ mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
+ wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
+ * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
+ * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
+ }
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtPS < Rndm::flat() * wtPSmax );
+
+ // Perform two-particle decays in the respective rest frame.
+ pInv.resize(mult + 1);
+ for (int i = 1; i < mult; ++i) {
+ double pAbs = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
+ * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
+ * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
+
+ // Isotropic angles give three-momentum.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi = 2. * M_PI * Rndm::flat();
+ double pX = pAbs * sinTheta * cos(phi);
+ double pY = pAbs * sinTheta * sin(phi);
+ double pZ = pAbs * cosTheta;
+
+ // Calculate energies, fill four-momenta.
+ double eHad = sqrt( mProd[i]*mProd[i] + pAbs*pAbs);
+ double eInv = sqrt( mInv[i+1]*mInv[i+1] + pAbs*pAbs);
+ event[iProd[i]].p( pX, pY, pZ, eHad);
+ pInv[i+1].p( -pX, -pY, -pZ, eInv);
+ }
+
+ // Boost decay products to the mother rest frame.
+ event[iProd[mult]].p( pInv[mult] );
+ for (int iFrame = mult - 1; iFrame > 1; --iFrame)
+ for (int i = iFrame; i <= mult; ++i)
+ event[iProd[i]].bst( pInv[iFrame], mInv[iFrame]);
+
+ // Effective matrix element for nu spectrum in tau -> nu + hadrons.
+ if (meMode == 21 && event[iProd[1]].isLepton()) {
+ double x1 = 2. * event[iProd[1]].e() / m0;
+ wtME = x1 * (3. - 2. * x1);
+ double xMax = min( 0.75, 2. * (1. - mSum / m0) );
+ wtMEmax = xMax * (3. - 2. * xMax);
+
+ // Effective matrix element for weak decay (only semileptonic for c and b).
+ // Particles 4 onwards should be made softer explicitly?
+ } else if ((meMode == 22 || meMode == 23) && event[iProd[1]].isLepton()) {
+ Vec4 pRest = event[iProd[3]].p();
+ for (int i = 4; i <= mult; ++i) pRest += event[iProd[i]].p();
+ wtME = m0 * event[iProd[1]].e() * (event[iProd[2]].p() * pRest);
+ for (int i = 4; i <= mult; ++i) wtME
+ *= exp(- event[iProd[i]].pAbs2() / pow2(sigmaSoft) );
+ wtMEmax = pow4(m0) / 16.;
+
+ // Effective matrix element for weak decay to hadrons (B -> D, D -> K).
+ } else if (meMode == 22 || meMode == 23) {
+ double x1 = 2. * event[iProd[1]].pAbs() / m0;
+ wtME = x1 * (3. - 2. * x1);
+ double xMax = min( 0.75, 2. * (1. - mSum / m0) );
+ wtMEmax = xMax * (3. - 2. * xMax);
+
+ // Effective matrix element for gamma spectrum in B -> gamma + hadrons.
+ } else if (meMode == 31) {
+ double x1 = 2. * event[iProd[1]].e() / m0;
+ wtME = pow3(x1);
+ double x1Max = 1. - pow2(mSum / m0);
+ wtMEmax = pow3(x1Max);
+ }
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtME < Rndm::flat() * wtMEmax );
+
+ // Boost decay products to the current frame.
+ pInv[1].p( event[iProd[0]].p() );
+ for (int i = 1; i <= mult; ++i) event[iProd[i]].bst( pInv[1], mInv[1] );
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Select mass of lepton pair in a Dalitz decay.
+
+bool ParticleDecays::dalitzMass() {
+
+ // Mother and sum daughter masses.
+ double mSum1 = 0;
+ for (int i = 1; i <= mult - 2; ++i) mSum1 += mProd[i];
+ if (meMode == 13) mSum1 *= MSAFEDALITZ;
+ double mSum2 = MSAFEDALITZ * (mProd[mult -1] + mProd[mult]);
+ double mDiff = mProd[0] - mSum1 - mSum2;
+
+ // Fail if too close or inconsistent.
+ if (mDiff < mSafety) return false;
+ if (idProd[mult - 1] + idProd[mult] != 0
+ || mProd[mult - 1] != mProd[mult]) {
+ infoPtr->errorMsg("Error in ParticleDecays::dalitzMass:"
+ " inconsistent flavour/mass assignments");
+ return false;
+ }
+ if ( meMode == 13 && (idProd[1] + idProd[2] != 0
+ || mProd[1] != mProd[2]) ) {
+ infoPtr->errorMsg("Error in ParticleDecays::dalitzMass:"
+ " inconsistent flavour/mass assignments");
+ return false;
+ }
+
+ // Case 1: one Dalitz pair.
+ if (meMode == 11 || meMode == 12) {
+
+ // Kinematical limits for gamma* squared mass.
+ double sGamMin = pow2(mSum2);
+ double sGamMax = pow2(mProd[0] - mSum1);
+
+ // Select virtual gamma squared mass. Guessed form for meMode == 12.
+ double sGam, wtGam;
+ do {
+ sGam = sGamMin * pow( sGamMax / sGamMin, Rndm::flat() );
+ wtGam = (1. + 0.5 * sGamMin / sGam) * sqrt(1. - sGamMin / sGam)
+ * pow3(1. - sGam / sGamMax) * sRhoDal * (sRhoDal + wRhoDal)
+ / ( pow2(sGam - sRhoDal) + sRhoDal * wRhoDal );
+ } while ( wtGam < Rndm::flat() );
+
+ // Store results in preparation for doing a one-less-body decay.
+ --mult;
+ mProd[mult] = sqrt(sGam);
+
+ // Case 2: two Dalitz pairs.
+ } else {
+
+ // Kinematical limits for 1 + 2 and 3 + 4 gamma* masses.
+ double s0 = pow2(mProd[0]);
+ double s12Min = pow2(mSum1);
+ double s12Max = pow2(mProd[0] - mSum2);
+ double s34Min = pow2(mSum2);
+ double s34Max = pow2(mProd[0] - mSum1);
+
+ // Select virtual gamma squared masses. Guessed form for meMode == 13.
+ double s12, s34, wt12, wt34, wtPAbs, wtAll;
+ do {
+ s12 = s12Min * pow( s12Max / s12Min, Rndm::flat() );
+ wt12 = (1. + 0.5 * s12Min / s12) * sqrt(1. - s12Min / s12)
+ * sRhoDal * (sRhoDal + wRhoDal)
+ / ( pow2(s12 - sRhoDal) + sRhoDal * wRhoDal );
+ s34 = s34Min * pow( s34Max / s34Min, Rndm::flat() );
+ wt34 = (1. + 0.5 * s34Min / s34) * sqrt(1. - s34Min / s34)
+ * sRhoDal * (sRhoDal + wRhoDal)
+ / ( pow2(s34 - sRhoDal) + sRhoDal * wRhoDal );
+ wtPAbs = sqrtpos( pow2(1. - (s12 + s34)/ s0)
+ - 4. * s12 * s34 / (s0 * s0) );
+ wtAll = wt12 * wt34 * pow3(wtPAbs);
+ if (wtAll > 1.) infoPtr->errorMsg(
+ "Error in ParticleDecays::dalitzMass: weight > 1");
+ } while (wtAll < Rndm::flat());
+
+ // Store results in preparation for doing a two-body decay.
+ mult = 2;
+ mProd[1] = sqrt(s12);
+ mProd[2] = sqrt(s34);
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Do kinematics of gamma* -> l- l+ in Dalitz decay.
+
+bool ParticleDecays::dalitzKinematics(Event& event) {
+
+ // Restore multiplicity.
+ int nDal = (meMode < 13) ? 1 : 2;
+ mult += nDal;
+
+ // Loop over one or two lepton pairs.
+ for (int iDal = 0; iDal < nDal; ++iDal) {
+
+ // References to the particles involved.
+ Particle& decayer = event[iProd[0]];
+ Particle& prodA = (iDal == 0) ? event[iProd[mult - 1]]
+ : event[iProd[1]];
+ Particle& prodB = (iDal == 0) ? event[iProd[mult]]
+ : event[iProd[2]];
+
+ // Reconstruct required rotations and boosts backwards.
+ Vec4 pDec = decayer.p();
+ int iGam = (meMode < 13) ? mult - 1 : 2 - iDal;
+ Vec4 pGam = event[iProd[iGam]].p();
+ Vec4 pGamOld = pGam;
+ pGam.bstback( pDec, decayer.m() );
+ double phiGam = pGam.phi();
+ pGam.rot( 0., -phiGam);
+ double thetaGam = pGam.theta();
+ pGam.rot( -thetaGam, 0.);
+
+ // Masses and phase space in gamma* rest frame.
+ double mGam = (meMode < 13) ? mProd[mult - 1] : mProd[2 - iDal];
+ double mA = prodA.m();
+ double mB = prodB.m();
+ double mGamMin = MSAFEDALITZ * (mA + mB);
+ double mGamRat = pow2(mGamMin / mGam);
+ double pGamAbs = 0.5 * sqrtpos( (mGam - mA - mB) * (mGam + mA + mB) );
+
+ // Set up decay in gamma* rest frame, reference along +z axis.
+ double cosTheta, cos2Theta;
+ do {
+ cosTheta = 2. * Rndm::flat() - 1.;
+ cos2Theta = cosTheta * cosTheta;
+ } while ( 1. + cos2Theta + mGamRat * (1. - cos2Theta)
+ < 2. * Rndm::flat() );
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi = 2. * M_PI * Rndm::flat();
+ double pX = pGamAbs * sinTheta * cos(phi);
+ double pY = pGamAbs * sinTheta * sin(phi);
+ double pZ = pGamAbs * cosTheta;
+ double eA = sqrt( mA*mA + pGamAbs*pGamAbs);
+ double eB = sqrt( mB*mB + pGamAbs*pGamAbs);
+ prodA.p( pX, pY, pZ, eA);
+ prodB.p( -pX, -pY, -pZ, eB);
+
+ // Boost to lab frame.
+ prodA.bst( pGam, mGam);
+ prodB.bst( pGam, mGam);
+ prodA.rot( thetaGam, phiGam);
+ prodB.rot( thetaGam, phiGam);
+ prodA.bst( pDec, decayer.m() );
+ prodB.bst( pDec, decayer.m() );
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Translate a partonic content into a set of actual hadrons.
+
+bool ParticleDecays::pickHadrons() {
+
+ // Find partonic decay products. Rest are known id's, mainly hadrons,
+ // when necessary shuffled to beginning of idProd list.
+ idPartons.resize(0);
+ int nPartons = 0;
+ int nKnown = 0;
+ bool closedGLoop = false;
+ for (int i = 1; i <= mult; ++i) {
+ int idAbs = abs(idProd[i]);
+ if ( idAbs < 9 || (idAbs > 1000 && idAbs < 10000 && (idAbs/10)%10 == 0)
+ || idAbs == 81 || idAbs == 82 || idAbs == 83) {
+ ++nPartons;
+ idPartons.push_back(idProd[i]);
+ if (idAbs == 83) closedGLoop = true;
+ } else {
+ ++nKnown;
+ if (nPartons > 0) {
+ idProd[nKnown] = idProd[i];
+ mProd[nKnown] = mProd[i];
+ }
+ }
+ }
+
+ // Replace generic spectator flavour code by the actual one.
+ for (int i = 0; i < nPartons; ++i) {
+ int idPart = idPartons[i];
+ int idNew = idPart;
+ if (idPart == 81) {
+ int idAbs = abs(idDec);
+ if ( (idAbs/1000)%10 == 0 ) {
+ idNew = -(idAbs/10)%10;
+ if ((idAbs/100)%2 == 1) idNew = -idNew;
+ } else if ( (idAbs/100)%10 >= (idAbs/10)%10 )
+ idNew = 100 * ((idAbs/10)%100) + 3;
+ else idNew = 1000 * ((idAbs/10)%10) + 100 * ((idAbs/100)%10) + 1;
+ if (idDec < 0) idNew = -idNew;
+
+ // Replace generic random flavour by a randomly selected one.
+ } else if (idPart == 82 || idPart == 83) {
+ double mFlav;
+ do {
+ int idDummy = -flavSelPtr->pickLightQ();
+ FlavContainer flavDummy(idDummy, idPart - 82);
+ do idNew = flavSelPtr->pick(flavDummy).id;
+ while (idNew == 0);
+ mFlav = ParticleDataTable::constituentMass(idNew);
+ } while (2. * mFlav + stopMass > mProd[0]);
+ } else if (idPart == -82 || idPart == -83) {
+ idNew = -idPartons[i-1];
+ }
+ idPartons[i] = idNew;
+ }
+
+ // Determine whether fixed multiplicity or to be selected at random.
+ int nMin = max( 2, nKnown + nPartons / 2);
+ if (meMode == 23) nMin = 3;
+ if (meMode > 41 && meMode <= 50) nMin = meMode - 40;
+ if (meMode > 51 && meMode <= 60) nMin = meMode - 50;
+ int nFix = 0;
+ if (meMode == 0) nFix = nMin;
+ if (meMode == 11) nFix = 3;
+ if (meMode == 12) nFix = 4;
+ if (meMode > 61 && meMode <= 70) nFix = meMode - 60;
+ if (meMode > 71 && meMode <= 80) nFix = meMode - 70;
+ if (nFix > 0 && nKnown + nPartons/2 > nFix) return false;
+
+ // Initial values for loop to set new hadronic content.
+ int nFilled = nKnown + 1;
+ int nTotal, nNew, nSpec, nLeft;
+ double mDiff;
+ int nTry = 0;
+ bool diquarkClash = false;
+ bool usedChannel = false;
+
+ // Begin loop; interrupt if multiple tries fail.
+ do {
+ ++nTry;
+ if (nTry > NTRYPICK) return false;
+
+ // Initialize variables inside new try.
+ nFilled = nKnown + 1;
+ idProd.resize(nFilled);
+ mProd.resize(nFilled);
+ nTotal = nKnown;
+ nNew = 0;
+ nSpec = 0;
+ nLeft = nPartons;
+ mDiff = mProd[0];
+ for (int i = 1; i < nFilled; ++i) mDiff -= mProd[i];
+ diquarkClash = false;
+ usedChannel = false;
+
+ // For weak decays collapse spectators to one particle.
+ if ( (meMode == 22 || meMode == 23) && nLeft > 1) {
+ FlavContainer flav1( idPartons[nPartons - 2] );
+ FlavContainer flav2( idPartons[nPartons - 1] );
+ int idHad;
+ do idHad = flavSelPtr->combine( flav1, flav2);
+ while (idHad == 0);
+ double mHad = ParticleDataTable::mass(idHad);
+ mDiff -= mHad;
+ idProd.push_back( idHad);
+ mProd.push_back( mHad);
+ ++nFilled;
+ nSpec = 1;
+ nLeft -= 2;
+ }
+
+ // If there are partons left, then determine how many hadrons to pick.
+ if (nLeft > 0) {
+
+ // For B -> gamma + X use geometrical distribution.
+ if (meMode == 31) {
+ double geom = Rndm::flat();
+ nTotal = 1;
+ do {
+ ++nTotal;
+ geom *= 2.;
+ } while (geom < 1. && nTotal < 10);
+
+ // Calculate mass excess and from there average multiplicity.
+ } else if (nFix == 0) {
+ double mDiffPS = mDiff;
+ for (int i = 0; i < nLeft; ++i)
+ mDiffPS -= ParticleDataTable::constituentMass( idPartons[i] );
+ double average = 0.5 * (nKnown + nSpec) + 0.25 * nPartons
+ + multIncrease * log( max( 1.1, mDiffPS / multRefMass ) );
+ if (closedGLoop) average += multGoffset;
+
+ // Pick multiplicity according to Poissonian.
+ double value = 1.;
+ double sum = 1.;
+ for (int nNow = nMin + 1; nNow <= 10; ++nNow) {
+ value *= average / nNow;
+ sum += value;
+ }
+ nTotal = nMin;
+ value = 1.;
+ sum *= Rndm::flat();
+ sum -= value;
+ if (sum > 0.) do {
+ ++nTotal;
+ value *= average / nTotal;
+ sum -= value;
+ } while (sum > 0. && nTotal < 10);
+
+ // Alternatively predetermined multiplicity.
+ } else {
+ nTotal = nFix;
+ }
+ nNew = nTotal - nKnown - nSpec;
+
+ // Set up ends of fragmented system, as copy of idPartons.
+ flavEnds.resize(0);
+ for (int i = 0; i < nLeft; ++i) {
+ flavEnds.push_back( FlavContainer(idPartons[i]) );
+ if (abs(idPartons[i]) > 100) flavSelPtr->assignPopQ( flavEnds[i] );
+ }
+
+ // Fragment off at random, but save nLeft/2 for final recombination.
+ if (nNew > nLeft/2) {
+ FlavContainer flavNew;
+ int idHad;
+ for (int i = 0; i < nNew - nLeft/2; ++i) {
+ // When four quarks consider last one to be spectator.
+ int iEnd = int( (nLeft - 1.) * Rndm::flat() );
+ // Pick new flavour and form a new hadron.
+ do {
+ flavNew = flavSelPtr->pick( flavEnds[iEnd] );
+ idHad = flavSelPtr->combine( flavEnds[iEnd], flavNew);
+ } while (idHad == 0);
+ // Store new hadron and endpoint flavour.
+ idProd.push_back( idHad);
+ flavEnds[iEnd].anti(flavNew);
+ }
+ }
+
+ // When only two quarks left, combine to form final hadron.
+ if (nLeft == 2) {
+ int idHad;
+ if ( abs(flavEnds[0].id) > 8 && abs(flavEnds[1].id) > 8)
+ diquarkClash = true;
+ else {
+ do idHad = flavSelPtr->combine( flavEnds[0], flavEnds[1]);
+ while (idHad == 0);
+ idProd.push_back( idHad);
+ }
+
+ // If four quarks, decide how to pair them up.
+ } else {
+ int iEnd1 = 0;
+ int iEnd2 = 1;
+ int iEnd3 = 2;
+ int iEnd4 = 3;
+ if ( Rndm::flat() < colRearrange) iEnd2 = 3;
+ int relColSign =
+ ( (flavEnds[iEnd1].id > 0 && flavEnds[iEnd1].id < 9)
+ || flavEnds[iEnd1].id < -10 ) ? 1 : -1;
+ if ( (flavEnds[iEnd2].id < 0 && flavEnds[iEnd2].id > -9)
+ || flavEnds[iEnd2].id > 10 ) relColSign *= -1;
+ if (relColSign == 1) iEnd2 = 2;
+ if (iEnd2 == 2) iEnd3 = 1;
+ if (iEnd2 == 3) iEnd4 = 1;
+
+ // Then combine to get final two hadrons.
+ int idHad;
+ if ( abs(flavEnds[iEnd1].id) > 8 && abs(flavEnds[iEnd2].id) > 8)
+ diquarkClash = true;
+ else {
+ do idHad = flavSelPtr->combine( flavEnds[iEnd1], flavEnds[iEnd2]);
+ while (idHad == 0);
+ idProd.push_back( idHad);
+ }
+ if ( abs(flavEnds[iEnd3].id) > 8 && abs(flavEnds[iEnd4].id) > 8)
+ diquarkClash = true;
+ else {
+ do idHad = flavSelPtr->combine( flavEnds[iEnd3], flavEnds[iEnd4]);
+ while (idHad == 0);
+ idProd.push_back( idHad);
+ }
+ }
+
+ // Find masses of the new hadrons.
+ for (int i = nFilled; i < int(idProd.size()) ; ++i) {
+ double mHad = ParticleDataTable::mass(idProd[i]);
+ mProd.push_back( mHad);
+ mDiff -= mHad;
+ }
+ }
+
+ // Optional: check that this decay mode is not explicitly defined.
+ if ( (meMode > 61 && meMode <= 80) && mDiff > mSafety && !diquarkClash ) {
+ int idMatch[10], idPNow;
+ usedChannel = false;
+ bool matched = false;
+ // Loop through all channels. Done if not same multiplicity.
+ for (int i = 0; i < decDataPtr->decay.size(); ++i) {
+ DecayChannel& channel = decDataPtr->decay[i];
+ if (channel.multiplicity() != nTotal) continue;
+ for (int k = 0; k < nTotal; ++k) idMatch[k] = channel.product(k);
+ // Match particles one by one until fail.
+ // Do not distinguish K0/K0bar/K0short/K0long at this stage.
+ for (int j = 0; j < nTotal; ++j) {
+ matched = false;
+ idPNow = idProd[j + 1];
+ if (idPNow == -311 || idPNow == 130 || idPNow == 310) idPNow = 311;
+ for (int k = 0; k < nTotal - j; ++k)
+ if (idMatch[k] == idPNow || (idMatch[k] == -311 && idPNow == 311)) {
+ // Compress list of unmatched when matching worked.
+ idMatch[k] = idMatch[nTotal - 1 - j];
+ matched = true;
+ break;
+ }
+ if (!matched) break;
+ }
+ // If matching worked, then chosen channel to be rejected.
+ if (matched) {usedChannel = true; break;}
+ }
+ }
+
+ // Keep on trying until enough phase space and no clash.
+ } while (mDiff < mSafety || diquarkClash || usedChannel);
+
+ // Update particle multiplicity.
+ mult = idProd.size() - 1;
+
+ // For Dalitz decays shuffle Dalitz pair to the end of the list.
+ if (meMode == 11 || meMode == 12) {
+ int iL1 = 0;
+ int iL2 = 0;
+ for (int i = 1; i <= mult; ++i) {
+ if (idProd[i] == 11 || idProd[i] == 13 || idProd[i] == 15) iL1 = i;
+ if (idProd[i] == -11 || idProd[i] == -13 || idProd[i] == -15) iL2 = i;
+ }
+ if (iL1 > 0 && iL2 > 0) {
+ int idL1 = idProd[iL1];
+ int idL2 = idProd[iL2];
+ double mL1 = mProd[iL1];
+ double mL2 = mProd[iL2];
+ int iMove = 0;
+ for (int i = 1; i <= mult; ++i) if (i != iL1 && i != iL2) {
+ ++iMove;
+ idProd[iMove] = idProd[i];
+ mProd[iMove] = mProd[i];
+ }
+ idProd[mult - 1] = idL1;
+ idProd[mult] = idL2;
+ mProd[mult - 1] = mL1;
+ mProd[mult] = mL2;
+ }
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Set colour flow and scale in a decay explicitly to partons.
+
+bool ParticleDecays::setColours(Event& event) {
+
+ // Decay to q qbar (or qbar q).
+ if (meMode == 91 && idProd[1] > 0 && idProd[1] < 9) {
+ int newCol = event.nextColTag();
+ cols[1] = newCol;
+ acols[2] = newCol;
+ } else if (meMode == 91 && idProd[1] < 0 && idProd[1] > -9) {
+ int newCol = event.nextColTag();
+ cols[2] = newCol;
+ acols[1] = newCol;
+
+ // Decay to g g.
+ } else if (meMode == 91 && idProd[1] == 21) {
+ int newCol1 = event.nextColTag();
+ int newCol2 = event.nextColTag();
+ cols[1] = newCol1;
+ acols[1] = newCol2;
+ cols[2] = newCol2;
+ acols[2] = newCol1;
+
+ // Decay to g g g.
+ } else if (meMode == 92 && idProd[1] == 21 && idProd[2] == 21
+ && idProd[3] == 21) {
+ int newCol1 = event.nextColTag();
+ int newCol2 = event.nextColTag();
+ int newCol3 = event.nextColTag();
+ cols[1] = newCol1;
+ acols[1] = newCol2;
+ cols[2] = newCol2;
+ acols[2] = newCol3;
+ cols[3] = newCol3;
+ acols[3] = newCol1;
+
+ // Decay to g g gamma: locate which is gamma.
+ } else if (meMode == 92) {
+ int iGlu1 = (idProd[1] == 21) ? 1 : 3;
+ int iGlu2 = (idProd[2] == 21) ? 2 : 3;
+ int newCol1 = event.nextColTag();
+ int newCol2 = event.nextColTag();
+ cols[iGlu1] = newCol1;
+ acols[iGlu1] = newCol2;
+ cols[iGlu2] = newCol2;
+ acols[iGlu2] = newCol1;
+
+ // Unknown decay mode means failure.
+ } else return false;
+
+ // Set maximum scale to be mass of decaying particle.
+ double scale = mProd[0];
+ for (int i = 1; i <= mult; ++i) event[iProd[i]].scale(scale);
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
--- /dev/null
+// PartonDistributions.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the PDF,
+// GRV94L, CTEQ5L, LHAPDF and Lepton classes.
+
+#include "PartonDistributions.h"
+#include "LHAPDFInterface.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Base class for parton distribution functions.
+
+//*********
+
+// Standard parton densities.
+
+double PDF::xf(int id, double x, double Q2) {
+
+ // Need to update if flavour, x or Q2 changed.
+ // Use idSav = 9 to indicate that ALL flavours are up-to-date.
+ // Assume that flavour and antiflavour always updated simultaneously.
+ if ( (abs(idSav) != abs(id) && idSav != 9) || x != xSav || Q2 != Q2Sav)
+ {idSav = id; xfUpdate(id, x, Q2); xSav = x; Q2Sav = Q2;}
+
+ // Baryon beam.
+ if (abs(idBeam) > 100) {
+ int idNow = (idBeam > 0) ? id : -id;
+ int idAbs = abs(id);
+ if (idNow == 0 || idAbs == 21) return max(0., xg);
+ if (idNow == 1) return max(0., xd);
+ if (idNow == -1) return max(0., xdbar);
+ if (idNow == 2) return max(0., xu);
+ if (idNow == -2) return max(0., xubar);
+ if (idAbs == 3) return max(0., xs);
+ if (idAbs == 4) return max(0., xc);
+ if (idAbs == 5) return max(0., xb);
+ return 0.;
+
+ // Lepton beam.
+ } else {
+ if (id == idBeam ) return max(0., xlepton);
+ if (abs(id) == 22) return max(0., xgamma);
+ return 0.;
+ }
+
+}
+
+//*********
+
+// Only valence part of parton densities.
+
+double PDF::xfVal(int id, double x, double Q2) {
+
+ // Need to update if flavour, x or Q2 changed.
+ // Use idSav = 9 to indicate that ALL flavours are up-to-date.
+ // Assume that flavour and antiflavour always updated simultaneously.
+ if ( (abs(idSav) != abs(id) && idSav != 9) || x != xSav || Q2 != Q2Sav)
+ {idSav = id; xfUpdate(id, x, Q2); xSav = x; Q2Sav = Q2;}
+
+ // Baryon beam.
+ if (abs(idBeam) > 100) {
+ int idNow = (idBeam > 0) ? id : -id;
+ if (idNow == 1) return max(0., xdVal);
+ if (idNow == 2) return max(0., xuVal);
+ return 0.;
+
+ // Lepton beam.
+ } else {
+ if (id == idBeam) return max(0., xlepton);
+ return 0.;
+ }
+
+}
+
+//*********
+
+// Only sea part of parton densities.
+
+double PDF::xfSea(int id, double x, double Q2) {
+
+ // Need to update if flavour, x or Q2 changed.
+ // Use idSav = 9 to indicate that ALL flavours are up-to-date.
+ // Assume that flavour and antiflavour always updated simultaneously.
+ if ( (abs(idSav) != abs(id) && idSav != 9) || x != xSav || Q2 != Q2Sav)
+ {idSav = id; xfUpdate(id, x, Q2); xSav = x; Q2Sav = Q2;}
+
+ // Baryon beam.
+ if (abs(idBeam) > 100) {
+ int idNow = (idBeam > 0) ? id : -id;
+ int idAbs = abs(id);
+ if (idNow == 0 || idAbs == 21) return max(0., xg);
+ if (idNow == 1) return max(0., xdSea);
+ if (idNow == -1) return max(0., xdbar);
+ if (idNow == 2) return max(0., xuSea);
+ if (idNow == -2) return max(0., xubar);
+ if (idAbs == 3) return max(0., xs);
+ if (idAbs == 4) return max(0., xc);
+ if (idAbs == 5) return max(0., xb);
+ if (idAbs == 5) return max(0., xb);
+ return 0.;
+
+ // Lepton beam.
+ } else {
+ if (abs(id) == 22) return max(0., xgamma);
+ return 0.;
+ }
+
+}
+
+//**************************************************************************
+
+// Gives the GRV 94 L (leading order) parton distribution function set
+// in parametrized form. Authors: M. Glueck, E. Reya and A. Vogt.
+// Ref: M. Glueck, E. Reya and A. Vogt, Z.Phys. C67 (1995) 433.
+
+void GRV94L::xfUpdate(int id, double x, double Q2) {
+
+ // Common expressions.
+ double mu2 = 0.23;
+ double lam2 = 0.2322 * 0.2322;
+ double s = log (log(Q2/lam2) / log(mu2/lam2));
+ double ds = sqrt(s);
+ double s2 = s * s;
+ double s3 = s2 * s;
+
+ // uv :
+ double nu = 2.284 + 0.802 * s + 0.055 * s2;
+ double aku = 0.590 - 0.024 * s;
+ double bku = 0.131 + 0.063 * s;
+ double au = -0.449 - 0.138 * s - 0.076 * s2;
+ double bu = 0.213 + 2.669 * s - 0.728 * s2;
+ double cu = 8.854 - 9.135 * s + 1.979 * s2;
+ double du = 2.997 + 0.753 * s - 0.076 * s2;
+ double uv = grvv (x, nu, aku, bku, au, bu, cu, du);
+
+ // dv :
+ double nd = 0.371 + 0.083 * s + 0.039 * s2;
+ double akd = 0.376;
+ double bkd = 0.486 + 0.062 * s;
+ double ad = -0.509 + 3.310 * s - 1.248 * s2;
+ double bd = 12.41 - 10.52 * s + 2.267 * s2;
+ double cd = 6.373 - 6.208 * s + 1.418 * s2;
+ double dd = 3.691 + 0.799 * s - 0.071 * s2;
+ double dv = grvv (x, nd, akd, bkd, ad, bd, cd, dd);
+
+ // udb :
+ double alx = 1.451;
+ double bex = 0.271;
+ double akx = 0.410 - 0.232 * s;
+ double bkx = 0.534 - 0.457 * s;
+ double agx = 0.890 - 0.140 * s;
+ double bgx = -0.981;
+ double cx = 0.320 + 0.683 * s;
+ double dx = 4.752 + 1.164 * s + 0.286 * s2;
+ double ex = 4.119 + 1.713 * s;
+ double esx = 0.682 + 2.978 * s;
+ double udb = grvw (x, s, alx, bex, akx, bkx, agx, bgx, cx,
+ dx, ex, esx);
+
+ // del :
+ double ne = 0.082 + 0.014 * s + 0.008 * s2;
+ double ake = 0.409 - 0.005 * s;
+ double bke = 0.799 + 0.071 * s;
+ double ae = -38.07 + 36.13 * s - 0.656 * s2;
+ double be = 90.31 - 74.15 * s + 7.645 * s2;
+ double ce = 0.;
+ double de = 7.486 + 1.217 * s - 0.159 * s2;
+ double del = grvv (x, ne, ake, bke, ae, be, ce, de);
+
+ // sb :
+ double sts = 0.;
+ double als = 0.914;
+ double bes = 0.577;
+ double aks = 1.798 - 0.596 * s;
+ double as = -5.548 + 3.669 * ds - 0.616 * s;
+ double bs = 18.92 - 16.73 * ds + 5.168 * s;
+ double dst = 6.379 - 0.350 * s + 0.142 * s2;
+ double est = 3.981 + 1.638 * s;
+ double ess = 6.402;
+ double sb = grvs (x, s, sts, als, bes, aks, as, bs, dst, est, ess);
+
+ // cb :
+ double stc = 0.888;
+ double alc = 1.01;
+ double bec = 0.37;
+ double akc = 0.;
+ double ac = 0.;
+ double bc = 4.24 - 0.804 * s;
+ double dct = 3.46 - 1.076 * s;
+ double ect = 4.61 + 1.49 * s;
+ double esc = 2.555 + 1.961 * s;
+ double chm = grvs (x, s, stc, alc, bec, akc, ac, bc, dct, ect, esc);
+
+ // bb :
+ double stb = 1.351;
+ double alb = 1.00;
+ double beb = 0.51;
+ double akb = 0.;
+ double ab = 0.;
+ double bb = 1.848;
+ double dbt = 2.929 + 1.396 * s;
+ double ebt = 4.71 + 1.514 * s;
+ double esb = 4.02 + 1.239 * s;
+ double bot = grvs (x, s, stb, alb, beb, akb, ab, bb, dbt, ebt, esb);
+
+ // gl :
+ double alg = 0.524;
+ double beg = 1.088;
+ double akg = 1.742 - 0.930 * s;
+ double bkg = - 0.399 * s2;
+ double ag = 7.486 - 2.185 * s;
+ double bg = 16.69 - 22.74 * s + 5.779 * s2;
+ double cg = -25.59 + 29.71 * s - 7.296 * s2;
+ double dg = 2.792 + 2.215 * s + 0.422 * s2 - 0.104 * s3;
+ double eg = 0.807 + 2.005 * s;
+ double esg = 3.841 + 0.316 * s;
+ double gl = grvw (x, s, alg, beg, akg, bkg, ag, bg, cg,
+ dg, eg, esg);
+
+ // Update values
+ xg = gl;
+ xu = uv + 0.5*(udb - del);
+ xd = dv + 0.5*(udb + del);
+ xubar = 0.5*(udb - del);
+ xdbar = 0.5*(udb + del);
+ xs = sb;
+ xc = chm;
+ xb = bot;
+
+ // Subdivision of valence and sea.
+ xuVal = uv;
+ xuSea = xubar;
+ xdVal = dv;
+ xdSea = xdbar;
+
+ // idSav = 9 to indicate that all flavours reset. id change dummy.
+ idSav = 9;
+ id = 0;
+
+}
+
+//*********
+
+double GRV94L::grvv (double x, double n, double ak, double bk, double a,
+ double b, double c, double d) {
+
+ double dx = sqrt(x);
+ return n * pow(x, ak) * (1. + a * pow(x, bk) + x * (b + c * dx)) *
+ pow(1. - x, d);
+
+}
+
+//*********
+
+double GRV94L::grvw (double x, double s, double al, double be, double ak,
+ double bk, double a, double b, double c, double d, double e, double es) {
+
+ double lx = log(1./x);
+ return (pow(x, ak) * (a + x * (b + x * c)) * pow(lx, bk) + pow(s, al)
+ * exp(-e + sqrt(es * pow(s, be) * lx))) * pow(1. - x, d);
+
+}
+
+//*********
+
+double GRV94L::grvs (double x, double s, double sth, double al, double be,
+ double ak, double ag, double b, double d, double e, double es) {
+
+ if(s <= sth) {
+ return 0.;
+ } else {
+ double dx = sqrt(x);
+ double lx = log(1./x);
+ return pow(s - sth, al) / pow(lx, ak) * (1. + ag * dx + b * x) *
+ pow(1. - x, d) * exp(-e + sqrt(es * pow(s, be) * lx));
+ }
+
+}
+
+//**************************************************************************
+
+// Gives the CTEQ 5 L (leading order) parton distribution function set
+// in parametrized form. Parametrization by J. Pumplin.
+// Ref: CTEQ Collaboration, H.L. Lai et al., Eur.Phys.J. C12 (2000) 375.
+
+// The range of (x, Q) covered by this parametrization of the QCD
+// evolved parton distributions is 1E-6 < x < 1, 1.1 GeV < Q < 10 TeV.
+// In the current implementation, densities are frozen at borders.
+
+void CTEQ5L::xfUpdate(int id, double x, double Q2) {
+
+ // Constrain x and Q2 to range for which parametrization is valid.
+ double Q = sqrt( max( 1., min( 1e8, Q2) ) );
+ x = max( 1e-6, min( 1.-1e-10, x) );
+
+ // Derived kinematical quantities.
+ double y = - log(x);
+ double u = log( x / 0.00001);
+ double x1 = 1. - x;
+ double x1L = log(1. - x);
+ double sumUbarDbar = 0.;
+
+ // Parameters of parametrizations.
+ const double Qmin[8] = { 0., 0., 0., 0., 0., 0., 1.3, 4.5};
+ const double alpha[8] = { 0.2987216, 0.3407552, 0.4491863, 0.2457668,
+ 0.5293999, 0.3713141, 0.03712017, 0.004952010 };
+ const double ut1[8] = { 4.971265, 2.612618, -0.4656819, 3.862583,
+ 0.1895615, 3.753257, 4.400772, 5.562568 };
+ const double ut2[8] = { -1.105128, -1.258304e5, -274.2390, -1.265969,
+ -3.069097, -1.113085, -1.356116, -1.801317 };
+ const double am[8][9][3] = {
+ // d.
+ { { 0.5292616E+01, -0.2751910E+01, -0.2488990E+01 },
+ { 0.9714424E+00, 0.1011827E-01, -0.1023660E-01 },
+ { -0.1651006E+02, 0.7959721E+01, 0.8810563E+01 },
+ { -0.1643394E+02, 0.5892854E+01, 0.9348874E+01 },
+ { 0.3067422E+02, 0.4235796E+01, -0.5112136E+00 },
+ { 0.2352526E+02, -0.5305168E+01, -0.1169174E+02 },
+ { -0.1095451E+02, 0.3006577E+01, 0.5638136E+01 },
+ { -0.1172251E+02, -0.2183624E+01, 0.4955794E+01 },
+ { 0.1662533E-01, 0.7622870E-02, -0.4895887E-03 } },
+ // u.
+ { { 0.9905300E+00, -0.4502235E+00, 0.1624441E+00 },
+ { 0.8867534E+00, 0.1630829E-01, -0.4049085E-01 },
+ { 0.8547974E+00, 0.3336301E+00, 0.1371388E+00 },
+ { 0.2941113E+00, -0.1527905E+01, 0.2331879E+00 },
+ { 0.3384235E+02, 0.3715315E+01, 0.8276930E+00 },
+ { 0.6230115E+01, 0.3134639E+01, -0.1729099E+01 },
+ { -0.1186928E+01, -0.3282460E+00, 0.1052020E+00 },
+ { -0.8545702E+01, -0.6247947E+01, 0.3692561E+01 },
+ { 0.1724598E-01, 0.7120465E-02, 0.4003646E-04 } },
+ // g.
+ { { 0.1193572E+03, -0.3886845E+01, -0.1133965E+01 },
+ { -0.9421449E+02, 0.3995885E+01, 0.1607363E+01 },
+ { 0.4206383E+01, 0.2485954E+00, 0.2497468E+00 },
+ { 0.1210557E+03, -0.3015765E+01, -0.1423651E+01 },
+ { -0.1013897E+03, -0.7113478E+00, 0.2621865E+00 },
+ { -0.1312404E+01, -0.9297691E+00, -0.1562531E+00 },
+ { 0.1627137E+01, 0.4954111E+00, -0.6387009E+00 },
+ { 0.1537698E+00, -0.2487878E+00, 0.8305947E+00 },
+ { 0.2496448E-01, 0.2457823E-02, 0.8234276E-03 } },
+ // ubar + dbar.
+ { { 0.2647441E+02, 0.1059277E+02, -0.9176654E+00 },
+ { 0.1990636E+01, 0.8558918E-01, 0.4248667E-01 },
+ { -0.1476095E+02, -0.3276255E+02, 0.1558110E+01 },
+ { -0.2966889E+01, -0.3649037E+02, 0.1195914E+01 },
+ { -0.1000519E+03, -0.2464635E+01, 0.1964849E+00 },
+ { 0.3718331E+02, 0.4700389E+02, -0.2772142E+01 },
+ { -0.1872722E+02, -0.2291189E+02, 0.1089052E+01 },
+ { -0.1628146E+02, -0.1823993E+02, 0.2537369E+01 },
+ { -0.1156300E+01, -0.1280495E+00, 0.5153245E-01 } },
+ // dbar/ubar.
+ { { -0.6556775E+00, 0.2490190E+00, 0.3966485E-01 },
+ { 0.1305102E+01, -0.1188925E+00, -0.4600870E-02 },
+ { -0.2371436E+01, 0.3566814E+00, -0.2834683E+00 },
+ { -0.6152826E+01, 0.8339877E+00, -0.7233230E+00 },
+ { -0.8346558E+01, 0.2892168E+01, 0.2137099E+00 },
+ { 0.1279530E+02, 0.1021114E+00, 0.5787439E+00 },
+ { 0.5858816E+00, -0.1940375E+01, -0.4029269E+00 },
+ { -0.2795725E+02, -0.5263392E+00, 0.1290229E+01 },
+ { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } },
+ // sbar.
+ { { 0.1580931E+01, -0.2273826E+01, -0.1822245E+01 },
+ { 0.2702644E+01, 0.6763243E+00, 0.7231586E-02 },
+ { -0.1857924E+02, 0.3907500E+01, 0.5850109E+01 },
+ { -0.3044793E+02, 0.2639332E+01, 0.5566644E+01 },
+ { -0.4258011E+01, -0.5429244E+01, 0.4418946E+00 },
+ { 0.3465259E+02, -0.5532604E+01, -0.4904153E+01 },
+ { -0.1658858E+02, 0.2923275E+01, 0.2266286E+01 },
+ { -0.1149263E+02, 0.2877475E+01, -0.7999105E+00 },
+ { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } },
+ // cbar.
+ { { -0.8293661E+00, -0.3982375E+01, -0.6494283E-01 },
+ { 0.2754618E+01, 0.8338636E+00, -0.6885160E-01 },
+ { -0.1657987E+02, 0.1439143E+02, -0.6887240E+00 },
+ { -0.2800703E+02, 0.1535966E+02, -0.7377693E+00 },
+ { -0.6460216E+01, -0.4783019E+01, 0.4913297E+00 },
+ { 0.3141830E+02, -0.3178031E+02, 0.7136013E+01 },
+ { -0.1802509E+02, 0.1862163E+02, -0.4632843E+01 },
+ { -0.1240412E+02, 0.2565386E+02, -0.1066570E+02 },
+ { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } },
+ // bbar.
+ { { -0.6031237E+01, 0.1992727E+01, -0.1076331E+01 },
+ { 0.2933912E+01, 0.5839674E+00, 0.7509435E-01 },
+ { -0.8284919E+01, 0.1488593E+01, -0.8251678E+00 },
+ { -0.1925986E+02, 0.2805753E+01, -0.3015446E+01 },
+ { -0.9480483E+01, -0.9767837E+00, -0.1165544E+01 },
+ { 0.2193195E+02, -0.1788518E+02, 0.9460908E+01 },
+ { -0.1327377E+02, 0.1201754E+02, -0.6277844E+01 },
+ { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 },
+ { 0.0000000E+00, 0.0000000E+00, 0.0000000E+00 } } };
+
+ // Loop over 8 different parametrizations. Check if inside allowed region.
+ for (int i = 0; i < 8; ++i) {
+ double answer = 0.;
+ if (Q > max(Qmin[i], alpha[i])) {
+
+ // Evaluate answer.
+ double tmp = log(Q / alpha[i]);
+ double sb = log(tmp);
+ double sb1 = sb - 1.2;
+ double sb2 = sb1*sb1;
+ double af[9];
+ for (int j = 0; j < 9; ++j)
+ af[j] = am[i][j][0] + sb1 * am[i][j][1] + sb2 * am[i][j][2];
+ double part1 = af[1] * pow( y, 1. + 0.01 * af[4]) * (1. + af[8] * u);
+ double part2 = af[0] * x1 + af[3] * x;
+ double part3 = x * x1 * (af[5] + af[6] * x1 + af[7] * x * x1);
+ double part4 = (ut2[i] < -100.) ? ut1[i] * x1L + af[2] * x1L
+ : ut1[i] * x1L + af[2] * log(x1 + exp(ut2[i]));
+ answer = x * exp( part1 + part2 + part3 + part4);
+ answer *= 1. - Qmin[i] / Q;
+ }
+
+ // Store results.
+ if (i == 0) xd = x * answer;
+ else if (i == 1) xu = x * answer;
+ else if (i == 2) xg = x * answer;
+ else if (i == 3) sumUbarDbar = x * answer;
+ else if (i == 4) { xubar = sumUbarDbar / (1. + answer);
+ xdbar = sumUbarDbar * answer / (1. + answer); }
+ else if (i == 5) xs = x * answer;
+ else if (i == 6) xc = x * answer;
+ else if (i == 7) xb = x * answer;
+ }
+
+ // Subdivision of valence and sea.
+ xuVal = xu - xubar;
+ xuSea = xubar;
+ xdVal = xd - xdbar;
+ xdSea = xdbar;
+
+ // idSav = 9 to indicate that all flavours reset. id change is dummy here.
+ idSav = 9;
+ id = 0;
+
+}
+
+//**************************************************************************
+
+// Interface to the LHAPDF library.
+
+//*********
+
+// Definitions of static variables.
+
+string LHAPDF::latestSetName = " ";
+int LHAPDF::latestMember = -1;
+int LHAPDF::latestNSet = 0;
+
+//*********
+
+// Initialize a parton density function from LHAPDF.
+
+void LHAPDF::init(string setName, int member, Info* infoPtr) {
+
+ // If already initialized then need not do anything.
+ if (setName == latestSetName && member == latestMember
+ && nSet == latestNSet) return;
+
+ // Initialize set. If first character is '/' then assume that name
+ // is given with path, else not.
+ if (setName[0] == '/') LHAPDFInterface::initPDFsetM( nSet, setName);
+ else LHAPDFInterface::initPDFsetByNameM( nSet, setName);
+
+ // Check that not dummy library was linked and put nSet negative.
+ isSet = (nSet >= 0);
+ if (!isSet) {
+ if (infoPtr > 0) infoPtr->errorMsg("Error from LHAPDF::init: "
+ "you try to use LHAPDF but did not link it");
+ else cout << "Error from LHAPDF::init: you try to use LHAPDF "
+ << "but did not link it" << endl;
+ }
+
+ // Initialize member.
+ LHAPDFInterface::initPDFM(nSet, member);
+
+ // Do not collect statistics on under/overflow to save time and space.
+ LHAPDFInterface::setPDFparm( "NOSTAT" );
+ LHAPDFInterface::setPDFparm( "LOWKEY" );
+
+ // Save values to avoid unnecessary reinitializations.
+ latestSetName = setName;
+ latestMember = member;
+ latestNSet = nSet;
+
+}
+
+//*********
+
+// Allow optional extrapolation beyond boundaries.
+
+void LHAPDF::setExtrapolate(bool extrapol) {
+
+ LHAPDFInterface::setPDFparm( (extrapol) ? "EXTRAPOLATE" : "18" );
+
+}
+
+//*********
+
+// Give the parton distribution function set from LHAPDF.
+
+void LHAPDF::xfUpdate(int , double x, double Q2) {
+
+ // Let LHAPDF do the evaluation of parton densities.
+ double Q = sqrt( max( 0., Q2));
+ LHAPDFInterface::evolvePDFM( nSet, x, Q, xfArray);
+
+ // Update values.
+ xg = xfArray[6];
+ xu = xfArray[8];
+ xd = xfArray[7];
+ xubar = xfArray[4];
+ xdbar = xfArray[5];
+ xs = xfArray[9];
+ xc = xfArray[10];
+ xb = xfArray[11];
+
+ // Subdivision of valence and sea.
+ xuVal = xu - xubar;
+ xuSea = xubar;
+ xdVal = xd - xdbar;
+ xdSea = xdbar;
+
+ // idSav = 9 to indicate that all flavours reset.
+ idSav = 9;
+
+}
+
+//**************************************************************************
+
+// Gives electron (or muon, or tau) parton distribution.
+
+// Constant. alphaEM(0) could be taken from settings but safer this way.
+const double Lepton::ALPHAEM = 0.00729735;
+
+void Lepton::xfUpdate(int id, double x, double Q2) {
+
+ // Squared mass of lepton species: electron, muon, tau.
+ if (!isInit) {
+ m2Lep = pow2( ParticleDataTable::m0(idBeam) );
+ isInit = true;
+ }
+
+ // Electron inside electron, see R. Kleiss et al., in Z physics at
+ // LEP 1, CERN 89-08, p. 34
+ double xLog = log(max(1e-10,x));
+ double xMinusLog = log( max(1e-10, 1. - x) );
+ double Q2Log = log( max(3., Q2/m2Lep) );
+ double beta = (ALPHAEM / M_PI) * (Q2Log - 1.);
+ double delta = 1. + (ALPHAEM / M_PI) * (1.5 * Q2Log + 1.289868)
+ + pow2(ALPHAEM / M_PI) * (-2.164868 * Q2Log*Q2Log
+ + 9.840808 * Q2Log - 10.130464);
+ double fPrel = beta * pow(1. - x, beta - 1.) * sqrtpos( delta )
+ - 0.5 * beta * (1. + x) + 0.125 * beta*beta * ( (1. + x)
+ * (-4. * xMinusLog + 3. * xLog) - 4. * xLog / (1. - x) - 5. - x);
+
+ // Zero distribution for very large x and rescale it for intermediate.
+ if (x > 1. - 1e-10) fPrel = 0.;
+ else if (x > 1. - 1e-7) fPrel *= pow(1000.,beta) / (pow(1000.,beta) - 1.);
+ xlepton = x * fPrel;
+
+ // Photon inside electron (one possible scheme - primitive).
+ xgamma = (0.5 * ALPHAEM / M_PI) * Q2Log * (1. + pow2(1. - x));
+
+ // idSav = 9 to indicate that all flavours reset. id change is dummy here.
+ idSav = 9;
+ id = 0;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// PartonLevel.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the PartonLevel class.
+
+#include "PartonLevel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The PartonLevel class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maximum number of tries to produce parton level from given input..
+const int PartonLevel::NTRY = 10;
+
+//*********
+
+// Main routine to initialize the parton-level generation process.
+
+bool PartonLevel::init( Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn, SigmaTotal* sigmaTotPtr,
+ TimeShower* timesDecPtrIn, TimeShower* timesPtrIn,
+ SpaceShower* spacePtrIn, UserHooks* userHooksPtrIn) {
+
+ // Store input pointers and modes for future use.
+ infoPtr = infoPtrIn;
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+ timesDecPtr = timesDecPtrIn;
+ timesPtr = timesPtrIn;
+ spacePtr = spacePtrIn;
+ userHooksPtr = userHooksPtrIn;
+
+ // Main flags.
+ doMI = Settings::flag("PartonLevel:MI");
+ doISR = Settings::flag("PartonLevel:ISR");
+ bool FSR = Settings::flag("PartonLevel:FSR");
+ bool FSRinProcess = Settings::flag("PartonLevel:FSRinProcess");
+ bool interleaveFSR = Settings::flag("TimeShower:interleave");
+ doFSRduringProcess = FSR && FSRinProcess && interleaveFSR;
+ doFSRafterProcess = FSR && FSRinProcess && !interleaveFSR;
+ doFSRinResonances = FSR && Settings::flag("PartonLevel:FSRinResonances");
+ doRemnants = true;
+ doSecondHard = Settings::flag("SecondHard:generate");
+
+ // Need MI initialization for minbias processes, even if only first MI.
+ // But no need to initialize MI if never going to use it.
+ doMIinit = doMI;
+ if (Settings::flag("SoftQCD:minBias") || Settings::flag("SoftQCD:all"))
+ doMIinit = true;
+ if (!Settings::flag("PartonLevel:all")) doMIinit = false;
+
+ // Flag if lepton beams, and if non-resolved ones. May change main flags.
+ hasLeptonBeams = ( beamAPtr->isLepton() || beamBPtr->isLepton() );
+ hasPointLeptons = ( hasLeptonBeams
+ && (beamAPtr->isUnresolved() || beamBPtr->isUnresolved() ) );
+ if (hasLeptonBeams) {
+ doMI = false;
+ doMIinit = false;
+ }
+ if (hasPointLeptons) {
+ doISR = false;
+ doRemnants = false;
+ }
+
+ // Possibility to allow user veto during evolution.
+ canVetoPT = (userHooksPtr > 0) ? userHooksPtr->canVetoPT() : false;
+ pTvetoPT = (canVetoPT) ? userHooksPtr->scaleVetoPT() : -1.;
+ canVetoStep = (userHooksPtr > 0) ? userHooksPtr->canVetoStep() : false;
+ nVetoStep = (canVetoStep) ? userHooksPtr->numberVetoStep() : -1;
+
+ // Set info and initialize the respective program elements.
+ timesPtr->init( beamAPtr, beamBPtr);
+ if (doISR) spacePtr->init( beamAPtr, beamBPtr);
+ doMI = multi.init( doMIinit, infoPtr, beamAPtr, beamBPtr, sigmaTotPtr);
+ remnants.init( infoPtr, beamAPtr, beamBPtr);
+
+ // Succeeded. (Check return values from other classes??)
+ return true;
+}
+
+//*********
+
+// Main routine to do the parton-level evolution.
+
+bool PartonLevel::next( Event& process, Event& event) {
+
+ // Special case if unresolved = elastic/diffractive event.
+ if (!infoPtr->isResolved()) return setupUnresolvedSys( process, event);
+
+ // Special case if minimum bias: do hardest interaction.
+ if (doMIinit) multi.clear();
+ if (infoPtr->isMinBias()) {
+ multi.pTfirst();
+ multi.setupFirstSys( process);
+ }
+
+ // Allow up to ten tries; failure possible for beam remnants.
+ // Main cause: inconsistent colour flow at the end of the day.
+ bool physical = true;
+ int nRad = 0;
+ for (int iTry = 0; iTry < NTRY; ++ iTry) {
+
+ // Reset flag, counters and max scales.
+ physical = true;
+ nMI = (doSecondHard) ? 2 : 1;
+ nISR = 0;
+ nFSRinProc = 0;
+ nFSRinRes = 0;
+ nISRhard = 0;
+ nFSRhard = 0;
+ pTsaveMI = 0.;
+ pTsaveISR = 0.;
+ pTsaveFSR = 0.;
+
+ // Identify hard interaction system for showers.
+ setupHardSys( process, event);
+
+ // Check matching of process scale to maximum ISR/MI scales.
+ double Q2Fac = infoPtr->Q2Fac();
+ double Q2Ren = infoPtr->Q2Ren();
+ bool limitPTmaxISR = (doISR)
+ ? spacePtr->limitPTmax( event, Q2Fac, Q2Ren) : false;
+ bool limitPTmaxMI = (doMI) ? multi.limitPTmax( event) : false;
+
+ // Set hard scale, maximum for showers and multiple interactions,
+ double pTscale = process.scale();
+ if (doSecondHard) pTscale = max( pTscale, process.scaleSecond() );
+ double pTmaxMI = (limitPTmaxMI) ? pTscale : infoPtr->eCM();
+ double pTmaxISR = (limitPTmaxISR) ? spacePtr->enhancePTmax() * pTscale
+ : infoPtr->eCM();
+ double pTmaxFSR = timesPtr->enhancePTmax() * pTscale;
+ double pTmax = max( pTmaxMI, max( pTmaxISR, pTmaxFSR) );
+ pTsaveMI = pTmaxMI;
+ pTsaveISR = pTmaxISR;
+ pTsaveFSR = pTmaxFSR;
+
+ // Prepare the classes to begin the generation.
+ if (doMI) multi.prepare( pTmaxMI);
+ if (doISR) spacePtr->prepare( 0, event, limitPTmaxISR);
+ if (doFSRduringProcess) timesPtr->prepare( 0, event);
+ if (doSecondHard && doISR) spacePtr->prepare( 1, event, limitPTmaxISR);
+ if (doSecondHard && doFSRduringProcess) timesPtr->prepare( 1, event);
+
+ // Set up initial veto scale.
+ doVeto = false;
+ double pTveto = pTvetoPT;
+ typeLatest = 0;
+
+ // Begin evolution down in pT from hard pT scale.
+ do {
+
+ typeVetoStep = 0;
+ nRad = nISR + nFSRinProc;
+
+ // Find next pT value for FSR, MI and ISR.
+ // Order calls to minimize time expenditure.
+ double pTgen = 0.;
+ double pTtimes = (doFSRduringProcess)
+ ? timesPtr->pTnext( event, pTmaxFSR, pTgen) : -1.;
+ pTgen = max( pTgen, pTtimes);
+ double pTmulti = (doMI)
+ ? multi.pTnext( pTmaxMI, pTgen) : -1.;
+ pTgen = max( pTgen, pTmulti);
+ double pTspace = (doISR)
+ ? spacePtr->pTnext( event, pTmaxISR, pTgen, nRad) : -1.;
+
+ // Allow a user veto. Only do it once, so remember to change pTveto.
+ if (pTveto > 0. && pTveto > pTmulti && pTveto > pTspace
+ && pTveto > pTtimes) {
+ pTveto = -1.;
+ doVeto = userHooksPtr->doVetoPT( typeLatest, event);
+ // Abort event if vetoed.
+ if (doVeto) return false;
+ }
+
+ // Do a multiple interaction (if allowed).
+ if (pTmulti > 0. && pTmulti > pTspace && pTmulti > pTtimes) {
+ multi.scatter( event);
+ typeLatest = 1;
+ ++nMI;
+ if (doISR) spacePtr->prepare( nMI - 1, event);
+ if (doFSRduringProcess) timesPtr->prepare( nMI - 1, event);
+ pTmaxMI = pTmulti;
+ pTmaxISR = min( pTmulti, pTmaxISR);
+ pTmaxFSR = min( pTmulti, pTmaxFSR);
+ pTmax = pTmulti;
+ }
+
+ // Do an initial-state emission (if allowed).
+ else if (pTspace > 0. && pTspace > pTtimes) {
+ if (spacePtr->branch( event)) {
+ typeLatest = 2;
+ iSysNow = spacePtr->system();
+ ++nISR;
+ if (iSysNow == 0) ++nISRhard;
+ if (doFSRduringProcess) timesPtr->update( iSysNow, event);
+ if (canVetoStep && iSysNow == 0 && nISRhard <= nVetoStep)
+ typeVetoStep = 2;
+ }
+ pTmaxMI = min( pTspace, pTmaxMI);
+ pTmaxISR = pTspace;
+ pTmaxFSR = min( pTspace, pTmaxFSR);
+ pTmax = pTspace;
+ }
+
+ // Do a final-state emission (if allowed).
+ else if (pTtimes > 0.) {
+ if (timesPtr->branch( event)) {
+ typeLatest = 3;
+ iSysNow = timesPtr->system();
+ ++nFSRinProc;
+ if (iSysNow == 0) ++nFSRhard;
+ if (doISR) spacePtr->update( iSysNow, event);
+ if (canVetoStep && iSysNow == 0 && nFSRhard <= nVetoStep)
+ typeVetoStep = 3;
+ }
+ pTmaxMI = min( pTtimes, pTmaxMI);
+ pTmaxISR = min( pTtimes, pTmaxISR);
+ pTmaxFSR = pTtimes;
+ pTmax = pTtimes;
+ }
+
+ // If no pT scales above zero then nothing to be done.
+ else pTmax = 0.;
+
+ // Optionally check for a veto after the first few emissions.
+ if (typeVetoStep > 0) {
+ doVeto = userHooksPtr->doVetoStep( typeVetoStep, nISRhard,
+ nFSRhard, event);
+ // Abort event if vetoed.
+ if (doVeto) return false;
+ }
+
+ // Keep on evolving until nothing is left to be done.
+ } while (pTmax > 0.);
+
+ // Do all final-state emissions if not already considered above.
+ if (doFSRafterProcess) {
+
+ // Find largest scale for final partons.
+ pTmax = 0.;
+ for (int i = 0; i < event.size(); ++i)
+ if (event[i].isFinal() && event[i].scale() > pTmax)
+ pTmax = event[i].scale();
+ pTsaveFSR = pTmax;
+
+ // Prepare all subsystems for evolution.
+ for (int iSys = 0; iSys < event.sizeSystems(); ++iSys)
+ timesPtr->prepare( iSys, event);
+
+ // Set up initial veto scale.
+ doVeto = false;
+ pTveto = pTvetoPT;
+
+ // Begin evolution down in pT from hard pT scale.
+ do {
+ typeVetoStep = 0;
+ double pTtimes = timesPtr->pTnext( event, pTmax, 0.);
+
+ // Allow a user veto. Only do it once, so remember to change pTveto.
+ if (pTveto > 0. && pTveto > pTtimes) {
+ pTveto = -1.;
+ doVeto = userHooksPtr->doVetoPT( 4, event);
+ // Abort event if vetoed.
+ if (doVeto) return false;
+ }
+
+ // Do a final-state emission (if allowed).
+ if (pTtimes > 0.) {
+ if (timesPtr->branch( event)) {
+ iSysNow = timesPtr->system();
+ ++nFSRinProc;
+ if (iSysNow == 0) ++nFSRhard;
+ if (canVetoStep && iSysNow == 0 && nFSRhard <= nVetoStep)
+ typeVetoStep = 4;
+ }
+ pTmax = pTtimes;
+ }
+
+ // If no pT scales above zero then nothing to be done.
+ else pTmax = 0.;
+
+ // Optionally check for a veto after the first few emissions.
+ if (typeVetoStep > 0) {
+ doVeto = userHooksPtr->doVetoStep( typeVetoStep, nISRhard,
+ nFSRhard, event);
+ // Abort event if vetoed.
+ if (doVeto) return false;
+ }
+
+ // Keep on evolving until nothing is left to be done.
+ } while (pTmax > 0.);
+ }
+
+ // Add beam remnants, including primordial kT kick and colour tracing.
+ if (doRemnants && !remnants.add( event)) physical = false;
+
+ // If no problems then done, else restore and loop.
+ if (physical) break;
+ event.clear();
+ beamAPtr->clear();
+ beamBPtr->clear();
+
+ // End loop over ten tries. Hopefully it worked
+ }
+ if (!physical) return false;
+
+ // Perform showers in resonance decay chains.
+ nFSRinRes = resonanceShowers( process, event);
+
+ // Store event properties.
+ infoPtr->setImpact( multi.bMI(), multi.enhanceMI());
+ infoPtr->setEvolution( pTsaveMI, pTsaveISR, pTsaveFSR,
+ nMI, nISR, nFSRinProc, nFSRinRes);
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Set up the hard process(es), excluding subsequent resonance decays.
+
+void PartonLevel::setupHardSys( Event& process, Event& event) {
+
+ // Incoming partons to hard process are stored in slots 3 and 4.
+ int inP = 3;
+ int inM = 4;
+
+ // If two hard interactions then find where second begins.
+ int iBeginSecond = process.size();
+ if (doSecondHard) {
+ iBeginSecond = 5;
+ while (process[iBeginSecond].status() != -21) ++iBeginSecond;
+ }
+
+ // If incoming partons are massive then recalculate to put them massless.
+ if (process[inP].m() != 0. || process[inM].m() != 0.) {
+ double pPlus = process[inP].pPlus() + process[inM].pPlus();
+ double pMinus = process[inP].pMinus() + process[inM].pMinus();
+ process[inP].pz( 0.5 * pPlus);
+ process[inP].e( 0.5 * pPlus);
+ process[inP].m( 0.);
+ process[inM].pz(-0.5 * pMinus);
+ process[inM].e( 0.5 * pMinus);
+ process[inM].m( 0.);
+ }
+
+ // Add incoming hard-scattering partons to list in beam remnants.
+ double x1 = process[inP].pPlus() / process[0].e();
+ beamAPtr->append( inP, process[inP].id(), x1);
+ double x2 = process[inM].pMinus() / process[0].e();
+ beamBPtr->append( inM, process[inM].id(), x2);
+
+ // Scale. Find whether incoming partons are valence or sea. Store.
+ double scale = process.scale();
+ beamAPtr->xfISR( 0, process[inP].id(), x1, scale*scale);
+ int vsc1 = beamAPtr->pickValSeaComp();
+ beamBPtr->xfISR( 0, process[inM].id(), x2, scale*scale);
+ int vsc2 = beamBPtr->pickValSeaComp();
+ bool isVal1 = (vsc1 == -3);
+ bool isVal2 = (vsc2 == -3);
+ infoPtr->setValence( isVal1, isVal2);
+
+ // Initialize info needed for subsequent sequential decays + showers.
+ nHardDone = 0;
+ iPosBefShow.resize( process.size() );
+
+ // Add the beam and hard subprocess partons to the event record.
+ for (int i = 0; i < iBeginSecond; ++ i) {
+ if (process[i].mother1() > inM) break;
+ event.append(process[i]);
+ iPosBefShow[i] = i;
+
+ // Currently outgoing ones should not count as decayed.
+ if (event[i].status() == -22) {
+ event[i].statusPos();
+ event[i].daughters(0, 0);
+ }
+
+ // Complete task of copying hard subsystem into event record.
+ ++nHardDone;
+ }
+
+ // Store participating partons as first set in list of all systems.
+ event.newSystem();
+ for (int i = inP; i < nHardDone; ++i) event.addToSystem(0, i);
+
+ // Identify second hard process where applicable.
+ // Since internally generated incoming partons are guaranteed massless.
+ if (doSecondHard) {
+ int inP2 = iBeginSecond;
+ int inM2 = iBeginSecond + 1;
+
+ // Add incoming hard-scattering partons to list in beam remnants.
+ // Not valid if not in rest frame??
+ x1 = process[inP2].pPlus() / process[0].e();
+ beamAPtr->append( inP2, process[inP2].id(), x1);
+ x2 = process[inM2].pMinus() / process[0].e();
+ beamBPtr->append( inM2, process[inM2].id(), x2);
+
+ // Find whether incoming partons are valence or sea.
+ scale = process.scaleSecond();
+ beamAPtr->xfISR( 1, process[inP2].id(), x1, scale*scale);
+ beamAPtr->pickValSeaComp();
+ beamBPtr->xfISR( 1, process[inM2].id(), x2, scale*scale);
+ beamBPtr->pickValSeaComp();
+
+ // Add the beam and hard subprocess partons to the event record.
+ for (int i = inP2; i < process.size(); ++ i) {
+ int mother = process[i].mother1();
+ if ( (mother > 2 && mother < inP2) || mother > inM2 ) break;
+ event.append(process[i]);
+ iPosBefShow[i] = i;
+
+ // Currently outgoing ones should not count as decayed.
+ if (event[i].status() == -22) {
+ event[i].statusPos();
+ event[i].daughters(0, 0);
+ }
+
+ // Complete task of copying hard subsystem into event record.
+ ++nHardDone;
+ }
+
+ // Store participating partons as second set in list of all systems.
+ event.newSystem();
+ for (int i = inP2; i < nHardDone; ++i) event.addToSystem(1, i);
+
+ // End code for second hard process.
+ }
+
+ // Update event colour tag to maximum in whole process.
+ int maxColTag = 0;
+ for (int i = 0; i < process.size(); ++ i) {
+ if (process[i].col() > maxColTag) maxColTag = process[i].col();
+ if (process[i].acol() > maxColTag) maxColTag = process[i].acol();
+ }
+ event.initColTag(maxColTag);
+
+ // Copy junctions from process to event.
+ for (int i = 0; i < process.sizeJunction(); ++i)
+ event.appendJunction( process.getJunction(i));
+
+ // Done.
+}
+
+//*********
+
+// Set up an unresolved process, i.e. elastic or diffractive.
+
+bool PartonLevel::setupUnresolvedSys( Event& process, Event& event) {
+
+ // Copy particles from process to event.
+ for (int i = 0; i < process.size(); ++ i) event.append( process[i]);
+
+ // Loop to find diffractively excited beams.
+ for (int i = 0; i < 2; ++i)
+ if ( (i == 0 && infoPtr->isDiffractiveA())
+ || (i == 1 && infoPtr->isDiffractiveB()) ) {
+ int iBeam = i + 3;
+ BeamParticle* beamPtr = (i == 0) ? beamAPtr : beamBPtr;
+
+ // Diffractive mass. Reconstruct boost and rotation to event cm frame.
+ double mDiff = process[iBeam].m();
+ double m2Diff = mDiff*mDiff;
+ double beta = process[iBeam].pAbs() / process[iBeam].e();
+ double theta = process[iBeam].theta();
+ double phi = process[iBeam].phi();
+
+ // Pick quark or gluon kicked out and flavour subdivision.
+ bool gluonIsKicked = beamPtr->pickGluon(mDiff);
+ int id1 = beamPtr->pickValence();
+ int id2 = beamPtr->pickRemnant();
+
+ // Find flavour masses. Scale them down if too big.
+ double m1 = ParticleDataTable::constituentMass(id1);
+ double m2 = ParticleDataTable::constituentMass(id2);
+ if (m1 + m2 > 0.5 * mDiff) {
+ double reduce = 0.5 * mDiff / (m1 + m2);
+ m1 *= reduce;
+ m2 *= reduce;
+ }
+
+ // If quark is kicked out, then trivial kinematics in rest frame.
+ if (!gluonIsKicked) {
+ double pAbs = sqrt( pow2(m2Diff - m1*m1 - m2*m2)
+ - pow2(2. * m1 * m2) ) / (2. * mDiff);
+ double e1 = (m2Diff + m1*m1 - m2*m2) / (2. * mDiff);
+ double e2 = (m2Diff + m2*m2 - m1*m1) / (2. * mDiff);
+ Vec4 p1(0.,0., -pAbs, e1);
+ Vec4 p2(0.,0., pAbs, e2);
+
+ // Boost and rotate to event cm frame.
+ p1.bst(0., 0., beta); p1.rot(theta, phi);
+ p2.bst(0., 0., beta); p2.rot(theta, phi);
+
+ // Set colours.
+ int col1, acol1, col2, acol2;
+ if (ParticleDataTable::colType(id1) == 1) {
+ col1 = event.nextColTag(); acol1 = 0;
+ col2 = 0; acol2 = col1;
+ } else {
+ col1 = 0; acol1 = event.nextColTag();
+ col2 = acol1; acol2 = 0;
+ }
+
+ // Store partons of diffractive system and mark system decayed.
+ int iDauBeg = event.append( id1, 23, iBeam, 0, 0, 0, col1, acol1,
+ p1, m1);
+ int iDauEnd = event.append( id2, 63, iBeam, 0, 0, 0, col2, acol2,
+ p2, m2);
+ event[iBeam].statusNeg();
+ event[iBeam].daughters(iDauBeg, iDauEnd);
+
+
+ // If gluon is kicked out: share momentum between two remnants.
+ } else {
+ double m2Sys, zSys, pxSys, pySys, mTS1, mTS2;
+ zSys = beamPtr->zShare(mDiff, m1, m2);
+
+ // Provide relative pT kick in remnant. Construct (transverse) masses.
+ pxSys = beamPtr->pxShare();
+ pySys = beamPtr->pyShare();
+ mTS1 = m1*m1 + pxSys*pxSys + pySys*pySys;
+ mTS2 = m2*m2 + pxSys*pxSys + pySys*pySys;
+ m2Sys = mTS1 / zSys + mTS2 / (1. - zSys);
+
+ // Momentum of kicked-out massless gluon in diffractive rest frame.
+ double pAbs = (m2Diff - m2Sys) / (2. * mDiff);
+ Vec4 pG(0., 0., -pAbs, pAbs);
+ Vec4 pRem(0., 0., pAbs, mDiff - pAbs);
+
+ // Momenta of the two beam remnant flavours. (Lightcone p+ = m_diff!)
+ double e1 = 0.5 * (zSys * mDiff + mTS1 / (zSys * mDiff));
+ double pL1 = 0.5 * (zSys * mDiff - mTS1 / (zSys * mDiff));
+ Vec4 p1(pxSys, pySys, pL1, e1);
+ Vec4 p2 = pRem - p1;
+
+ // Boost and rotate to event cm frame.
+ pG.bst(0., 0., beta); pG.rot(theta, phi);
+ p1.bst(0., 0., beta); p1.rot(theta, phi);
+ p2.bst(0., 0., beta); p2.rot(theta, phi);
+
+ // Set colours.
+ int colG, acolG, col1, acol1, col2, acol2;
+ if (ParticleDataTable::colType(id1) == 1) {
+ col1 = event.nextColTag(); acol1 = 0;
+ colG = event.nextColTag(); acolG = col1;
+ col2 = 0; acol2 = colG;
+ } else {
+ col1 = 0; acol1 = event.nextColTag();
+ colG = acol1; acolG = event.nextColTag();
+ col2 = acolG; acol2 = 0;
+ }
+
+ // Store partons of diffractive system and mark system decayed.
+ int iDauBeg = event.append( 21, 23, iBeam, 0, 0, 0, colG, acolG,
+ pG, m1);
+ event.append( id1, 63, iBeam, 0, 0, 0, col1, acol1, p1, m1);
+ int iDauEnd = event.append( id2, 63, iBeam, 0, 0, 0, col2, acol2,
+ p2, m2);
+ event[iBeam].statusNeg();
+ event[iBeam].daughters(iDauBeg, iDauEnd);
+ }
+
+ // End loop over beams. Done.
+ }
+ return true;
+}
+
+//*********
+
+// Handle showers in successive resonance decays.
+
+int PartonLevel::resonanceShowers( Event& process, Event& event) {
+
+ // Isolate next system to be processed, if anything remains.
+ int nFSRres = 0;
+ while (nHardDone < process.size()) {
+ int iBegin = nHardDone;
+
+ // Mother in hard process and in complete event (after shower).
+ int iHardMother = process[iBegin].mother1();
+ Particle& hardMother = process[iHardMother];
+ int iBefMother = iPosBefShow[iHardMother];
+ int iAftMother = event.iBotCopyId(iBefMother);
+ Particle& aftMother = event[iAftMother];
+
+ // From now mother counts as decayed.
+ aftMother.statusNeg();
+
+ // Mother can have been moved by showering (in any of previous steps),
+ // so prepare to update colour and momentum information for system.
+ int colBef = hardMother.col();
+ int acolBef = hardMother.acol();
+ int colAft = aftMother.col();
+ int acolAft = aftMother.acol();
+ RotBstMatrix M;
+ M.bst( hardMother.p(), aftMother.p());
+
+ // Extract next partons from hard event into normal event record.
+ for (int i = iBegin; i < process.size(); ++ i) {
+ if (process[i].mother1() != iHardMother) break;
+ int iNow = event.append( process[i] );
+ iPosBefShow[i] = iNow;
+ Particle& now = event.back();
+
+ // Currently outgoing ones should not count as decayed.
+ if (now.status() == -22) {
+ now.statusPos();
+ now.daughters(0, 0);
+ }
+
+ // Update daughter and mother information.
+ if (i == iBegin) aftMother.daughter1( iNow);
+ else aftMother.daughter2( iNow);
+ now.mother1(iAftMother);
+
+ // Update colour and momentum information.
+ if (now.col() == colBef) now.col( colAft);
+ if (now.acol() == acolBef) now.acol( acolAft);
+ now.rotbst( M);
+
+ // Complete task of copying next subsystem into event record.
+ ++nHardDone;
+ }
+ int iEnd = nHardDone - 1;
+
+ // Do parton showers inside subsystem: maximum scale by mother mass.
+ if (doFSRinResonances) {
+ double pTmax = 0.5 * hardMother.m();
+ nFSRhard = 0;
+
+ // Add new system, with two empty beam slots.
+ int iSys = event.newSystem();
+ event.addToSystem( iSys, 0);
+ event.addToSystem( iSys, 0);
+
+ // Loop over allowed range to find all final-state particles.
+ for (int i = iPosBefShow[iBegin]; i <= iPosBefShow[iEnd]; ++i)
+ if (event[i].isFinal()) event.addToSystem( iSys, i);
+
+ // Let prepare routine do the setup.
+ timesDecPtr->prepare( iSys, event);
+
+ // Set up initial veto scale.
+ doVeto = false;
+ double pTveto = pTvetoPT;
+
+ // Begin evolution down in pT from hard pT scale.
+ do {
+ typeVetoStep = 0;
+ double pTtimes = timesDecPtr->pTnext( event, pTmax, 0.);
+
+ // Allow a user veto. Only do it once, so remember to change pTveto.
+ if (pTveto > 0. && pTveto > pTtimes) {
+ pTveto = -1.;
+ doVeto = userHooksPtr->doVetoPT( 5, event);
+ // Abort event if vetoed.
+ if (doVeto) return false;
+ }
+
+ // Do a final-state emission (if allowed).
+ if (pTtimes > 0.) {
+ if (timesDecPtr->branch( event)) {
+ ++nFSRres;
+ ++nFSRhard;
+ if (canVetoStep && nFSRhard <= nVetoStep) typeVetoStep = 5;
+ }
+ pTmax = pTtimes;
+ }
+
+ // If no pT scales above zero then nothing to be done.
+ else pTmax = 0.;
+
+ // Optionally check for a veto after the first few emissions.
+ if (typeVetoStep > 0) {
+ doVeto = userHooksPtr->doVetoStep( typeVetoStep, 0, nFSRhard,
+ event);
+ // Abort event if vetoed.
+ if (doVeto) return false;
+ }
+
+ // Keep on evolving until nothing is left to be done.
+ } while (pTmax > 0.);
+
+ }
+
+ // No more systems to be processed. Return total number of emissions.
+ }
+ return nFSRres;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// PhaseSpace.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// PhaseSpace and PhaseSpace2to2tauyz classes.
+
+#include "PhaseSpace.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The PhaseSpace class.
+// Base class for phase space generators.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of trial maxima around which maximum search is performed.
+const int PhaseSpace::NMAXTRY = 2;
+
+// Number of three-body trials in phase space optimization.
+const int PhaseSpace::NTRY3BODY = 20;
+
+// Maximum cross section increase, just in case true maximum not found.
+const double PhaseSpace::SAFETYMARGIN = 1.05;
+
+// Small number to avoid division by zero.
+const double PhaseSpace::TINY = 1e-20;
+
+// Fraction of total weight that is shared evenly between all shapes.
+const double PhaseSpace::EVENFRAC = 0.4;
+
+// Two cross sections with a small relative error are assumed same.
+const double PhaseSpace::SAMESIGMA = 1e-6;
+
+// Do not include resonances peaked too far outside allowed mass region.
+const double PhaseSpace::WIDTHMARGIN = 20.;
+
+// Special optimization treatment when two resonances at almost same mass.
+const double PhaseSpace::SAMEMASS = 0.01;
+
+// Minimum phase space left when kinematics constraints are combined.
+const double PhaseSpace::MASSMARGIN = 0.01;
+
+// When using Breit-Wigners in 2 -> 2 raise maximum weight estimate.
+const double PhaseSpace::EXTRABWWTMAX = 1.25;
+
+// Size of Breit-Wigner threshold region, for mass selection biasing.
+const double PhaseSpace::THRESHOLDSIZE = 3.;
+
+// Step size in optimal-mass search, for mass selection biasing.
+const double PhaseSpace::THRESHOLDSTEP = 0.2;
+
+// Minimal rapidity range for allowed open range (in 2 -> 3).
+const double PhaseSpace::YRANGEMARGIN = 1e-6;
+
+// Cutoff for f_e^e at x < 1 - 10^{-10} to be used in phase space selection.
+// Note: the ...MIN quantities come from 1 - x_max or 1 - tau_max.
+const double PhaseSpace::LEPTONXMIN = 1e-10;
+const double PhaseSpace::LEPTONXMAX = 1. - 1e-10;
+const double PhaseSpace::LEPTONXLOGMIN = log(1e-10);
+const double PhaseSpace::LEPTONXLOGMAX = log(1. - 1e-10);
+const double PhaseSpace::LEPTONTAUMIN = 2e-10;
+
+// Safety to avoid division with unreasonably small value for z selection.
+const double PhaseSpace::SHATMINZ = 1.;
+
+// Regularization for small pT2min in z = cos(theta) selection.
+const double PhaseSpace::PT2RATMINZ = 0.0001;
+
+// These numbers are hardwired empirical parameters,
+// intended to speed up the M-generator.
+const double PhaseSpace::WTCORRECTION[11] = { 1., 1., 1.,
+ 2., 5., 15., 60., 250., 1250., 7000., 50000. };
+
+//*********
+
+// Perform simple initialization and store pointers.
+
+void PhaseSpace::init(SigmaProcess* sigmaProcessPtrIn, Info* infoPtrIn,
+ BeamParticle* beamAPtrIn, BeamParticle* beamBPtrIn,
+ SigmaTotal* sigmaTotPtrIn, UserHooks* userHooksPtrIn) {
+
+ // Store input pointers for future use.
+ sigmaProcessPtr = sigmaProcessPtrIn;
+ infoPtr = infoPtrIn;
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+ sigmaTotPtr = sigmaTotPtrIn;
+ userHooksPtr = userHooksPtrIn;
+
+ // Some commonly used beam information.
+ idA = beamAPtr->id();
+ idB = beamBPtr->id();
+ mA = beamAPtr->m();
+ mB = beamBPtr->m();
+ eCM = infoPtr->eCM();
+ s = eCM * eCM;
+
+ // Flag if lepton beams, and if non-resolved ones.
+ hasLeptonBeams = ( beamAPtr->isLepton() || beamBPtr->isLepton() );
+ hasPointLeptons = ( hasLeptonBeams
+ && (beamAPtr->isUnresolved() || beamBPtr->isUnresolved() ) );
+
+ // Standard phase space cuts.
+ mHatGlobalMin = Settings::parm("PhaseSpace:mHatMin");
+ mHatGlobalMax = Settings::parm("PhaseSpace:mHatMax");
+ pTHatGlobalMin = Settings::parm("PhaseSpace:pTHatMin");
+ pTHatGlobalMax = Settings::parm("PhaseSpace:pTHatMax");
+ pTHatMinDiverge = Settings::parm("PhaseSpace:pTHatMinDiverge");
+
+ // When to use Breit-Wigners.
+ useBreitWigners = Settings::flag("PhaseSpace:useBreitWigners");
+ minWidthBreitWigners = Settings::parm("PhaseSpace:minWidthBreitWigners");
+
+ // Whether generation is with variable energy.
+ doEnergySpread = Settings::flag("Beams:allowMomentumSpread");
+
+ // Print flag for maximization information.
+ showSearch = Settings::flag("PhaseSpace:showSearch");
+ showViolation = Settings::flag("PhaseSpace:showViolation");
+
+ // Know whether a Z0 is pure Z0 or admixed with gamma*.
+ gmZmodeGlobal = Settings::mode("WeakZ0:gmZmode");
+
+ // Default event-specific kinematics properties.
+ x1H = 1.;
+ x2H = 1.;
+ m3 = 0.;
+ m4 = 0.;
+ m5 = 0.;
+ s3 = m3 * m3;
+ s4 = m4 * m4;
+ s5 = m5 * m5;
+ mHat = eCM;
+ sH = s;
+ tH = 0.;
+ uH = 0.;
+ pTH = 0.;
+ theta = 0.;
+ phi = 0.;
+ runBW3H = 1.;
+ runBW4H = 1.;
+ runBW5H = 1.;
+
+ // Default cross section information.
+ sigmaNw = 0.;
+ sigmaMx = 0.;
+ sigmaNeg = 0.;
+ newSigmaMx = false;
+
+ // Flag if user should be allow to reweight cross section.
+ canModifySigma = (userHooksPtr > 0)
+ ? userHooksPtr->canModifySigma() : false;
+
+}
+
+//*********
+
+// Allow for nonisotropic decays when ME's available.
+
+void PhaseSpace::decayKinematics( Event& process) {
+
+ // Identify sets of sister partons.
+ int iResEnd = 4;
+ for (int iResBeg = 5; iResBeg < process.size(); ++iResBeg) {
+ if (iResBeg <= iResEnd) continue;
+ iResEnd = iResBeg;
+ while ( iResEnd < process.size() - 1
+ && process[iResEnd + 1].mother1() == process[iResBeg].mother1()
+ && process[iResEnd + 1].mother2() == process[iResBeg].mother2() )
+ ++iResEnd;
+
+ // Check that at least one of them is a resonance.
+ bool hasRes = false;
+ for (int iRes = iResBeg; iRes <= iResEnd; ++iRes)
+ if ( !process[iRes].isFinal() ) hasRes = true;
+ if ( !hasRes ) continue;
+
+ // Evaluate matrix element and decide whether to keep kinematics.
+ double decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
+ if (decWt < 0.) infoPtr->errorMsg("Warning in PhaseSpace::decay"
+ "Kinematics: negative angular weight");
+ if (decWt > 1.) infoPtr->errorMsg("Warning in PhaseSpace::decay"
+ "Kinematics: angular weight above unity");
+ while (decWt < Rndm::flat() ) {
+
+ // Find resonances for which to redo decay angles.
+ for (int iRes = iResBeg; iRes < process.size(); ++iRes) {
+ if ( process[iRes].isFinal() ) continue;
+ int iResMother = iRes;
+ while (iResMother > iResEnd)
+ iResMother = process[iResMother].mother1();
+ if (iResMother < iResBeg) continue;
+
+ // Do decay of this mother isotropically in phase space.
+ decayKinematicsStep( process, iRes);
+
+ // End loop over resonance decay chains.
+ }
+
+ // Ready to allow new test of matrix element.
+ decWt = sigmaProcessPtr->weightDecay( process, iResBeg, iResEnd);
+ if (decWt < 0.) infoPtr->errorMsg("Warning in PhaseSpace::decay"
+ "Kinematics: negative angular weight");
+ if (decWt > 1.) infoPtr->errorMsg("Warning in PhaseSpace::decay"
+ "Kinematics: angular weight above unity");
+ }
+
+ // End loop over sets of sister resonances/partons.
+ }
+
+}
+
+//*********
+
+// Reselect decay products momenta isotropically in phase space.
+// Does not redo secondary vertex position!
+
+void PhaseSpace::decayKinematicsStep( Event& process, int iRes) {
+
+ // Multiplicity and mother mass and four-momentum.
+ int i1 = process[iRes].daughter1();
+ int mult = process[iRes].daughter2() + 1 - i1;
+ double m0 = process[iRes].m();
+ Vec4 pRes = process[iRes].p();
+
+ // Description of two-body decays as simple special case.
+ if (mult == 2) {
+
+ // Products and product masses.
+ int i2 = i1 + 1;
+ double m1t = process[i1].m();
+ double m2t = process[i2].m();
+
+ // Energies and absolute momentum in the rest frame.
+ double e1 = 0.5 * (m0*m0 + m1t*m1t - m2t*m2t) / m0;
+ double e2 = 0.5 * (m0*m0 + m2t*m2t - m1t*m1t) / m0;
+ double p12 = 0.5 * sqrtpos( (m0 - m1t - m2t) * (m0 + m1t + m2t)
+ * (m0 + m1t - m2t) * (m0 - m1t + m2t) ) / m0;
+
+ // Pick isotropic angles to give three-momentum.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi12 = 2. * M_PI * Rndm::flat();
+ double pX = p12 * sinTheta * cos(phi12);
+ double pY = p12 * sinTheta * sin(phi12);
+ double pZ = p12 * cosTheta;
+
+ // Fill four-momenta in mother rest frame and then boost to lab frame.
+ Vec4 p1( pX, pY, pZ, e1);
+ Vec4 p2( -pX, -pY, -pZ, e2);
+ p1.bst( pRes );
+ p2.bst( pRes );
+
+ // Done for two-body decay.
+ process[i1].p( p1 );
+ process[i2].p( p2 );
+ return;
+ }
+
+ // Description of three-body decays as semi-simple special case.
+ if (mult == 3) {
+
+ // Products and product masses.
+ int i2 = i1 + 1;
+ int i3 = i2 + 1;
+ double m1t = process[i1].m();
+ double m2t = process[i2].m();
+ double m3t = process[i3].m();
+ double mDiff = m0 - (m1t + m2t + m3t);
+
+ // Kinematical limits for 2+3 mass. Maximum phase-space weight.
+ double m23Min = m2t + m3t;
+ double m23Max = m0 - m1t;
+ double p1Max = 0.5 * sqrtpos( (m0 - m1t - m23Min)
+ * (m0 + m1t + m23Min) * (m0 + m1t - m23Min)
+ * (m0 - m1t + m23Min) ) / m0;
+ double p23Max = 0.5 * sqrtpos( (m23Max - m2t - m3t)
+ * (m23Max + m2t + m3t) * (m23Max + m2t - m3t)
+ * (m23Max - m2t + m3t) ) / m23Max;
+ double wtPSmax = 0.5 * p1Max * p23Max;
+
+ // Pick an intermediate mass m23 flat in the allowed range.
+ double wtPS, m23, p1Abs, p23Abs;
+ do {
+ m23 = m23Min + Rndm::flat() * mDiff;
+
+ // Translate into relative momenta and find phase-space weight.
+ p1Abs = 0.5 * sqrtpos( (m0 - m1t - m23) * (m0 + m1t + m23)
+ * (m0 + m1t - m23) * (m0 - m1t + m23) ) / m0;
+ p23Abs = 0.5 * sqrtpos( (m23 - m2t - m3t) * (m23 + m2t + m3t)
+ * (m23 + m2t - m3t) * (m23 - m2t + m3t) ) / m23;
+ wtPS = p1Abs * p23Abs;
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtPS < Rndm::flat() * wtPSmax );
+
+ // Set up m23 -> m2 + m3 isotropic in its rest frame.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi23 = 2. * M_PI * Rndm::flat();
+ double pX = p23Abs * sinTheta * cos(phi23);
+ double pY = p23Abs * sinTheta * sin(phi23);
+ double pZ = p23Abs * cosTheta;
+ double e2 = sqrt( m2t*m2t + p23Abs*p23Abs);
+ double e3 = sqrt( m3t*m3t + p23Abs*p23Abs);
+ Vec4 p2( pX, pY, pZ, e2);
+ Vec4 p3( -pX, -pY, -pZ, e3);
+
+ // Set up 0 -> 1 + 23 isotropic in its rest frame.
+ cosTheta = 2. * Rndm::flat() - 1.;
+ sinTheta = sqrt(1. - cosTheta*cosTheta);
+ phi23 = 2. * M_PI * Rndm::flat();
+ pX = p1Abs * sinTheta * cos(phi23);
+ pY = p1Abs * sinTheta * sin(phi23);
+ pZ = p1Abs * cosTheta;
+ double e1 = sqrt( m1t*m1t + p1Abs*p1Abs);
+ double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
+ Vec4 p1( pX, pY, pZ, e1);
+
+ // Boost 2 + 3 to the 0 rest frame and then boost to lab frame.
+ Vec4 p23( -pX, -pY, -pZ, e23);
+ p2.bst( p23 );
+ p3.bst( p23 );
+ p1.bst( pRes );
+ p2.bst( pRes );
+ p3.bst( pRes );
+
+ // Done for three-body decay.
+ process[i1].p( p1 );
+ process[i2].p( p2 );
+ process[i3].p( p3 );
+ return;
+ }
+
+ // Do a multibody decay using the M-generator algorithm.
+
+ // Set up masses and four-momenta in a vector, with mother in slot 0.
+ vector<double> mProd;
+ mProd.push_back( m0);
+ for (int i = i1; i <= process[iRes].daughter2(); ++i)
+ mProd.push_back( process[i].m() );
+ vector<Vec4> pProd;
+ pProd.push_back( pRes);
+
+ // Sum of daughter masses.
+ double mSum = mProd[1];
+ for (int i = 2; i <= mult; ++i) mSum += mProd[i];
+ double mDiff = m0 - mSum;
+
+ // Begin setup of intermediate invariant masses.
+ vector<double> mInv;
+ for (int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
+
+ // Calculate the maximum weight in the decay.
+ double wtPSmax = 1. / WTCORRECTION[mult];
+ double mMaxWT = mDiff + mProd[mult];
+ double mMinWT = 0.;
+ for (int i = mult - 1; i > 0; --i) {
+ mMaxWT += mProd[i];
+ mMinWT += mProd[i+1];
+ double mNow = mProd[i];
+ wtPSmax *= 0.5 * sqrtpos( (mMaxWT - mMinWT - mNow)
+ * (mMaxWT + mMinWT + mNow) * (mMaxWT + mMinWT - mNow)
+ * (mMaxWT - mMinWT + mNow) ) / mMaxWT;
+ }
+
+ // Begin loop to find the set of intermediate invariant masses.
+ vector<double> rndmOrd;
+ double wtPS;
+ do {
+ wtPS = 1.;
+
+ // Find and order random numbers in descending order.
+ rndmOrd.resize(0);
+ rndmOrd.push_back(1.);
+ for (int i = 1; i < mult - 1; ++i) {
+ double rndm = Rndm::flat();
+ rndmOrd.push_back(rndm);
+ for (int j = i - 1; j > 0; --j) {
+ if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
+ else break;
+ }
+ }
+ rndmOrd.push_back(0.);
+
+ // Translate into intermediate masses and find weight.
+ for (int i = mult - 1; i > 0; --i) {
+ mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
+ wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
+ * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
+ * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
+ }
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtPS < Rndm::flat() * wtPSmax );
+
+ // Perform two-particle decays in the respective rest frame.
+ vector<Vec4> pInv;
+ pInv.resize(mult + 1);
+ for (int i = 1; i < mult; ++i) {
+ double p12 = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
+ * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
+ * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
+
+ // Isotropic angles give three-momentum.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phiLoc = 2. * M_PI * Rndm::flat();
+ double pX = p12 * sinTheta * cos(phiLoc);
+ double pY = p12 * sinTheta * sin(phiLoc);
+ double pZ = p12 * cosTheta;
+
+ // Calculate energies, fill four-momenta.
+ double eHad = sqrt( mProd[i]*mProd[i] + p12*p12);
+ double eInv = sqrt( mInv[i+1]*mInv[i+1] + p12*p12);
+ pProd.push_back( Vec4( pX, pY, pZ, eHad) );
+ pInv[i+1].p( -pX, -pY, -pZ, eInv);
+ }
+ pProd.push_back( pInv[mult] );
+
+ // Boost decay products to the mother rest frame and on to lab frame.
+ pInv[1] = pProd[0];
+ for (int iFrame = mult - 1; iFrame > 0; --iFrame)
+ for (int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);
+
+ // Done for multibody decay.
+ for (int i = 1; i < mult; ++i)
+ process[i1 + i - 1].p( pProd[i] );
+ return;
+
+}
+
+//*********
+
+// Determine how 3-body phase space should be sampled.
+
+void PhaseSpace::setup3Body() {
+
+ // Check for massive t-channel propagator particles.
+ int idTchan1 = abs( sigmaProcessPtr->idTchan1() );
+ int idTchan2 = abs( sigmaProcessPtr->idTchan2() );
+ mTchan1 = (idTchan1 == 0) ? 0. : ParticleDataTable::m0(idTchan1);
+ mTchan2 = (idTchan2 == 0) ? 0. : ParticleDataTable::m0(idTchan2);
+ sTchan1 = mTchan1 * mTchan1;
+ sTchan2 = mTchan2 * mTchan2;
+
+ // Find coefficients of different pT2 selection terms. Mirror choice.
+ frac3Pow1 = sigmaProcessPtr->tChanFracPow1();
+ frac3Pow2 = sigmaProcessPtr->tChanFracPow2();
+ frac3Flat = 1. - frac3Pow1 - frac3Pow2;
+ useMirrorWeight = sigmaProcessPtr->useMirrorWeight();
+
+}
+
+//*********
+
+// Determine how phase space should be sampled.
+
+bool PhaseSpace::setupSampling123(bool is2, bool is3, ostream& os) {
+
+ // Optional printout.
+ if (showSearch) os << "\n PYTHIA Optimization printout for "
+ << sigmaProcessPtr->name() << "\n \n" << scientific << setprecision(3);
+
+ // Check that open range in tau (+ set tauMin, tauMax).
+ if (!limitTau(is2, is3)) return false;
+
+ // Reset coefficients and matrices of equation system to solve.
+ int binTau[8], binY[8], binZ[8];
+ double vecTau[8], matTau[8][8], vecY[8], matY[8][8], vecZ[8], matZ[8][8];
+ for (int i = 0; i < 8; ++i) {
+ tauCoef[i] = 0.;
+ yCoef[i] = 0.;
+ zCoef[i] = 0.;
+ binTau[i] = 0;
+ binY[i] = 0;
+ binZ[i] = 0;
+ vecTau[i] = 0.;
+ vecY[i] = 0.;
+ vecZ[i] = 0.;
+ for (int j = 0; j < 8; ++j) {
+ matTau[i][j] = 0.;
+ matY[i][j] = 0.;
+ matZ[i][j] = 0.;
+ }
+ }
+ sigmaMx = 0.;
+ sigmaNeg = 0.;
+
+ // Number of used coefficients/points for each dimension: tau, y, c.
+ nTau = (hasPointLeptons) ? 1 : 2;
+ nY = (hasPointLeptons) ? 1 : 3;
+ nZ = (is2) ? 5 : 1;
+
+ // Identify if any resonances contribute in s-channel.
+ idResA = sigmaProcessPtr->resonanceA();
+ if (idResA != 0) {
+ mResA = ParticleDataTable::m0(idResA);
+ GammaResA = ParticleDataTable::mWidth(idResA);
+ if (mHatMin > mResA + WIDTHMARGIN * GammaResA || (mHatMax > 0.
+ && mHatMax < mResA - WIDTHMARGIN * GammaResA) ) idResA = 0;
+ }
+ idResB = sigmaProcessPtr->resonanceB();
+ if (idResB != 0) {
+ mResB = ParticleDataTable::m0(idResB);
+ GammaResB = ParticleDataTable::mWidth(idResB);
+ if (mHatMin > mResB + WIDTHMARGIN * GammaResB || (mHatMax > 0.
+ && mHatMax < mResB - WIDTHMARGIN * GammaResB) ) idResB = 0;
+ }
+ if (idResA == 0 && idResB != 0) {
+ idResA = idResB;
+ mResA = mResB;
+ GammaResA = GammaResB;
+ idResB = 0;
+ }
+
+ // More sampling in tau if resonances in s-channel.
+ if (idResA !=0 && !hasPointLeptons) {
+ nTau += 2;
+ tauResA = mResA * mResA / s;
+ widResA = mResA * GammaResA / s;
+ }
+ if (idResB != 0 && !hasPointLeptons) {
+ nTau += 2;
+ tauResB = mResB * mResB / s;
+ widResB = mResB * GammaResB / s;
+ }
+
+ // More sampling in tau and y if incoming lepton beams.
+ if (hasLeptonBeams && !hasPointLeptons) {
+ ++nTau;
+ nY += 2;
+ }
+
+ // Special case when both resonances have same mass.
+ sameResMass = false;
+ if (idResB != 0 && abs(mResA - mResB) < SAMEMASS * (GammaResA + GammaResB))
+ sameResMass = true;
+
+ // Default z value and weight required for 2 -> 1. Number of dimensions.
+ z = 0.;
+ wtZ = 1.;
+ int nVar = (is2) ? 3 : 2;
+
+ // Initial values, to be modified later.
+ tauCoef[0] = 1.;
+ yCoef[0] = 0.5;
+ yCoef[1] = 0.5;
+ zCoef[0] = 1.;
+
+ // Step through grid in tau. Set limits on y and z generation.
+ for (int iTau = 0; iTau < nTau; ++iTau) {
+ double posTau = 0.5;
+ if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
+ selectTau( iTau, posTau, is2);
+ if (!limitY()) continue;
+ if (is2 && !limitZ()) continue;
+
+ // Step through grids in y and z.
+ for (int iY = 0; iY < nY; ++iY) {
+ selectY( iY, 0.5);
+ for (int iZ = 0; iZ < nZ; ++iZ) {
+ if (is2) selectZ( iZ, 0.5);
+ double sigmaTmp = 0.;
+
+ // 2 -> 1: calculate cross section, weighted by phase-space volume.
+ if (!is2 && !is3) {
+ sigmaProcessPtr->set1Kin( x1H, x2H, sH);
+ sigmaTmp = sigmaProcessPtr->sigmaPDF();
+ sigmaTmp *= wtTau * wtY;
+
+ // 2 -> 2: calculate cross section, weighted by phase-space volume
+ // and Breit-Wigners for masses
+ } else if (is2) {
+ sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
+ runBW3H, runBW4H);
+ sigmaTmp = sigmaProcessPtr->sigmaPDF();
+ sigmaTmp *= wtTau * wtY * wtZ * wtBW;
+
+ // 2 -> 3: repeat internal 3-body phase space several times and
+ // keep maximal cross section, weighted by phase-space volume
+ // and Breit-Wigners for masses
+ } else if (is3) {
+ for (int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
+ if (!select3Body()) continue;
+ sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
+ m3, m4, m5, runBW3H, runBW4H, runBW5H);
+ double sigmaTry = sigmaProcessPtr->sigmaPDF();
+ sigmaTry *= wtTau * wtY * wt3Body * wtBW;
+ if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
+ }
+ }
+
+ // Allow possibility for user to modify cross section. (3body??)
+ if (canModifySigma) sigmaTmp
+ *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr, this, false);
+
+ // Check if current maximum exceeded.
+ if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
+
+ // Optional printout. Protect against negative cross sections.
+ if (showSearch) os << " tau =" << setw(11) << tau << " y ="
+ << setw(11) << y << " z =" << setw(11) << z
+ << " sigma =" << setw(11) << sigmaTmp << "\n";
+ if (sigmaTmp < 0.) sigmaTmp = 0.;
+
+ // Sum up tau cross-section pieces in points used.
+ if (!hasPointLeptons) {
+ binTau[iTau] += 1;
+ vecTau[iTau] += sigmaTmp;
+ matTau[iTau][0] += 1. / intTau0;
+ matTau[iTau][1] += (1. / intTau1) / tau;
+ if (idResA != 0) {
+ matTau[iTau][2] += (1. / intTau2) / (tau + tauResA);
+ matTau[iTau][3] += (1. / intTau3)
+ * tau / ( pow2(tau - tauResA) + pow2(widResA) );
+ }
+ if (idResB != 0) {
+ matTau[iTau][4] += (1. / intTau4) / (tau + tauResB);
+ matTau[iTau][5] += (1. / intTau5)
+ * tau / ( pow2(tau - tauResB) + pow2(widResB) );
+ }
+ if (hasLeptonBeams) matTau[iTau][nTau - 1] += (1. / intTau6)
+ * tau / max( LEPTONTAUMIN, 1. - tau);
+ }
+
+ // Sum up y cross-section pieces in points used.
+ if (!hasPointLeptons) {
+ binY[iY] += 1;
+ vecY[iY] += sigmaTmp;
+ matY[iY][0] += (yMax / intY01) * (y + yMax);
+ matY[iY][1] += (yMax / intY01) * (yMax - y);
+ matY[iY][2] += (yMax / intY2) / cosh(y);
+ if (hasLeptonBeams) {
+ matY[iY][3] += (yMax / intY34)
+ / max( LEPTONXMIN, 1. - exp( y - yMax) );
+ matY[iY][4] += (yMax / intY34)
+ / max( LEPTONXMIN, 1. - exp(-y - yMax) );
+ }
+ }
+
+ // Integrals over z expressions at tauMax, to be used below.
+ if (is2) {
+ double p2AbsMax = 0.25 * (pow2(tauMax * s - s3 - s4)
+ - 4. * s3 * s4) / (tauMax * s);
+ double zMaxMax = sqrtpos( 1. - pT2HatMin / p2AbsMax );
+ double zPosMaxMax = max(ratio34, unity34 + zMaxMax);
+ double zNegMaxMax = max(ratio34, unity34 - zMaxMax);
+ double intZ0Max = 2. * zMaxMax;
+ double intZ12Max = log( zPosMaxMax / zNegMaxMax);
+ double intZ34Max = 1. / zNegMaxMax - 1. / zPosMaxMax;
+
+ // Sum up z cross-section pieces in points used.
+ binZ[iZ] += 1;
+ vecZ[iZ] += sigmaTmp;
+ matZ[iZ][0] += 1.;
+ matZ[iZ][1] += (intZ0Max / intZ12Max) / zNeg;
+ matZ[iZ][2] += (intZ0Max / intZ12Max) / zPos;
+ matZ[iZ][3] += (intZ0Max / intZ34Max) / pow2(zNeg);
+ matZ[iZ][4] += (intZ0Max / intZ34Max) / pow2(zPos);
+ }
+
+ // End of loops over phase space points.
+ }
+ }
+ }
+
+ // Fail if no non-vanishing cross sections.
+ if (sigmaMx <= 0.) {
+ sigmaMx = 0.;
+ return false;
+ }
+
+ // Solve respective equation system for better phase space coefficients.
+ if (!hasPointLeptons) solveSys( nTau, binTau, vecTau, matTau, tauCoef);
+ if (!hasPointLeptons) solveSys( nY, binY, vecY, matY, yCoef);
+ if (is2) solveSys( nZ, binZ, vecZ, matZ, zCoef);
+ if (showSearch) os << "\n";
+
+ // Provide cumulative sum of coefficients.
+ tauCoefSum[0] = tauCoef[0];
+ yCoefSum[0] = yCoef[0];
+ zCoefSum[0] = zCoef[0];
+ for (int i = 1; i < 8; ++ i) {
+ tauCoefSum[i] = tauCoefSum[i - 1] + tauCoef[i];
+ yCoefSum[i] = yCoefSum[i - 1] + yCoef[i];
+ zCoefSum[i] = zCoefSum[i - 1] + zCoef[i];
+ }
+ // The last element should be > 1 to be on safe side in selection below.
+ tauCoefSum[nTau - 1] = 2.;
+ yCoefSum[nY - 1] = 2.;
+ zCoefSum[nZ - 1] = 2.;
+
+
+ // Begin find two most promising maxima among same points as before.
+ int iMaxTau[NMAXTRY + 2], iMaxY[NMAXTRY + 2], iMaxZ[NMAXTRY + 2];
+ double sigMax[NMAXTRY + 2];
+ int nMax = 0;
+
+ // Scan same grid as before in tau, y, z.
+ for (int iTau = 0; iTau < nTau; ++iTau) {
+ double posTau = 0.5;
+ if (sameResMass && iTau > 1 && iTau < 6) posTau = (iTau < 4) ? 0.4 : 0.6;
+ selectTau( iTau, posTau, is2);
+ if (!limitY()) continue;
+ if (is2 && !limitZ()) continue;
+ for (int iY = 0; iY < nY; ++iY) {
+ selectY( iY, 0.5);
+ for (int iZ = 0; iZ < nZ; ++iZ) {
+ if (is2) selectZ( iZ, 0.5);
+ double sigmaTmp = 0.;
+
+ // 2 -> 1: calculate cross section, weighted by phase-space volume.
+ if (!is2 && !is3) {
+ sigmaProcessPtr->set1Kin( x1H, x2H, sH);
+ sigmaTmp = sigmaProcessPtr->sigmaPDF();
+ sigmaTmp *= wtTau * wtY;
+
+ // 2 -> 2: calculate cross section, weighted by phase-space volume
+ // and Breit-Wigners for masses
+ } else if (is2) {
+ sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
+ runBW3H, runBW4H);
+ sigmaTmp = sigmaProcessPtr->sigmaPDF();
+ sigmaTmp *= wtTau * wtY * wtZ * wtBW;
+
+ // 2 -> 3: repeat internal 3-body phase space several times and
+ // keep maximal cross section, weighted by phase-space volume
+ // and Breit-Wigners for masses
+ } else if (is3) {
+ for (int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
+ if (!select3Body()) continue;
+ sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
+ m3, m4, m5, runBW3H, runBW4H, runBW5H);
+ double sigmaTry = sigmaProcessPtr->sigmaPDF();
+ sigmaTry *= wtTau * wtY * wt3Body * wtBW;
+ if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
+ }
+ }
+
+ // Allow possibility for user to modify cross section. (3body??)
+ if (canModifySigma) sigmaTmp
+ *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr, this, false);
+
+ // Optional printout. Protect against negative cross section.
+ if (showSearch) os << " tau =" << setw(11) << tau << " y ="
+ << setw(11) << y << " z =" << setw(11) << z
+ << " sigma =" << setw(11) << sigmaTmp << "\n";
+ if (sigmaTmp < 0.) sigmaTmp = 0.;
+
+ // Check that point is not simply mirror of already found one.
+ bool mirrorPoint = false;
+ for (int iMove = 0; iMove < nMax; ++iMove)
+ if (abs(sigmaTmp - sigMax[iMove]) < SAMESIGMA
+ * (sigmaTmp + sigMax[iMove])) mirrorPoint = true;
+
+ // Add to or insert in maximum list. Only first two count.
+ if (!mirrorPoint) {
+ int iInsert = 0;
+ for (int iMove = nMax - 1; iMove >= -1; --iMove) {
+ iInsert = iMove + 1;
+ if (iInsert == 0 || sigmaTmp < sigMax[iMove]) break;
+ iMaxTau[iMove + 1] = iMaxTau[iMove];
+ iMaxY[iMove + 1] = iMaxY[iMove];
+ iMaxZ[iMove + 1] = iMaxZ[iMove];
+ sigMax[iMove + 1] = sigMax[iMove];
+ }
+ iMaxTau[iInsert] = iTau;
+ iMaxY[iInsert] = iY;
+ iMaxZ[iInsert] = iZ;
+ sigMax[iInsert] = sigmaTmp;
+ if (nMax < NMAXTRY) ++nMax;
+ }
+
+ // Found two most promising maxima.
+ }
+ }
+ }
+ if (showSearch) os << "\n";
+
+ // Read out starting position for search.
+ sigmaMx = sigMax[0];
+ int beginVar = (hasPointLeptons) ? 2 : 0;
+ for (int iMax = 0; iMax < nMax; ++iMax) {
+ int iTau = iMaxTau[iMax];
+ int iY = iMaxY[iMax];
+ int iZ = iMaxZ[iMax];
+ double tauVal = 0.5;
+ double yVal = 0.5;
+ double zVal = 0.5;
+ int iGrid;
+ double varVal, varNew, deltaVar, marginVar, sigGrid[3];
+
+ // Starting point and step size in parameter space.
+ for (int iRepeat = 0; iRepeat < 2; ++iRepeat) {
+ // Run through (possibly a subset of) tau, y and z.
+ for (int iVar = beginVar; iVar < nVar; ++iVar) {
+ if (iVar == 0) varVal = tauVal;
+ else if (iVar == 1) varVal = yVal;
+ else varVal = zVal;
+ deltaVar = (iRepeat == 0) ? 0.1
+ : max( 0.01, min( 0.05, min( varVal - 0.02, 0.98 - varVal) ) );
+ marginVar = (iRepeat == 0) ? 0.02 : 0.002;
+ int moveStart = (iRepeat == 0 && iVar == 0) ? 0 : 1;
+ for (int move = moveStart; move < 9; ++move) {
+
+ // Define new parameter-space point by step in one dimension.
+ if (move == 0) {
+ iGrid = 1;
+ varNew = varVal;
+ } else if (move == 1) {
+ iGrid = 2;
+ varNew = varVal + deltaVar;
+ } else if (move == 2) {
+ iGrid = 0;
+ varNew = varVal - deltaVar;
+ } else if (sigGrid[2] >= max( sigGrid[0], sigGrid[1])
+ && varVal + 2. * deltaVar < 1. - marginVar) {
+ varVal += deltaVar;
+ sigGrid[0] = sigGrid[1];
+ sigGrid[1] = sigGrid[2];
+ iGrid = 2;
+ varNew = varVal + deltaVar;
+ } else if (sigGrid[0] >= max( sigGrid[1], sigGrid[2])
+ && varVal - 2. * deltaVar > marginVar) {
+ varVal -= deltaVar;
+ sigGrid[2] = sigGrid[1];
+ sigGrid[1] = sigGrid[0];
+ iGrid = 0;
+ varNew = varVal - deltaVar;
+ } else if (sigGrid[2] >= sigGrid[0]) {
+ deltaVar *= 0.5;
+ varVal += deltaVar;
+ sigGrid[0] = sigGrid[1];
+ iGrid = 1;
+ varNew = varVal;
+ } else {
+ deltaVar *= 0.5;
+ varVal -= deltaVar;
+ sigGrid[2] = sigGrid[1];
+ iGrid = 1;
+ varNew = varVal;
+ }
+
+ // Convert to relevant variables and find derived new limits.
+ bool insideLimits = true;
+ if (iVar == 0) {
+ tauVal = varNew;
+ selectTau( iTau, tauVal, is2);
+ if (!limitY()) insideLimits = false;
+ if (is2 && !limitZ()) insideLimits = false;
+ if (insideLimits) {
+ selectY( iY, yVal);
+ if (is2) selectZ( iZ, zVal);
+ }
+ } else if (iVar == 1) {
+ yVal = varNew;
+ selectY( iY, yVal);
+ } else if (iVar == 2) {
+ zVal = varNew;
+ selectZ( iZ, zVal);
+ }
+
+ // Evaluate cross-section.
+ double sigmaTmp = 0.;
+ if (insideLimits) {
+
+ // 2 -> 1: calculate cross section, weighted by phase-space volume.
+ if (!is2 && !is3) {
+ sigmaProcessPtr->set1Kin( x1H, x2H, sH);
+ sigmaTmp = sigmaProcessPtr->sigmaPDF();
+ sigmaTmp *= wtTau * wtY;
+
+ // 2 -> 2: calculate cross section, weighted by phase-space volume
+ // and Breit-Wigners for masses
+ } else if (is2) {
+ sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4,
+ runBW3H, runBW4H);
+ sigmaTmp = sigmaProcessPtr->sigmaPDF();
+ sigmaTmp *= wtTau * wtY * wtZ * wtBW;
+
+ // 2 -> 3: repeat internal 3-body phase space several times and
+ // keep maximal cross section, weighted by phase-space volume
+ // and Breit-Wigners for masses
+ } else if (is3) {
+ for (int iTry3 = 0; iTry3 < NTRY3BODY; ++iTry3) {
+ if (!select3Body()) continue;
+ sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
+ m3, m4, m5, runBW3H, runBW4H, runBW5H);
+ double sigmaTry = sigmaProcessPtr->sigmaPDF();
+ sigmaTry *= wtTau * wtY * wt3Body * wtBW;
+ if (sigmaTry > sigmaTmp) sigmaTmp = sigmaTry;
+ }
+ }
+
+ // Allow possibility for user to modify cross section.
+ if (canModifySigma) sigmaTmp
+ *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr, this, false);
+
+ // Optional printout. Protect against negative cross section.
+ if (showSearch) os << " tau =" << setw(11) << tau << " y ="
+ << setw(11) << y << " z =" << setw(11) << z
+ << " sigma =" << setw(11) << sigmaTmp << "\n";
+ if (sigmaTmp < 0.) sigmaTmp = 0.;
+ }
+
+ // Save new maximum. Final maximum.
+ sigGrid[iGrid] = sigmaTmp;
+ if (sigmaTmp > sigmaMx) sigmaMx = sigmaTmp;
+ }
+ }
+ }
+ }
+ sigmaMx *= SAFETYMARGIN;
+
+ // Optional printout.
+ if (showSearch) os << "\n Final maximum = " << setw(11) << sigmaMx << endl;
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Select a trial kinematics phase space point.
+// Note: by In is meant the integral over the quantity multiplying
+// coefficient cn. The sum of cn is normalized to unity.
+
+bool PhaseSpace::trialKin123(bool is2, bool is3, bool inEvent, ostream& os) {
+
+ // Allow for possibility that energy varies from event to event.
+ if (doEnergySpread) {
+ eCM = infoPtr->eCM();
+ s = eCM * eCM;
+
+ // Find shifted tauRes values.
+ if (idResA !=0 && !hasPointLeptons) {
+ tauResA = mResA * mResA / s;
+ widResA = mResA * GammaResA / s;
+ }
+ if (idResB != 0 && !hasPointLeptons) {
+ tauResB = mResB * mResB / s;
+ widResB = mResB * GammaResB / s;
+ }
+ }
+
+ // Choose tau according to h1(tau)/tau, where
+ // h1(tau) = c0/I0 + (c1/I1) * 1/tau
+ // + (c2/I2) / (tau + tauResA)
+ // + (c3/I3) * tau / ((tau - tauResA)^2 + widResA^2)
+ // + (c4/I4) / (tau + tauResB)
+ // + (c5/I5) * tau / ((tau - tauResB)^2 + widResB^2)
+ // + (c6/I6) * tau / (1 - tau).
+ if (!limitTau(is2, is3)) return false;
+ int iTau = 0;
+ if (!hasPointLeptons) {
+ double rTau = Rndm::flat();
+ while (rTau > tauCoefSum[iTau]) ++iTau;
+ }
+ selectTau( iTau, Rndm::flat(), is2);
+
+ // Choose y according to h2(y), where
+ // h2(y) = (c0/I0) * (y-ymin) + (c1/I1) * (ymax-y)
+ // + (c2/I2) * 1/cosh(y) + (c3/I3) * 1 / (1 - exp(y-ymax))
+ // + (c4/I4) * 1 / (1 - exp(ymin-y)).
+ if (!limitY()) return false;
+ int iY = 0;
+ if (!hasPointLeptons) {
+ double rY = Rndm::flat();
+ while (rY > yCoefSum[iY]) ++iY;
+ }
+ selectY( iY, Rndm::flat());
+
+ // Choose z = cos(thetaHat) according to h3(z), where
+ // h3(z) = c0/I0 + (c1/I1) * 1/(A - z) + (c2/I2) * 1/(A + z)
+ // + (c3/I3) * 1/(A - z)^2 + (c4/I4) * 1/(A + z)^2,
+ // where A = 1 + 2*(m3*m4/sH)^2 (= 1 for massless products).
+ if (is2) {
+ if (!limitZ()) return false;
+ int iZ = 0;
+ double rZ = Rndm::flat();
+ while (rZ > zCoefSum[iZ]) ++iZ;
+ selectZ( iZ, Rndm::flat());
+ }
+
+ // 2 -> 1: calculate cross section, weighted by phase-space volume.
+ if (!is2 && !is3) {
+ sigmaProcessPtr->set1Kin( x1H, x2H, sH);
+ sigmaNw = sigmaProcessPtr->sigmaPDF();
+ sigmaNw *= wtTau * wtY;
+
+ // 2 -> 2: calculate cross section, weighted by phase-space volume
+ // and Breit-Wigners for masses
+ } else if (is2) {
+ sigmaProcessPtr->set2Kin( x1H, x2H, sH, tH, m3, m4, runBW3H, runBW4H);
+ sigmaNw = sigmaProcessPtr->sigmaPDF();
+ sigmaNw *= wtTau * wtY * wtZ * wtBW;
+
+ // 2 -> 3: also sample internal 3-body phase, weighted by
+ // 2 -> 1 phase-space volume and Breit-Wigners for masses
+ } else if (is3) {
+ if (!select3Body()) sigmaNw = 0.;
+ else {
+ sigmaProcessPtr->set3Kin( x1H, x2H, sH, p3cm, p4cm, p5cm,
+ m3, m4, m5, runBW3H, runBW4H, runBW5H);
+ sigmaNw = sigmaProcessPtr->sigmaPDF();
+ sigmaNw *= wtTau * wtY * wt3Body * wtBW;
+ }
+ }
+
+ // Allow possibility for user to modify cross section.
+ if (canModifySigma) sigmaNw
+ *= userHooksPtr->multiplySigmaBy( sigmaProcessPtr, this, inEvent);
+
+ // Check if maximum violated.
+ newSigmaMx = false;
+ if (sigmaNw > sigmaMx) {
+ infoPtr->errorMsg("Warning in PhaseSpace2to2tauyz::trialKin: "
+ "maximum for cross section violated");
+ double violFact = SAFETYMARGIN * sigmaNw / sigmaMx;
+ sigmaMx = SAFETYMARGIN * sigmaNw;
+ newSigmaMx = true;
+
+ // Optional printout of (all) violations.
+ if (showViolation) {
+ if (violFact < 9.99) os << fixed;
+ else os << scientific;
+ os << " PYTHIA Maximum for " << sigmaProcessPtr->name()
+ << " increased by factor " << setprecision(3) << violFact
+ << " to " << scientific << sigmaMx << endl;
+ }
+ }
+
+ // Check if negative cross section.
+ if (sigmaNw < sigmaNeg) {
+ infoPtr->errorMsg("Warning in PhaseSpace2to2tauyz::trialKin:"
+ " negative cross section set 0", "for " + sigmaProcessPtr->name() );
+ sigmaNeg = sigmaNw;
+
+ // Optional printout of (all) violations.
+ if (showViolation) os << " PYTHIA Negative minimum for "
+ << sigmaProcessPtr->name() << " changed to " << scientific
+ << setprecision(3) << sigmaNeg << endl;
+ }
+ if (sigmaNw < 0.) sigmaNw = 0.;
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Find range of allowed tau values.
+
+bool PhaseSpace::limitTau(bool is2, bool is3) {
+
+ // Trivial reply for unresolved lepton beams.
+ if (hasPointLeptons) {
+ tauMin = 1.;
+ tauMax = 1.;
+ return true;
+ }
+
+ // Requirements from allowed mHat range.
+ tauMin = sHatMin / s;
+ tauMax = (mHatMax < mHatMin) ? 1. : min( 1., sHatMax / s);
+
+ // Requirements from allowed pT range and masses.
+ if (is2 || is3) {
+ double mT3Min = sqrt(s3 + pT2HatMin);
+ double mT4Min = sqrt(s4 + pT2HatMin);
+ double mT5Min = (is3) ? sqrt(s5 + pT2HatMin) : 0.;
+ tauMin = max( tauMin, pow2(mT3Min + mT4Min + mT5Min) / s);
+ }
+
+ // Check that there is an open range.
+ return (tauMax > tauMin);
+}
+
+//*********
+
+// Find range of allowed y values.
+
+bool PhaseSpace::limitY() {
+
+ // Trivial reply for unresolved lepton beams.
+ if (hasPointLeptons) {
+ yMax = 1.;
+ return true;
+ }
+
+ // Requirements from selected tau value.
+ yMax = -0.5 * log(tau);
+
+ // For lepton beams requirements from cutoff for f_e^e.
+ double yMaxMargin = (hasLeptonBeams) ? yMax + LEPTONXLOGMAX : yMax;
+
+ // Check that there is an open range.
+ return (yMaxMargin > 0.);
+}
+
+//*********
+
+// Find range of allowed z = cos(theta) values.
+
+bool PhaseSpace::limitZ() {
+
+ // Default limits.
+ zMin = 0.;
+ zMax = 1.;
+
+ // Requirements from pTHat limits.
+ zMax = sqrtpos( 1. - pT2HatMin / p2Abs );
+ if (pTHatMax > pTHatMin) zMin = sqrtpos( 1. - pT2HatMax / p2Abs );
+
+ // Check that there is an open range.
+ return (zMax > zMin);
+}
+
+//*********
+
+// Select tau according to a choice of shapes.
+
+void PhaseSpace::selectTau(int iTau, double tauVal, bool is2) {
+
+ // Trivial reply for unresolved lepton beams.
+ if (hasPointLeptons) {
+ tau = 1.;
+ wtTau = 1.;
+ sH = s;
+ mHat = sqrt(sH);
+ if (is2) {
+ p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
+ pAbs = sqrtpos( p2Abs );
+ }
+ return;
+ }
+
+ // Contributions from s-channel resonances.
+ double tRatA = 0.;
+ double aLowA = 0.;
+ double aUppA = 0.;
+ if (idResA !=0) {
+ tRatA = ((tauResA + tauMax) / (tauResA + tauMin)) * (tauMin / tauMax);
+ aLowA = atan( (tauMin - tauResA) / widResA);
+ aUppA = atan( (tauMax - tauResA) / widResA);
+ }
+ double tRatB = 0.;
+ double aLowB = 0.;
+ double aUppB = 0.;
+ if (idResB != 0) {
+ tRatB = ((tauResB + tauMax) / (tauResB + tauMin)) * (tauMin / tauMax);
+ aLowB = atan( (tauMin - tauResB) / widResB);
+ aUppB = atan( (tauMax - tauResB) / widResB);
+ }
+
+ // Contributions from 1 / (1 - tau) for lepton beams.
+ double aLowT = 0.;
+ double aUppT = 0.;
+ if (hasLeptonBeams) {
+ aLowT = log( max( LEPTONTAUMIN, 1. - tauMin) );
+ aUppT = log( max( LEPTONTAUMIN, 1. - tauMax) );
+ intTau6 = aLowT - aUppT;
+ }
+
+ // Select according to 1/tau or 1/tau^2.
+ if (iTau == 0) tau = tauMin * pow( tauMax / tauMin, tauVal);
+ else if (iTau == 1) tau = tauMax * tauMin
+ / (tauMin + (tauMax - tauMin) * tauVal);
+
+ // Select according to 1 / (1 - tau) for lepton beams.
+ else if (hasLeptonBeams && iTau == nTau - 1)
+ tau = 1. - exp( aUppT + intTau6 * tauVal );
+
+ // Select according to 1 / (tau * (tau + tauRes)) or
+ // 1 / ((tau - tauRes)^2 + widRes^2) for resonances A and B.
+ else if (iTau == 2) tau = tauResA * tauMin
+ / ((tauResA + tauMin) * pow( tRatA, tauVal) - tauMin);
+ else if (iTau == 3) tau = tauResA + widResA
+ * tan( aLowA + (aUppA - aLowA) * tauVal);
+ else if (iTau == 4) tau = tauResB * tauMin
+ / ((tauResB + tauMin) * pow( tRatB, tauVal) - tauMin);
+ else if (iTau == 5) tau = tauResB + widResB
+ * tan( aLowB + (aUppB - aLowB) * tauVal);
+
+ // Phase space weight in tau.
+ intTau0 = log( tauMax / tauMin);
+ intTau1 = (tauMax - tauMin) / (tauMax * tauMin);
+ double invWtTau = (tauCoef[0] / intTau0) + (tauCoef[1] / intTau1) / tau;
+ if (idResA != 0) {
+ intTau2 = -log(tRatA) / tauResA;
+ intTau3 = (aUppA - aLowA) / widResA;
+ invWtTau += (tauCoef[2] / intTau2) / (tau + tauResA)
+ + (tauCoef[3] / intTau3) * tau / ( pow2(tau - tauResA) + pow2(widResA) );
+ }
+ if (idResB != 0) {
+ intTau4 = -log(tRatB) / tauResB;
+ intTau5 = (aUppB - aLowB) / widResB;
+ invWtTau += (tauCoef[4] / intTau4) / (tau + tauResB)
+ + (tauCoef[5] / intTau5) * tau / ( pow2(tau - tauResB) + pow2(widResB) );
+ }
+ if (hasLeptonBeams)
+ invWtTau += (tauCoef[nTau - 1] / intTau6)
+ * tau / max( LEPTONTAUMIN, 1. - tau);
+ wtTau = 1. / invWtTau;
+
+ // Calculate sHat and absolute momentum of outgoing partons.
+ sH = tau * s;
+ mHat = sqrt(sH);
+ if (is2) {
+ p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
+ pAbs = sqrtpos( p2Abs );
+ }
+
+}
+
+//*********
+
+// Select y according to a choice of shapes.
+
+void PhaseSpace::selectY(int iY, double yVal) {
+
+ // Trivial reply for unresolved lepton beams.
+ if (hasPointLeptons) {
+ y = 0.;
+ wtY = 1.;
+ x1H = 1.;
+ x2H = 1.;
+ return;
+ }
+
+ // Standard expressions used below.
+ double atanMax = atan( exp(yMax) );
+ double atanMin = atan( exp(-yMax) );
+ double aUppY = (hasLeptonBeams)
+ ? log( max( LEPTONXMIN, LEPTONXMAX / tau - 1. ) ) : 0.;
+ double aLowY = LEPTONXLOGMIN;
+
+ // y - y_min or mirrored y_max - y.
+ if (iY <= 1) y = yMax * (2. * sqrt(yVal) - 1.);
+
+ // 1 / cosh(y).
+ else if (iY == 2)
+ y = log( tan( atanMin + (atanMax - atanMin) * yVal ) );
+
+ // 1 / (1 - exp(y - y_max)) or mirrored 1 / (1 - exp(y_min - y)).
+ else y = yMax - log( 1. + exp(aLowY + (aUppY - aLowY) * yVal) );
+
+ // Mirror two cases.
+ if (iY == 1 || iY == 4) y = -y;
+
+ // Phase space integral in y.
+ intY01 = 0.5 * pow2(2. * yMax);
+ intY2 = 2. * (atanMax - atanMin);
+ intY34 = aUppY - aLowY;
+ double invWtY = (yCoef[0] / intY01) * (y + yMax)
+ + (yCoef[1] / intY01) * (yMax - y) + (yCoef[2] / intY2) / cosh(y);
+ if (hasLeptonBeams) invWtY
+ += (yCoef[3] / intY34) / max( LEPTONXMIN, 1. - exp( y - yMax) )
+ + (yCoef[4] / intY34) / max( LEPTONXMIN, 1. - exp(-y - yMax) );
+ wtY = 1. / invWtY;
+
+ // Calculate x1 and x2.
+ x1H = sqrt(tau) * exp(y);
+ x2H = sqrt(tau) * exp(-y);
+}
+
+//*********
+
+// Select z = cos(theta) according to a choice of shapes.
+// The selection is split in the positive- and negative-z regions,
+// since a pTmax cut can remove the region around z = 0.
+
+void PhaseSpace::selectZ(int iZ, double zVal) {
+
+ // Mass-dependent dampening of pT -> 0 limit.
+ ratio34 = max(TINY, 2. * s3 * s4 / pow2(sH));
+ unity34 = 1. + ratio34;
+ double ratiopT2 = 2. * pT2HatMin / max( SHATMINZ, sH);
+ if (ratiopT2 < PT2RATMINZ) ratio34 = max( ratio34, ratiopT2);
+
+ // Common expressions in z limits.
+ double zPosMax = max(ratio34, unity34 + zMax);
+ double zNegMax = max(ratio34, unity34 - zMax);
+ double zPosMin = max(ratio34, unity34 + zMin);
+ double zNegMin = max(ratio34, unity34 - zMin);
+
+ // Flat in z.
+ if (iZ == 0) {
+ if (zVal < 0.5) z = -(zMax + (zMin - zMax) * 2. * zVal);
+ else z = zMin + (zMax - zMin) * (2. * zVal - 1.);
+
+ // 1 / (unity34 - z).
+ } else if (iZ == 1) {
+ double areaNeg = log(zPosMax / zPosMin);
+ double areaPos = log(zNegMin / zNegMax);
+ double area = areaNeg + areaPos;
+ if (zVal * area < areaNeg) {
+ double zValMod = zVal * area / areaNeg;
+ z = unity34 - zPosMax * pow(zPosMin / zPosMax, zValMod);
+ } else {
+ double zValMod = (zVal * area - areaNeg)/ areaPos;
+ z = unity34 - zNegMin * pow(zNegMax / zNegMin, zValMod);
+ }
+
+ // 1 / (unity34 + z).
+ } else if (iZ == 2) {
+ double areaNeg = log(zNegMin / zNegMax);
+ double areaPos = log(zPosMax / zPosMin);
+ double area = areaNeg + areaPos;
+ if (zVal * area < areaNeg) {
+ double zValMod = zVal * area / areaNeg;
+ z = zNegMax * pow(zNegMin / zNegMax, zValMod) - unity34;
+ } else {
+ double zValMod = (zVal * area - areaNeg)/ areaPos;
+ z = zPosMin * pow(zPosMax / zPosMin, zValMod) - unity34;
+ }
+
+ // 1 / (unity34 - z)^2.
+ } else if (iZ == 3) {
+ double areaNeg = 1. / zPosMin - 1. / zPosMax;
+ double areaPos = 1. / zNegMax - 1. / zNegMin;
+ double area = areaNeg + areaPos;
+ if (zVal * area < areaNeg) {
+ double zValMod = zVal * area / areaNeg;
+ z = unity34 - 1. / (1./zPosMax + areaNeg * zValMod);
+ } else {
+ double zValMod = (zVal * area - areaNeg)/ areaPos;
+ z = unity34 - 1. / (1./zNegMin + areaPos * zValMod);
+ }
+
+ // 1 / (unity34 + z)^2.
+ } else if (iZ == 4) {
+ double areaNeg = 1. / zNegMax - 1. / zNegMin;
+ double areaPos = 1. / zPosMin - 1. / zPosMax;
+ double area = areaNeg + areaPos;
+ if (zVal * area < areaNeg) {
+ double zValMod = zVal * area / areaNeg;
+ z = 1. / (1./zNegMax - areaNeg * zValMod) - unity34;
+ } else {
+ double zValMod = (zVal * area - areaNeg)/ areaPos;
+ z = 1. / (1./zPosMin - areaPos * zValMod) - unity34;
+ }
+ }
+
+ // Safety check for roundoff errors. Combinations with z.
+ if (z < 0.) z = min(-zMin, max(-zMax, z));
+ else z = min(zMax, max(zMin, z));
+ zNeg = max(ratio34, unity34 - z);
+ zPos = max(ratio34, unity34 + z);
+
+ // Phase space integral in z.
+ double intZ0 = 2. * (zMax - zMin);
+ double intZ12 = log( (zPosMax * zNegMin) / (zPosMin * zNegMax) );
+ double intZ34 = 1. / zPosMin - 1. / zPosMax + 1. / zNegMax
+ - 1. / zNegMin;
+ wtZ = mHat * pAbs / ( (zCoef[0] / intZ0) + (zCoef[1] / intZ12) / zNeg
+ + (zCoef[2] / intZ12) / zPos + (zCoef[3] / intZ34) / pow2(zNeg)
+ + (zCoef[4] / intZ34) / pow2(zPos) );
+
+ // Calculate tHat and uHat. Also gives pTHat.
+ double sH34 = -0.5 * (sH - s3 - s4);
+ tH = sH34 + mHat * pAbs * z;
+ uH = sH34 - mHat * pAbs * z;
+ pTH = sqrtpos( (tH * uH - s3 * s4) / sH);
+
+}
+
+//*********
+
+// Select three-body phase space according to a cylindrically based form
+// that can be chosen to favour low pT based on the form of propagators.
+
+bool PhaseSpace::select3Body() {
+
+ // Upper and lower limits of pT choice for 4 and 5.
+ double m35S = pow2(m3 + m5);
+ double pT4Smax = 0.25 * ( pow2(sH - s4 - m35S) - 4. * s4 * m35S ) / sH;
+ if (pTHatMax > pTHatMin) pT4Smax = min( pT2HatMax, pT4Smax);
+ double pT4Smin = pT2HatMin;
+ double m34S = pow2(m3 + m4);
+ double pT5Smax = 0.25 * ( pow2(sH - s5 - m34S) - 4. * s5 * m34S ) / sH;
+ if (pTHatMax > pTHatMin) pT5Smax = min( pT2HatMax, pT5Smax);
+ double pT5Smin = pT2HatMin;
+
+ // Check that pT ranges not closed.
+ if ( pT4Smax < pow2(pTHatMin + MASSMARGIN) ) return false;
+ if ( pT5Smax < pow2(pTHatMin + MASSMARGIN) ) return false;
+
+ // Select pT4S according to c0 + c1/(M^2 + pT^2) + c2/(M^2 + pT^2)^2.
+ double pTSmaxProp = pT4Smax + sTchan1;
+ double pTSminProp = pT4Smin + sTchan1;
+ double pTSratProp = pTSmaxProp / pTSminProp;
+ double pTSdiff = pT4Smax - pT4Smin;
+ double rShape = Rndm::flat();
+ double pT4S = 0.;
+ if (rShape < frac3Flat) pT4S = pT4Smin + Rndm::flat() * pTSdiff;
+ else if (rShape < frac3Flat + frac3Pow1) pT4S = max( pT2HatMin,
+ pTSminProp * pow( pTSratProp, Rndm::flat() ) - sTchan1 );
+ else pT4S = max( pT2HatMin, pTSminProp * pTSmaxProp
+ / (pTSminProp + Rndm::flat()* pTSdiff) - sTchan1 );
+ double wt4 = pTSdiff / ( frac3Flat
+ + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT4S + sTchan1))
+ + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT4S + sTchan1) );
+
+ // Select pT5S according to c0 + c1/(M^2 + pT^2) + c2/(M^2 + pT^2)^2.
+ pTSmaxProp = pT5Smax + sTchan2;
+ pTSminProp = pT5Smin + sTchan2;
+ pTSratProp = pTSmaxProp / pTSminProp;
+ pTSdiff = pT5Smax - pT5Smin;
+ rShape = Rndm::flat();
+ double pT5S = 0.;
+ if (rShape < frac3Flat) pT5S = pT5Smin + Rndm::flat() * pTSdiff;
+ else if (rShape < frac3Flat + frac3Pow1) pT5S = max( pT2HatMin,
+ pTSminProp * pow( pTSratProp, Rndm::flat() ) - sTchan2 );
+ else pT5S = max( pT2HatMin, pTSminProp * pTSmaxProp
+ / (pTSminProp + Rndm::flat()* pTSdiff) - sTchan2 );
+ double wt5 = pTSdiff / ( frac3Flat
+ + frac3Pow1 * pTSdiff / (log(pTSratProp) * (pT5S + sTchan2))
+ + frac3Pow2 * pTSminProp * pTSmaxProp / pow2(pT5S + sTchan2) );
+
+ // Select azimuthal angles and check that third pT in range.
+ double phi4 = 2. * M_PI * Rndm::flat();
+ double phi5 = 2. * M_PI * Rndm::flat();
+ double pT3S = max( 0., pT4S + pT5S + 2. * sqrt(pT4S * pT5S)
+ * cos(phi4 - phi5) );
+ if ( pT3S < pT2HatMin || (pTHatMax > pTHatMin && pT3S > pT2HatMax) )
+ return false;
+
+ // Calculate transverse masses and check that phase space not closed.
+ double sT3 = s3 + pT3S;
+ double sT4 = s4 + pT4S;
+ double sT5 = s5 + pT5S;
+ double mT3 = sqrt(sT3);
+ double mT4 = sqrt(sT4);
+ double mT5 = sqrt(sT5);
+ if ( mT3 + mT4 + mT5 + MASSMARGIN > mHat ) return false;
+
+ // Select rapidity for particle 3 and check that phase space not closed.
+ double m45S = pow2(mT4 + mT5);
+ double y3max = log( ( sH + sT3 - m45S + sqrtpos( pow2(sH - sT3 - m45S)
+ - 4 * sT3 * m45S ) ) / (2. * mHat * mT3) );
+ if (y3max < YRANGEMARGIN) return false;
+ double y3 = (2. * Rndm::flat() - 1.) * (1. - YRANGEMARGIN) * y3max;
+ double pz3 = mT3 * sinh(y3);
+ double e3 = mT3 * cosh(y3);
+
+ // Find momentum transfers in the two mirror solutions (in 4-5 frame).
+ double pz45 = -pz3;
+ double e45 = mHat - e3;
+ double sT45 = e45 * e45 - pz45 * pz45;
+ double lam45 = sqrtpos( pow2(sT45 - sT4 - sT5) - 4. * sT4 * sT5 );
+ if (lam45 < YRANGEMARGIN * sH) return false;
+ double lam4e = sT45 + sT4 - sT5;
+ double lam5e = sT45 + sT5 - sT4;
+ double tFac = -0.5 * mHat / sT45;
+ double t1Pos = tFac * (e45 - pz45) * (lam4e - lam45);
+ double t1Neg = tFac * (e45 - pz45) * (lam4e + lam45);
+ double t2Pos = tFac * (e45 + pz45) * (lam5e - lam45);
+ double t2Neg = tFac * (e45 + pz45) * (lam5e + lam45);
+
+ // Construct relative mirror weights and make choice.
+ double wtPosUnnorm = 1.;
+ double wtNegUnnorm = 1.;
+ if (useMirrorWeight) {
+ wtPosUnnorm = 1./ pow2( (t1Pos - sTchan1) * (t2Pos - sTchan2) );
+ wtNegUnnorm = 1./ pow2( (t1Neg - sTchan1) * (t2Neg - sTchan2) );
+ }
+ double wtPos = wtPosUnnorm / (wtPosUnnorm + wtNegUnnorm);
+ double wtNeg = wtNegUnnorm / (wtPosUnnorm + wtNegUnnorm);
+ double epsilon = (Rndm::flat() < wtPos) ? 1. : -1.;
+
+ // Construct four-vectors in rest frame of subprocess.
+ double px4 = sqrt(pT4S) * cos(phi4);
+ double py4 = sqrt(pT4S) * sin(phi4);
+ double px5 = sqrt(pT5S) * cos(phi5);
+ double py5 = sqrt(pT5S) * sin(phi5);
+ double pz4 = 0.5 * (pz45 * lam4e + epsilon * e45 * lam45) / sT45;
+ double pz5 = pz45 - pz4;
+ double e4 = sqrt(sT4 + pz4 * pz4);
+ double e5 = sqrt(sT5 + pz5 * pz5);
+ p3cm = Vec4( -(px4 + px5), -(py4 + py5), pz3, e3);
+ p4cm = Vec4( px4, py4, pz4, e4);
+ p5cm = Vec4( px5, py5, pz5, e5);
+
+ // Total weight to associate with kinematics choice.
+ wt3Body = wt4 * wt5 * (2. * y3max) / (128. * pow3(M_PI) * lam45);
+ wt3Body *= (epsilon > 0.) ? 1. / wtPos : 1. / wtNeg;
+
+ // Cross section of form |M|^2/(2 sHat) dPS_3 so need 1/(2 sHat).
+ wt3Body /= (2. * sH);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Solve linear equation system for better phase space coefficients.
+
+void PhaseSpace::solveSys( int n, int bin[8], double vec[8],
+ double mat[8][8], double coef[8], ostream& os) {
+
+ // Optional printout.
+ if (showSearch) {
+ os << "\n Equation system: " << setw(5) << bin[0];
+ for (int j = 0; j < n; ++j) os << setw(12) << mat[0][j];
+ os << setw(12) << vec[0] << "\n";
+ for (int i = 1; i < n; ++i) {
+ os << " " << setw(5) << bin[i];
+ for (int j = 0; j < n; ++j) os << setw(12) << mat[i][j];
+ os << setw(12) << vec[i] << "\n";
+ }
+ }
+
+ // Local variables.
+ double vecNor[8], coefTmp[8];
+ for (int i = 0; i < n; ++i) coefTmp[i] = 0.;
+
+ // Check if equation system solvable.
+ bool canSolve = true;
+ for (int i = 0; i < n; ++i) if (bin[i] == 0) canSolve = false;
+ double vecSum = 0.;
+ for (int i = 0; i < n; ++i) vecSum += vec[i];
+ if (abs(vecSum) < TINY) canSolve = false;
+
+ // Solve to find relative importance of cross-section pieces.
+ if (canSolve) {
+ for (int i = 0; i < n; ++i) vecNor[i] = max( 0.1, vec[i] / vecSum);
+ for (int k = 0; k < n - 1; ++k) {
+ for (int i = k + 1; i < n; ++i) {
+ if (abs(mat[k][k]) < TINY) {canSolve = false; break;}
+ double ratio = mat[i][k] / mat[k][k];
+ vec[i] -= ratio * vec[k];
+ for (int j = k; j < n; ++j) mat[i][j] -= ratio * mat[k][j];
+ }
+ if (!canSolve) break;
+ }
+ if (canSolve) {
+ for (int k = n - 1; k >= 0; --k) {
+ for (int j = k + 1; j < n; ++j) vec[k] -= mat[k][j] * coefTmp[j];
+ coefTmp[k] = vec[k] / mat[k][k];
+ }
+ }
+ }
+
+ // Share evenly if failure.
+ if (!canSolve) for (int i = 0; i < n; ++i) {
+ coefTmp[i] = 1.;
+ vecNor[i] = 0.1;
+ if (vecSum > TINY) vecNor[i] = max(0.1, vec[i] / vecSum);
+ }
+
+ // Normalize coefficients, with piece shared democratically.
+ double coefSum = 0.;
+ vecSum = 0.;
+ for (int i = 0; i < n; ++i) {
+ coefTmp[i] = max( 0., coefTmp[i]);
+ coefSum += coefTmp[i];
+ vecSum += vecNor[i];
+ }
+ if (coefSum > 0.) for (int i = 0; i < n; ++i) coef[i] = EVENFRAC / n
+ + (1. - EVENFRAC) * 0.5 * (coefTmp[i] / coefSum + vecNor[i] / vecSum);
+ else for (int i = 0; i < n; ++i) coef[i] = 1. / n;
+
+ // Optional printout.
+ if (showSearch) {
+ os << " Solution: ";
+ for (int i = 0; i < n; ++i) os << setw(12) << coef[i];
+ os << "\n";
+ }
+}
+
+//*********
+
+// Setup mass selection for one resonance at a time - part 1.
+
+void PhaseSpace::setupMass1(int iM) {
+
+ // Identity for mass seletion; is 0 also for light quarks (not yet selected).
+ if (iM == 3) idMass[iM] = abs(sigmaProcessPtr->id3Mass());
+ if (iM == 4) idMass[iM] = abs(sigmaProcessPtr->id4Mass());
+ if (iM == 5) idMass[iM] = abs(sigmaProcessPtr->id5Mass());
+
+ // Masses and widths of resonances.
+ if (idMass[iM] == 0) {
+ mPeak[iM] = 0.;
+ mWidth[iM] = 0.;
+ mMin[iM] = 0.;
+ mMax[iM] = 0.;
+ } else {
+ mPeak[iM] = ParticleDataTable::m0(idMass[iM]);
+ mWidth[iM] = ParticleDataTable::mWidth(idMass[iM]);
+ mMin[iM] = ParticleDataTable::mMin(idMass[iM]);
+ mMax[iM] = ParticleDataTable::mMax(idMass[iM]);
+ // gmZmode == 1 means pure photon propagator; set at lower mass limit.
+ if (idMass[iM] == 23 && gmZmode == 1) mPeak[iM] = mMin[iM];
+ }
+
+ // Mass and width combinations for Breit-Wigners.
+ sPeak[iM] = mPeak[iM] * mPeak[iM];
+ useBW[iM] = useBreitWigners && (mWidth[iM] > minWidthBreitWigners);
+ if (!useBW[iM]) mWidth[iM] = 0.;
+ mw[iM] = mPeak[iM] * mWidth[iM];
+ wmRat[iM] = (idMass[iM] == 0 || mPeak[iM] == 0.)
+ ? 0. : mWidth[iM] / mPeak[iM];
+
+ // Simple Breit-Wigner range, upper edge to be corrected subsequently.
+ if (useBW[iM]) {
+ mLower[iM] = mMin[iM];
+ mUpper[iM] = mHatMax;
+ }
+
+}
+
+//*********
+
+// Setup mass selection for one resonance at a time - part 2.
+
+void PhaseSpace::setupMass2(int iM, double distToThresh) {
+
+ // Store reduced Breit-Wigner range.
+ if (mMax[iM] > mMin[iM]) mUpper[iM] = min( mUpper[iM], mMax[iM]);
+ sLower[iM] = mLower[iM] * mLower[iM];
+ sUpper[iM] = mUpper[iM] * mUpper[iM];
+
+ // Prepare to select m3 by BW + flat + 1/s_3.
+ // Determine relative coefficients by allowed mass range.
+ if (distToThresh > THRESHOLDSIZE) {
+ fracFlat[iM] = 0.1;
+ fracInv[iM] = 0.1;
+ } else if (distToThresh > - THRESHOLDSIZE) {
+ fracFlat[iM] = 0.25 - 0.15 * distToThresh / THRESHOLDSIZE;
+ fracInv [iM] = 0.15 - 0.05 * distToThresh / THRESHOLDSIZE;
+ } else {
+ fracFlat[iM] = 0.4;
+ fracInv[iM] = 0.2;
+ }
+
+ // For gamma*/Z0: increase 1/s_i part and introduce 1/s_i^2 part.
+ fracInv2[iM] = 0.;
+ if (idMass[iM] == 23 && gmZmode == 0) {
+ fracFlat[iM] *= 0.5;
+ fracInv[iM] = 0.5 * fracInv[iM] + 0.25;
+ fracInv2[iM] = 0.25;
+ } else if (idMass[iM] == 23 && gmZmode == 1) {
+ fracFlat[iM] = 0.1;
+ fracInv[iM] = 0.4;
+ fracInv2[iM] = 0.4;
+ }
+
+ // Normalization integrals for the respective contribution.
+ atanLower[iM] = atan( (sLower[iM] - sPeak[iM])/ mw[iM] );
+ atanUpper[iM] = atan( (sUpper[iM] - sPeak[iM])/ mw[iM] );
+ intBW[iM] = atanUpper[iM] - atanLower[iM];
+ intFlat[iM] = sUpper[iM] - sLower[iM];
+ intInv[iM] = log( sUpper[iM] / sLower[iM] );
+ intInv2[iM] = 1./sLower[iM] - 1./sUpper[iM];
+
+}
+
+//*********
+
+// Select Breit-Wigner-distributed or fixed masses.
+
+void PhaseSpace::trialMass(int iM) {
+
+ // References to masses to be set.
+ double& mSet = (iM == 3) ? m3 : ( (iM == 4) ? m4 : m5 );
+ double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
+
+ // Distribution for m_i is BW + flat + 1/s_i + 1/s_i^2.
+ if (useBW[iM]) {
+ double pickForm = Rndm::flat();
+ if (pickForm > fracFlat[iM] + fracInv[iM] + fracInv2[iM])
+ sSet = sPeak[iM] + mw[iM] * tan( atanLower[iM]
+ + Rndm::flat() * intBW[iM] );
+ else if (pickForm > fracInv[iM] + fracInv2[iM])
+ sSet = sLower[iM] + Rndm::flat() * (sUpper[iM] - sLower[iM]);
+ else if (pickForm > fracInv2[iM])
+ sSet = sLower[iM] * pow( sUpper[iM] / sLower[iM], Rndm::flat() );
+ else sSet = sLower[iM] * sUpper[iM]
+ / (sLower[iM] + Rndm::flat() * (sUpper[iM] - sLower[iM]));
+ mSet = sqrt(sSet);
+
+ // Else m_i is fixed at peak value.
+ } else {
+ mSet = mPeak[iM];
+ sSet = sPeak[iM];
+ }
+
+}
+
+//*********
+
+// Naively a fixed-width Breit-Wigner is used to pick the mass.
+// Here come the correction factors for
+// (i) preselection according to BW + flat in s_i + 1/s_i + 1/s_i^2,
+// (ii) reduced allowed mass range,
+// (iii) running width, i.e. m0*Gamma0 -> s*Gamma0/m0.
+// In the end, the weighted distribution is a running-width BW.
+
+double PhaseSpace::weightMass(int iM) {
+
+ // Reference to mass and to Breit-Wigner weight to be set.
+ double& sSet = (iM == 3) ? s3 : ( (iM == 4) ? s4 : s5 );
+ double& runBWH = (iM == 3) ? runBW3H : ( (iM == 4) ? runBW4H : runBW5H );
+
+ // Default weight if no Breit-Wigner.
+ runBWH = 1.;
+ if (!useBW[iM]) return 1.;
+
+ // Weight of generated distribution.
+ double genBW = (1. - fracFlat[iM] - fracInv[iM] - fracInv2[iM])
+ * mw[iM] / ( (pow2(sSet - sPeak[iM]) + pow2(mw[iM])) * intBW[iM])
+ + fracFlat[iM] / intFlat[iM] + fracInv[iM] / (sSet * intInv[iM])
+ + fracInv2[iM] / (sSet*sSet * intInv2[iM]);
+
+ // Weight of distribution with running width in Breit-Wigner.
+ double mwRun = sSet * wmRat[iM];
+ runBWH = mwRun / (pow2(sSet - sPeak[iM]) + pow2(mwRun)) / M_PI;
+
+ // Done.
+ return (runBWH / genBW);
+
+}
+
+//**************************************************************************
+
+// PhaseSpace2to1tauy class.
+// 2 -> 1 kinematics for normal subprocesses.
+
+//*********
+
+// Set limits for resonance mass selection.
+
+bool PhaseSpace2to1tauy::setupMass() {
+
+ // Treat Z0 as such or as gamma*/Z0
+ gmZmode = gmZmodeGlobal;
+ int gmZmodeProc = sigmaProcessPtr->gmZmode();
+ if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
+
+ // Mass limits for current resonance.
+ int idRes = abs(sigmaProcessPtr->resonanceA());
+ int idTmp = abs(sigmaProcessPtr->resonanceB());
+ if (idTmp > 0) idRes = idTmp;
+ double mResMin = (idRes == 0) ? 0. : ParticleDataTable::mMin(idRes);
+ double mResMax = (idRes == 0) ? 0. : ParticleDataTable::mMax(idRes);
+
+ // Compare with global mass limits and pick tighter of them.
+ mHatMin = max( mResMin, mHatGlobalMin);
+ sHatMin = mHatMin*mHatMin;
+ mHatMax = eCM;
+ if (mResMax > mResMin) mHatMax = min( mHatMax, mResMax);
+ if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( mHatMax, mHatGlobalMax);
+ sHatMax = mHatMax*mHatMax;
+
+ // Default Breit-Wigner weight.
+ wtBW = 1.;
+
+ // Fail if mass window (almost) closed.
+ return (mHatMax > mHatMin + MASSMARGIN);
+
+}
+
+//*********
+
+// Construct the four-vector kinematics from the trial values.
+
+bool PhaseSpace2to1tauy::finalKin() {
+
+ // Particle masses; incoming always on mass shell.
+ mH[1] = 0.;
+ mH[2] = 0.;
+ mH[3] = mHat;
+
+ // Incoming partons along beam axes. Outgoing has sum of momenta.
+ pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
+ pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
+ pH[3] = pH[1] + pH[2];
+
+ // Done.
+ return true;
+}
+
+//**************************************************************************
+
+// PhaseSpace2to2tauyz class.
+// 2 -> 2 kinematics for normal subprocesses.
+
+//*********
+
+// Set up for fixed or Breit-Wigner mass selection.
+
+bool PhaseSpace2to2tauyz::setupMasses() {
+
+ // Treat Z0 as such or as gamma*/Z0
+ gmZmode = gmZmodeGlobal;
+ int gmZmodeProc = sigmaProcessPtr->gmZmode();
+ if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
+
+ // Set sHat limits - based on global limits only.
+ mHatMin = mHatGlobalMin;
+ sHatMin = mHatMin*mHatMin;
+ mHatMax = eCM;
+ if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
+ sHatMax = mHatMax*mHatMax;
+
+ // Masses and widths of resonances.
+ setupMass1(3);
+ setupMass1(4);
+
+ // Reduced mass range when two massive particles.
+ if (useBW[3]) mUpper[3] -= (useBW[4]) ? mMin[4] : mPeak[4];
+ if (useBW[4]) mUpper[4] -= (useBW[3]) ? mMin[3] : mPeak[3];
+
+ // If closed phase space then unallowed process.
+ bool physical = true;
+ if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical = false;
+ if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical = false;
+ if (!useBW[3] && !useBW[4] && mHatMax < mPeak[3] + mPeak[4] + MASSMARGIN)
+ physical = false;
+ if (!physical) return false;
+
+ // If either particle is massless then need extra pTHat cut.
+ pTHatMin = pTHatGlobalMin;
+ if (mPeak[3] < pTHatMinDiverge || mPeak[4] < pTHatMinDiverge)
+ pTHatMin = max( pTHatMin, pTHatMinDiverge);
+ pT2HatMin = pTHatMin * pTHatMin;
+ pTHatMax = pTHatGlobalMax;
+ pT2HatMax = pTHatMax * pTHatMax;
+
+ // Prepare to select m3 by BW + flat + 1/s_3.
+ if (useBW[3]) {
+ double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[3]
+ / (pow2(mWidth[3]) + pow2(mWidth[4]));
+ double distToThreshB = (mHatMax - mPeak[3] - mMin[4]) / mWidth[3];
+ double distToThresh = min( distToThreshA, distToThreshB);
+ setupMass2(3, distToThresh);
+ }
+
+ // Prepare to select m4 by BW + flat + 1/s_4.
+ if (useBW[4]) {
+ double distToThreshA = (mHatMax - mPeak[3] - mPeak[4]) * mWidth[4]
+ / (pow2(mWidth[3]) + pow2(mWidth[4]));
+ double distToThreshB = (mHatMax - mMin[3] - mPeak[4]) / mWidth[4];
+ double distToThresh = min( distToThreshA, distToThreshB);
+ setupMass2(4, distToThresh);
+ }
+
+ // Initialization masses. Special cases when constrained phase space.
+ m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
+ m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
+ if (m3 + m4 + THRESHOLDSIZE * (mWidth[3] + mWidth[4]) + MASSMARGIN
+ > mHatMax) {
+ if (useBW[3] && useBW[4]) physical = constrainedM3M4();
+ else if (useBW[3]) physical = constrainedM3();
+ else if (useBW[4]) physical = constrainedM4();
+ }
+ s3 = m3*m3;
+ s4 = m4*m4;
+
+ // Correct selected mass-spectrum to running-width Breit-Wigner.
+ // Extra safety margin for maximum search.
+ wtBW = 1.;
+ if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
+ if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
+
+ // Done.
+ return physical;
+
+}
+
+
+//*********
+
+// Select Breit-Wigner-distributed or fixed masses.
+
+bool PhaseSpace2to2tauyz::trialMasses() {
+
+ // By default vanishing cross section.
+ sigmaNw = 0.;
+ wtBW = 1.;
+
+ // Pick m3 and m4 independently.
+ trialMass(3);
+ trialMass(4);
+
+ // If outside phase space then reject event.
+ if (m3 + m4 + MASSMARGIN > mHatMax) return false;
+
+ // Correct selected mass-spectrum to running-width Breit-Wigner.
+ if (useBW[3]) wtBW *= weightMass(3);
+ if (useBW[4]) wtBW *= weightMass(4);
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Construct the four-vector kinematics from the trial values.
+
+bool PhaseSpace2to2tauyz::finalKin() {
+
+ // Assign masses to particles assumed massless in matrix elements.
+ int id3 = sigmaProcessPtr->id(3);
+ int id4 = sigmaProcessPtr->id(4);
+ if (idMass[3] == 0) { m3 = ParticleDataTable::m0(id3); s3 = m3*m3; }
+ if (idMass[4] == 0) { m4 = ParticleDataTable::m0(id4); s4 = m4*m4; }
+
+ // Sometimes swap tHat <-> uHat to reflect chosen final-state order.
+ if (sigmaProcessPtr->swappedTU()) {
+ swap(tH, uH);
+ z = -z;
+ }
+
+ // Check that phase space still open after new mass assignment.
+ if (m3 + m4 + MASSMARGIN > mHat) {
+ infoPtr->errorMsg("Warning in PhaseSpace2to2tauyz::finalKin: "
+ "failed after mass assignment");
+ return false;
+ }
+ p2Abs = 0.25 * (pow2(sH - s3 - s4) - 4. * s3 * s4) / sH;
+ pAbs = sqrtpos( p2Abs );
+
+ // Particle masses; incoming always on mass shell.
+ mH[1] = 0.;
+ mH[2] = 0.;
+ mH[3] = m3;
+ mH[4] = m4;
+
+ // Incoming partons along beam axes.
+ pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
+ pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
+
+ // Outgoing partons initially in collision CM frame along beam axes.
+ pH[3] = Vec4( 0., 0., pAbs, 0.5 * (sH + s3 - s4) / mHat);
+ pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (sH + s4 - s3) / mHat);
+
+ // Then rotate and boost them to overall CM frame
+ theta = acos(z);
+ phi = 2. * M_PI * Rndm::flat();
+ betaZ = (x1H - x2H)/(x1H + x2H);
+ pH[3].rot( theta, phi);
+ pH[4].rot( theta, phi);
+ pH[3].bst( 0., 0., betaZ);
+ pH[4].bst( 0., 0., betaZ);
+ pTH = pAbs * sin(theta);
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Special choice of m3 and m4 when mHatMax push them off mass shell.
+// Vary x in expression m3 + m4 = mHatMax - x * (Gamma3 + Gamma4).
+// For each x try to put either 3 or 4 as close to mass shell as possible.
+// Maximize BW_3 * BW_4 * beta_34, where latter approximate phase space.
+
+bool PhaseSpace2to2tauyz::constrainedM3M4() {
+
+ // Initial values.
+ bool foundNonZero = false;
+ double wtMassMax = 0.;
+ double m3WtMax = 0.;
+ double m4WtMax = 0.;
+ double xMax = (mHatMax - mLower[3] - mLower[4]) / (mWidth[3] + mWidth[4]);
+ double xStep = THRESHOLDSTEP * min(1., xMax);
+ double xNow = 0.;
+ double wtMassXbin, wtMassMaxOld, m34, mT34Min, wtMassNow,
+ wtBW3Now, wtBW4Now, beta34Now;
+
+ // Step through increasing x values.
+ do {
+ xNow += xStep;
+ wtMassXbin = 0.;
+ wtMassMaxOld = wtMassMax;
+ m34 = mHatMax - xNow * (mWidth[3] + mWidth[4]);
+
+ // Study point where m3 as close as possible to on-shell.
+ m3 = min( mUpper[3], m34 - mLower[4]);
+ if (m3 > mPeak[3]) m3 = max( mLower[3], mPeak[3]);
+ m4 = m34 - m3;
+ if (m4 < mLower[4]) {m4 = mLower[4]; m3 = m34 - m4;}
+
+ // Check that inside phase space limit set by pTmin.
+ mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
+ if (mT34Min < mHatMax) {
+
+ // Breit-Wigners and beta factor give total weight.
+ wtMassNow = 0.;
+ if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
+ && m4 < mUpper[4]) {
+ wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
+ wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
+ beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
+ - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
+ wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
+ }
+
+ // Store new maximum, if any.
+ if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
+ if (wtMassNow > wtMassMax) {
+ foundNonZero = true;
+ wtMassMax = wtMassNow;
+ m3WtMax = m3;
+ m4WtMax = m4;
+ }
+ }
+
+ // Study point where m4 as close as possible to on-shell.
+ m4 = min( mUpper[4], m34 - mLower[3]);
+ if (m4 > mPeak[4]) m4 = max( mLower[4], mPeak[4]);
+ m3 = m34 - m4;
+ if (m3 < mLower[3]) {m3 = mLower[3]; m4 = m34 - m3;}
+
+ // Check that inside phase space limit set by pTmin.
+ mT34Min = sqrt(m3*m3 + pT2HatMin) + sqrt(m4*m4 + pT2HatMin);
+ if (mT34Min < mHatMax) {
+
+ // Breit-Wigners and beta factor give total weight.
+ wtMassNow = 0.;
+ if (m3 > mLower[3] && m3 < mUpper[3] && m4 > mLower[4]
+ && m4 < mUpper[4]) {
+ wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
+ wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
+ beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
+ - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
+ wtMassNow = wtBW3Now * wtBW4Now * beta34Now;
+ }
+
+ // Store new maximum, if any.
+ if (wtMassNow > wtMassXbin) wtMassXbin = wtMassNow;
+ if (wtMassNow > wtMassMax) {
+ foundNonZero = true;
+ wtMassMax = wtMassNow;
+ m3WtMax = m3;
+ m4WtMax = m4;
+ }
+ }
+
+ // Continue stepping if increasing trend and more x range available.
+ } while ( (!foundNonZero || wtMassXbin > wtMassMaxOld)
+ && xNow < xMax - xStep);
+
+ // Restore best values for subsequent maximization. Return.
+ m3 = m3WtMax;
+ m4 = m4WtMax;
+ return foundNonZero;
+
+}
+
+//*********
+
+// Special choice of m3 when mHatMax pushes it off mass shell.
+// Vary x in expression m3 = mHatMax - m4 - x * Gamma3.
+// Maximize BW_3 * beta_34, where latter approximate phase space.
+
+bool PhaseSpace2to2tauyz::constrainedM3() {
+
+ // Initial values.
+ bool foundNonZero = false;
+ double wtMassMax = 0.;
+ double m3WtMax = 0.;
+ double mT4Min = sqrt(m4*m4 + pT2HatMin);
+ double xMax = (mHatMax - mLower[3] - m4) / mWidth[3];
+ double xStep = THRESHOLDSTEP * min(1., xMax);
+ double xNow = 0.;
+ double wtMassNow, mT34Min, wtBW3Now, beta34Now;
+
+ // Step through increasing x values; gives m3 unambiguously.
+ do {
+ xNow += xStep;
+ wtMassNow = 0.;
+ m3 = mHatMax - m4 - xNow * mWidth[3];
+
+ // Check that inside phase space limit set by pTmin.
+ mT34Min = sqrt(m3*m3 + pT2HatMin) + mT4Min;
+ if (mT34Min < mHatMax) {
+
+ // Breit-Wigner and beta factor give total weight.
+ wtBW3Now = mw[3] / ( pow2(m3*m3 - sPeak[3]) + pow2(mw[3]) );
+ beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
+ - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
+ wtMassNow = wtBW3Now * beta34Now;
+
+ // Store new maximum, if any.
+ if (wtMassNow > wtMassMax) {
+ foundNonZero = true;
+ wtMassMax = wtMassNow;
+ m3WtMax = m3;
+ }
+ }
+
+ // Continue stepping if increasing trend and more x range available.
+ } while ( (!foundNonZero || wtMassNow > wtMassMax)
+ && xNow < xMax - xStep);
+
+ // Restore best value for subsequent maximization. Return.
+ m3 = m3WtMax;
+ return foundNonZero;
+
+}
+
+//*********
+
+// Special choice of m4 when mHatMax pushes it off mass shell.
+// Vary x in expression m4 = mHatMax - m3 - x * Gamma4.
+// Maximize BW_4 * beta_34, where latter approximate phase space.
+
+bool PhaseSpace2to2tauyz::constrainedM4() {
+
+ // Initial values.
+ bool foundNonZero = false;
+ double wtMassMax = 0.;
+ double m4WtMax = 0.;
+ double mT3Min = sqrt(m3*m3 + pT2HatMin);
+ double xMax = (mHatMax - mLower[4] - m3) / mWidth[4];
+ double xStep = THRESHOLDSTEP * min(1., xMax);
+ double xNow = 0.;
+ double wtMassNow, mT34Min, wtBW4Now, beta34Now;
+
+ // Step through increasing x values; gives m4 unambiguously.
+ do {
+ xNow += xStep;
+ wtMassNow = 0.;
+ m4 = mHatMax - m3 - xNow * mWidth[4];
+
+ // Check that inside phase space limit set by pTmin.
+ mT34Min = mT3Min + sqrt(m4*m4 + pT2HatMin);
+ if (mT34Min < mHatMax) {
+
+ // Breit-Wigner and beta factor give total weight.
+ wtBW4Now = mw[4] / ( pow2(m4*m4 - sPeak[4]) + pow2(mw[4]) );
+ beta34Now = sqrt( pow2(mHatMax*mHatMax - m3*m3 - m4*m4)
+ - pow2(2. * m3 * m4) ) / (mHatMax*mHatMax);
+ wtMassNow = wtBW4Now * beta34Now;
+
+ // Store new maximum, if any.
+ if (wtMassNow > wtMassMax) {
+ foundNonZero = true;
+ wtMassMax = wtMassNow;
+ m4WtMax = m4;
+ }
+ }
+
+ // Continue stepping if increasing trend and more x range available.
+ } while ( (!foundNonZero || wtMassNow > wtMassMax)
+ && xNow < xMax - xStep);
+
+ // Restore best value for subsequent maximization.
+ m4 = m4WtMax;
+ return foundNonZero;
+
+}
+
+//**************************************************************************
+
+// PhaseSpace2to2elastic class.
+// 2 -> 2 kinematics set up for elastic scattering.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maximum positive/negative argument for exponentiation.
+const double PhaseSpace2to2elastic::EXPMAX = 50.;
+
+// Conversion coefficients = 1/(16pi) * (mb <-> GeV^2).
+const double PhaseSpace2to2elastic::CONVERTEL = 0.0510925;
+
+//*********
+
+// Form of phase space sampling already fixed, so no optimization.
+// However, need to read out relevant parameters from SigmaTotal.
+
+bool PhaseSpace2to2elastic::setupSampling() {
+
+ // Find maximum = value of cross section.
+ sigmaNw = sigmaProcessPtr->sigmaHatWrap();
+ sigmaMx = sigmaNw;
+
+ // Squared masses of particles.
+ s1 = mA * mA;
+ s2 = mB * mB;
+
+ // Elastic slope.
+ bSlope = sigmaTotPtr->bSlopeEl();
+
+ // Determine maximum possible t range.
+ lambda12S = pow2(s - s1 - s2) - 4. * s1 * s2 ;
+ tLow = - lambda12S / s;
+ tUpp = 0;
+
+ // Production model with Coulomb corrections need more parameters.
+ useCoulomb = Settings::flag("SigmaTotal:setOwn")
+ && Settings::flag("SigmaElastic:setOwn");
+ if (useCoulomb) {
+ sigmaTot = sigmaTotPtr->sigmaTot();
+ rho = Settings::parm("SigmaElastic:rho");
+ lambda = Settings::parm("SigmaElastic:lambda");
+ tAbsMin = Settings::parm("SigmaElastic:tAbsMin");
+ phaseCst = Settings::parm("SigmaElastic:phaseConst");
+ alphaEM0 = Settings::parm("StandardModel:alphaEM0");
+
+ // Relative rate of nuclear and Coulombic parts in trials.
+ tUpp = -tAbsMin;
+ sigmaNuc = CONVERTEL * pow2(sigmaTot) * (1. + rho*rho) / bSlope
+ * exp(-bSlope * tAbsMin);
+ sigmaCou = (useCoulomb) ?
+ pow2(alphaEM0) / (4. * CONVERTEL * tAbsMin) : 0.;
+ signCou = (idA == idB) ? 1. : -1.;
+
+ // Dummy values.
+ } else {
+ sigmaNuc = sigmaNw;
+ sigmaCou = 0.;
+ }
+
+ // Calculate coefficient of generation.
+ tAux = exp( max(-EXPMAX, bSlope * (tLow - tUpp)) ) - 1.;
+
+ // Initialize alphaEM generation.
+ alphaEM.init( Settings::mode("SigmaProcess:alphaEMorder") );
+
+ return true;
+
+}
+
+//*********
+
+// Select a trial kinematics phase space point. Perform full
+// Monte Carlo acceptance/rejection at this stage.
+
+bool PhaseSpace2to2elastic::trialKin( bool, bool ) {
+
+ // Select t according to exp(bSlope*t).
+ if (!useCoulomb || sigmaNuc > Rndm::flat() * (sigmaNuc + sigmaCou))
+ tH = tUpp + log(1. + tAux * Rndm::flat()) / bSlope;
+
+ // Select t according to 1/t^2.
+ else tH = tLow * tUpp / (tUpp + Rndm::flat() * (tLow - tUpp));
+
+ // Correction factor for ratio full/simulated.
+ if (useCoulomb) {
+ double sigmaN = CONVERTEL * pow2(sigmaTot) * (1. + rho*rho)
+ * exp(bSlope * tH);
+ double alpEM = alphaEM.alphaEM(-tH);
+ double sigmaC = pow2(alpEM) / (4. * CONVERTEL * tH*tH);
+ double sigmaGen = 2. * (sigmaN + sigmaC);
+ double form2 = pow4(lambda/(lambda - tH));
+ double phase = signCou * alpEM
+ * (-phaseCst - log(-0.5 * bSlope * tH));
+ double sigmaCor = sigmaN + pow2(form2) * sigmaC
+ - signCou * alpEM * sigmaTot * (form2 / (-tH))
+ * exp(0.5 * bSlope * tH) * (rho * cos(phase) + sin(phase));
+ sigmaNw = sigmaMx * sigmaCor / sigmaGen;
+ }
+
+ // Careful reconstruction of scattering angle.
+ double tRat = s * tH / lambda12S;
+ double cosTheta = min(1., max(-1., 1. + 2. * tRat ) );
+ double sinTheta = 2. * sqrtpos( -tRat * (1. + tRat) );
+ theta = asin( min(1., sinTheta));
+ if (cosTheta < 0.) theta = M_PI - theta;
+
+ return true;
+
+}
+
+//*********
+
+// Construct the four-vector kinematics from the trial values.
+
+bool PhaseSpace2to2elastic::finalKin() {
+
+ // Particle masses.
+ mH[1] = mA;
+ mH[2] = mB;
+ mH[3] = m3;
+ mH[4] = m4;
+
+ // Incoming particles along beam axes.
+ pAbs = 0.5 * sqrtpos(lambda12S) / eCM;
+ pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
+ pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
+
+ // Outgoing particles initially along beam axes.
+ pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
+ pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
+
+ // Then rotate them
+ phi = 2. * M_PI * Rndm::flat();
+ pH[3].rot( theta, phi);
+ pH[4].rot( theta, phi);
+
+ // Set some further info for completeness.
+ x1H = 1.;
+ x2H = 1.;
+ sH = s;
+ uH = 2. * (s1 + s2) - sH - tH;
+ mHat = eCM;
+ p2Abs = pAbs * pAbs;
+ betaZ = 0.;
+ pTH = pAbs * sin(theta);
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+// PhaseSpace2to2diffractive class.
+// 2 -> 2 kinematics set up for diffractive scattering.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of tries to find acceptable (m^2, t) set.
+const int PhaseSpace2to2diffractive::NTRY = 500;
+
+// Maximum positive/negative argument for exponentiation.
+const double PhaseSpace2to2diffractive::EXPMAX = 50.;
+
+// Safety margin so sum of diffractive masses not too close to eCM.
+const double PhaseSpace2to2diffractive::DIFFMASSMAX = 1e-8;
+
+//*********
+
+// Form of phase space sampling already fixed, so no optimization.
+// However, need to read out relevant parameters from SigmaTotal.
+
+bool PhaseSpace2to2diffractive::setupSampling() {
+
+ // Find maximum = value of cross section.
+ sigmaNw = sigmaProcessPtr->sigmaHatWrap();
+ sigmaMx = sigmaNw;
+
+ // Masses of particles and minimal masses of diffractive states.
+ m3ElDiff = (isDiffA) ? sigmaTotPtr->mMinXB() : mA;
+ m4ElDiff = (isDiffB) ? sigmaTotPtr->mMinAX() : mB;
+ s1 = mA * mA;
+ s2 = mB * mB;
+ s3 = pow2( m3ElDiff);
+ s4 = pow2( m4ElDiff);
+
+ // Parameters of low-mass-resonance diffractive enhancement.
+ cRes = sigmaTotPtr->cRes();
+ sResXB = pow2( sigmaTotPtr->mResXB());
+ sResAX = pow2( sigmaTotPtr->mResAX());
+ sProton = sigmaTotPtr->sProton();
+
+ // Lower limit diffractive slope.
+ if (!isDiffB) bMin = sigmaTotPtr->bMinSlopeXB();
+ else if (!isDiffA) bMin = sigmaTotPtr->bMinSlopeAX();
+ else bMin = sigmaTotPtr->bMinSlopeXX();
+
+ // Determine maximum possible t range and coefficient of generation.
+ lambda12 = sqrtpos( pow2( s - s1 - s2) - 4. * s1 * s2 );
+ lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
+ double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
+ double tempB = lambda12 * lambda34 / s;
+ double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
+ * (s1 * s4 - s2 * s3) / s;
+ tLow = -0.5 * (tempA + tempB);
+ tUpp = tempC / tLow;
+ tAux = exp( max(-EXPMAX, bMin * (tLow - tUpp)) ) - 1.;
+
+ return true;
+
+}
+
+//*********
+
+// Select a trial kinematics phase space point. Perform full
+// Monte Carlo acceptance/rejection at this stage.
+
+bool PhaseSpace2to2diffractive::trialKin( bool, bool ) {
+
+ // Loop over attempts to set up masses and t consistently.
+ for (int loop = 0; ; ++loop) {
+ if (loop == NTRY) {
+ infoPtr->errorMsg("Error in PhaseSpace2to2diffractive::trialKin: "
+ " quit after repeated tries");
+ return false;
+ }
+
+ // Select diffractive mass/masses according to dm^2/m^2.
+ m3 = (isDiffA) ? m3ElDiff * pow( max(mA, eCM - m4ElDiff) / m3ElDiff,
+ Rndm::flat()) : m3ElDiff;
+ m4 = (isDiffB) ? m4ElDiff * pow( max(mB, eCM - m3ElDiff) / m4ElDiff,
+ Rndm::flat()) : m4ElDiff;
+ s3 = m3 * m3;
+ s4 = m4 * m4;
+
+ // Additional mass factors, including resonance enhancement.
+ if (m3 + m4 >= eCM) continue;
+ if (isDiffA && !isDiffB) {
+ double facXB = (1. - s3 / s)
+ * (1. + cRes * sResXB / (sResXB + s3));
+ if (facXB < Rndm::flat() * (1. + cRes)) continue;
+ } else if (isDiffB && !isDiffA) {
+ double facAX = (1. - s4 / s)
+ * (1. + cRes * sResAX / (sResAX + s4));
+ if (facAX < Rndm::flat() * (1. + cRes)) continue;
+ } else {
+ double facXX = (1. - pow2(m3 + m4) / s)
+ * (s * sProton / (s * sProton + s3 * s4))
+ * (1. + cRes * sResXB / (sResXB + s3))
+ * (1. + cRes * sResAX / (sResAX + s4));
+ if (facXX < Rndm::flat() * pow2(1. + cRes)) continue;
+ }
+
+ // Select t according to exp(bMin*t) and correct to right slope.
+ tH = tUpp + log(1. + tAux * Rndm::flat()) / bMin;
+ double bDiff = 0.;
+ if (isDiffA && !isDiffB) bDiff = sigmaTotPtr->bSlopeXB(s3) - bMin;
+ else if (!isDiffA) bDiff = sigmaTotPtr->bSlopeAX(s4) - bMin;
+ else bDiff = sigmaTotPtr->bSlopeXX(s3, s4) - bMin;
+ bDiff = max(0., bDiff);
+ if (exp( max(-50., bDiff * (tH - tUpp)) ) < Rndm::flat()) continue;
+
+ // Check whether m^2 and t choices are consistent.
+ lambda34 = sqrtpos( pow2( s - s3 - s4) - 4. * s3 * s4 );
+ double tempA = s - (s1 + s2 + s3 + s4) + (s1 - s2) * (s3 - s4) / s;
+ double tempB = lambda12 * lambda34 / s;
+ if (tempB < DIFFMASSMAX) continue;
+ double tempC = (s3 - s1) * (s4 - s2) + (s1 + s4 - s2 - s3)
+ * (s1 * s4 - s2 * s3) / s;
+ double tLowNow = -0.5 * (tempA + tempB);
+ double tUppNow = tempC / tLowNow;
+ if (tH < tLowNow || tH > tUppNow) continue;
+
+ // Careful reconstruction of scattering angle.
+ double cosTheta = min(1., max(-1., (tempA + 2. * tH) / tempB));
+ double sinTheta = 2. * sqrtpos( -(tempC + tempA * tH + tH * tH) )
+ / tempB;
+ theta = asin( min(1., sinTheta));
+ if (cosTheta < 0.) theta = M_PI - theta;
+
+ // Found acceptable kinematics, so no more looping.
+ break;
+ }
+
+ return true;
+
+}
+
+//*********
+
+// Construct the four-vector kinematics from the trial values.
+
+bool PhaseSpace2to2diffractive::finalKin() {
+
+ // Particle masses; incoming always on mass shell.
+ mH[1] = mA;
+ mH[2] = mB;
+ mH[3] = m3;
+ mH[4] = m4;
+
+ // Incoming particles along beam axes.
+ pAbs = 0.5 * lambda12 / eCM;
+ pH[1] = Vec4( 0., 0., pAbs, 0.5 * (s + s1 - s2) / eCM);
+ pH[2] = Vec4( 0., 0., -pAbs, 0.5 * (s + s2 - s1) / eCM);
+
+ // Outgoing particles initially along beam axes.
+ pAbs = 0.5 * lambda34 / eCM;
+ pH[3] = Vec4( 0., 0., pAbs, 0.5 * (s + s3 - s4) / eCM);
+ pH[4] = Vec4( 0., 0., -pAbs, 0.5 * (s + s4 - s3) / eCM);
+
+ // Then rotate them
+ phi = 2. * M_PI * Rndm::flat();
+ pH[3].rot( theta, phi);
+ pH[4].rot( theta, phi);
+
+ // Set some further info for completeness.
+ x1H = 1.;
+ x2H = 1.;
+ sH = s;
+ uH = s1 + s2 + s3 + s4 - sH - tH;
+ mHat = eCM;
+ p2Abs = pAbs * pAbs;
+ betaZ = 0.;
+ pTH = pAbs * sin(theta);
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+// PhaseSpace2to3tauycyl class.
+// 2 -> 3 kinematics for normal subprocesses.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of Newton-Raphson iterations of kinematics when masses introduced.
+const int PhaseSpace2to3tauycyl::NITERNR = 5;
+
+//*********
+
+// Set up for fixed or Breit-Wigner mass selection.
+
+bool PhaseSpace2to3tauycyl::setupMasses() {
+
+ // Treat Z0 as such or as gamma*/Z0
+ gmZmode = gmZmodeGlobal;
+ int gmZmodeProc = sigmaProcessPtr->gmZmode();
+ if (gmZmodeProc >= 0) gmZmode = gmZmodeProc;
+
+ // Set sHat limits - based on global limits only.
+ mHatMin = mHatGlobalMin;
+ sHatMin = mHatMin*mHatMin;
+ mHatMax = eCM;
+ if (mHatGlobalMax > mHatGlobalMin) mHatMax = min( eCM, mHatGlobalMax);
+ sHatMax = mHatMax*mHatMax;
+
+ // Masses and widths of resonances.
+ setupMass1(3);
+ setupMass1(4);
+ setupMass1(5);
+
+ // Reduced mass range - do not make it as fancy as in two-body case.
+ if (useBW[3]) mUpper[3] -= (mPeak[4] + mPeak[5]);
+ if (useBW[4]) mUpper[4] -= (mPeak[3] + mPeak[5]);
+ if (useBW[5]) mUpper[5] -= (mPeak[3] + mPeak[4]);
+
+ // If closed phase space then unallowed process.
+ bool physical = true;
+ if (useBW[3] && mUpper[3] < mLower[3] + MASSMARGIN) physical = false;
+ if (useBW[4] && mUpper[4] < mLower[4] + MASSMARGIN) physical = false;
+ if (useBW[5] && mUpper[5] < mLower[5] + MASSMARGIN) physical = false;
+ if (!useBW[3] && !useBW[4] && !useBW[5] && mHatMax < mPeak[3]
+ + mPeak[4] + mPeak[5] + MASSMARGIN) physical = false;
+ if (!physical) return false;
+
+ // No extra pT precautions in massless limit - assumed fixed by ME's.
+ pTHatMin = pTHatGlobalMin;
+ pT2HatMin = pTHatMin * pTHatMin;
+ pTHatMax = pTHatGlobalMax;
+ pT2HatMax = pTHatMax * pTHatMax;
+
+ // Prepare to select m3 by BW + flat + 1/s_3.
+ if (useBW[3]) {
+ double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
+ * mWidth[3] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
+ double distToThreshB = (mHatMax - mPeak[3] - mMin[4] - mMin[5])
+ / mWidth[3];
+ double distToThresh = min( distToThreshA, distToThreshB);
+ setupMass2(3, distToThresh);
+ }
+
+ // Prepare to select m4 by BW + flat + 1/s_3.
+ if (useBW[4]) {
+ double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
+ * mWidth[4] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
+ double distToThreshB = (mHatMax - mPeak[4] - mMin[3] - mMin[5])
+ / mWidth[4];
+ double distToThresh = min( distToThreshA, distToThreshB);
+ setupMass2(4, distToThresh);
+ }
+
+ // Prepare to select m5 by BW + flat + 1/s_3.
+ if (useBW[5]) {
+ double distToThreshA = (mHatMax - mPeak[3] - mPeak[4] - mPeak[5])
+ * mWidth[5] / (pow2(mWidth[3]) + pow2(mWidth[4]) + pow2(mWidth[5]));
+ double distToThreshB = (mHatMax - mPeak[5] - mMin[3] - mMin[4])
+ / mWidth[5];
+ double distToThresh = min( distToThreshA, distToThreshB);
+ setupMass2(5, distToThresh);
+ }
+
+ // Initialization masses. For now give up when constrained phase space.
+ m3 = (useBW[3]) ? min(mPeak[3], mUpper[3]) : mPeak[3];
+ m4 = (useBW[4]) ? min(mPeak[4], mUpper[4]) : mPeak[4];
+ m5 = (useBW[5]) ? min(mPeak[5], mUpper[5]) : mPeak[5];
+ if (m3 + m4 + m5 + MASSMARGIN > mHatMax) physical = false;
+ s3 = m3*m3;
+ s4 = m4*m4;
+ s5 = m5*m5;
+
+ // Correct selected mass-spectrum to running-width Breit-Wigner.
+ // Extra safety margin for maximum search.
+ wtBW = 1.;
+ if (useBW[3]) wtBW *= weightMass(3) * EXTRABWWTMAX;
+ if (useBW[4]) wtBW *= weightMass(4) * EXTRABWWTMAX;
+ if (useBW[5]) wtBW *= weightMass(5) * EXTRABWWTMAX;
+
+ // Done.
+ return physical;
+
+}
+
+//*********
+
+// Select Breit-Wigner-distributed or fixed masses.
+
+bool PhaseSpace2to3tauycyl::trialMasses() {
+
+ // By default vanishing cross section.
+ sigmaNw = 0.;
+ wtBW = 1.;
+
+ // Pick m3, m4 and m5 independently.
+ trialMass(3);
+ trialMass(4);
+ trialMass(5);
+
+ // If outside phase space then reject event.
+ if (m3 + m4 + m5 + MASSMARGIN > mHatMax) return false;
+
+ // Correct selected mass-spectrum to running-width Breit-Wigner.
+ if (useBW[3]) wtBW *= weightMass(3);
+ if (useBW[4]) wtBW *= weightMass(4);
+ if (useBW[5]) wtBW *= weightMass(5);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Construct the four-vector kinematics from the trial values.
+
+bool PhaseSpace2to3tauycyl::finalKin() {
+
+ // Assign masses to particles assumed massless in matrix elements.
+ int id3 = sigmaProcessPtr->id(3);
+ int id4 = sigmaProcessPtr->id(4);
+ int id5 = sigmaProcessPtr->id(5);
+ if (idMass[3] == 0) { m3 = ParticleDataTable::m0(id3); s3 = m3*m3; }
+ if (idMass[4] == 0) { m4 = ParticleDataTable::m0(id4); s4 = m4*m4; }
+ if (idMass[5] == 0) { m5 = ParticleDataTable::m0(id5); s5 = m5*m5; }
+
+ // Check that phase space still open after new mass assignment.
+ if (m3 + m4 + m5 + MASSMARGIN > mHat) {
+ infoPtr->errorMsg("Warning in PhaseSpace2to3tauycyl::finalKin: "
+ "failed after mass assignment");
+ return false;
+ }
+
+ // Particle masses; incoming always on mass shell.
+ mH[1] = 0.;
+ mH[2] = 0.;
+ mH[3] = m3;
+ mH[4] = m4;
+ mH[5] = m5;
+
+ // Incoming partons along beam axes.
+ pH[1] = Vec4( 0., 0., 0.5 * eCM * x1H, 0.5 * eCM * x1H);
+ pH[2] = Vec4( 0., 0., -0.5 * eCM * x2H, 0.5 * eCM * x2H);
+
+ // Begin three-momentum rescaling to compensate for masses.
+ if (idMass[3] == 0 || idMass[4] == 0 || idMass[5] == 0) {
+ double p3S = p3cm.pAbs2();
+ double p4S = p4cm.pAbs2();
+ double p5S = p5cm.pAbs2();
+ double fac = 1.;
+ double e3, e4, e5, value, deriv;
+
+ // Iterate rescaling solution five times, using Newton-Raphson.
+ for (int i = 0; i < NITERNR; ++i) {
+ e3 = sqrt(s3 + fac * p3S);
+ e4 = sqrt(s4 + fac * p4S);
+ e5 = sqrt(s5 + fac * p5S);
+ value = e3 + e4 + e5 - mHat;
+ deriv = 0.5 * (p3S / e3 + p4S / e4 + p5S / e5);
+ fac -= value / deriv;
+ }
+
+ // Rescale momenta appropriately.
+ double facRoot = sqrt(fac);
+ p3cm.rescale3( facRoot );
+ p4cm.rescale3( facRoot );
+ p5cm.rescale3( facRoot );
+ p3cm.e( sqrt(s3 + fac * p3S) );
+ p4cm.e( sqrt(s4 + fac * p4S) );
+ p5cm.e( sqrt(s5 + fac * p5S) );
+ }
+
+ // Outgoing partons initially in collision CM frame along beam axes.
+ pH[3] = p3cm;
+ pH[4] = p4cm;
+ pH[5] = p5cm;
+
+ // Then boost them to overall CM frame
+ betaZ = (x1H - x2H)/(x1H + x2H);
+ pH[3].rot( theta, phi);
+ pH[4].rot( theta, phi);
+ pH[3].bst( 0., 0., betaZ);
+ pH[4].bst( 0., 0., betaZ);
+ pH[5].bst( 0., 0., betaZ);
+
+ // Store average pT of three final particles for documentation.
+ pTH = (p3cm.pT() + p4cm.pT() + p5cm.pT()) / 3.;
+
+ // Done.
+ return true;
+}
+
+//**************************************************************************
+
+// The PhaseSpaceLHA class.
+// A derived class for Les Houches events.
+// Note: arbitrary subdivision into PhaseSpaceLHA and SigmaLHAProcess tasks.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// LHA convention with cross section in pb forces conversion to mb.
+const double PhaseSpaceLHA::CONVERTPB2MB = 1e-9;
+
+//*********
+
+// Find maximal cross section for comparison with internal processes.
+
+bool PhaseSpaceLHA::setupSampling() {
+
+ // Find which strategy Les Houches events are produced with.
+ strategy = lhaUpPtr->strategy();
+ stratAbs = abs(strategy);
+ if (strategy == 0 || stratAbs > 4) {
+ ostringstream stratCode;
+ stratCode << strategy;
+ infoPtr->errorMsg("Error in PhaseSpaceLHA::setupSampling: unknown "
+ "Les Houches Accord weighting stategy", stratCode.str());
+ return false;
+ }
+
+ // Number of contributing processes.
+ nProc = lhaUpPtr->sizeProc();
+
+ // Loop over all processes. Read out maximum and cross section.
+ xMaxAbsSum = 0.;
+ xSecSgnSum = 0.;
+ int idPr;
+ double xMax, xSec, xMaxAbs;
+ for (int iProc = 0 ; iProc < nProc; ++iProc) {
+ idPr = lhaUpPtr->idProcess(iProc);
+ xMax = lhaUpPtr->xMax(iProc);
+ xSec = lhaUpPtr->xSec(iProc);
+
+ // Check for inconsistencies between strategy and stored values.
+ if ( (strategy == 1 || strategy == 2) && xMax < 0.) {
+ infoPtr->errorMsg("Error in PhaseSpaceLHA::setupSampling: "
+ "negative maximum not allowed");
+ return false;
+ }
+ if ( ( strategy == 2 || strategy == 3) && xSec < 0.) {
+ infoPtr->errorMsg("Error in PhaseSpaceLHA::setupSampling: "
+ "negative cross section not allowed");
+ return false;
+ }
+
+ // Store maximal cross sections for later choice.
+ if (stratAbs == 1) xMaxAbs = abs(xMax);
+ else if (stratAbs < 4) xMaxAbs = abs(xSec);
+ else xMaxAbs = 1.;
+ idProc.push_back( idPr );
+ xMaxAbsProc.push_back( xMaxAbs );
+
+ // Find sum and convert to mb.
+ xMaxAbsSum += xMaxAbs;
+ xSecSgnSum += xSec;
+ }
+ sigmaMx = xMaxAbsSum * CONVERTPB2MB;
+ sigmaSgn = xSecSgnSum * CONVERTPB2MB;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Construct the next process, by interface to Les Houches class.
+
+bool PhaseSpaceLHA::trialKin( bool, bool repeatSame ) {
+
+ // Must select process type in some cases.
+ int idProcNow = 0;
+ if (repeatSame) idProcNow = idProcSave;
+ else if (stratAbs <= 2) {
+ double xMaxAbsRndm = xMaxAbsSum * Rndm::flat();
+ int iProc = -1;
+ do xMaxAbsRndm -= xMaxAbsProc[++iProc];
+ while (xMaxAbsRndm > 0. && iProc < nProc - 1);
+ idProcNow = idProc[iProc];
+ }
+
+ // Generate Les Houches event. Return if fail (= end of file).
+ bool physical = lhaUpPtr->setEvent(idProcNow);
+ if (!physical) return false;
+
+ // Find which process was generated.
+ int idPr = lhaUpPtr->idProcess();
+ int iProc = 0;
+ for (int iP = 0; iP < int(idProc.size()); ++iP)
+ if (idProc[iP] == idPr) iProc = iP;
+ idProcSave = idPr;
+
+ // Extract cross section and rescale according to strategy.
+ double wtPr = lhaUpPtr->weight();
+ if (stratAbs == 1) sigmaNw = wtPr * CONVERTPB2MB
+ * xMaxAbsSum / xMaxAbsProc[iProc];
+ else if (stratAbs == 2) sigmaNw = (wtPr / abs(lhaUpPtr->xMax(iProc)))
+ * sigmaMx;
+ else if (strategy == 3) sigmaNw = sigmaMx;
+ else if (strategy == -3 && wtPr > 0.) sigmaNw = sigmaMx;
+ else if (strategy == -3) sigmaNw = -sigmaMx;
+ else if (stratAbs == 4) sigmaNw = wtPr * CONVERTPB2MB;
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// ProcessContainer.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// ProcessContainer and SetupContainers classes.
+
+#include "ProcessContainer.h"
+
+// Internal headers for special processes.
+#include "SigmaCompositeness.h"
+#include "SigmaEW.h"
+#include "SigmaExtraDim.h"
+#include "SigmaHiggs.h"
+#include "SigmaLeftRightSym.h"
+#include "SigmaLeptoquark.h"
+#include "SigmaNewGaugeBosons.h"
+#include "SigmaOnia.h"
+#include "SigmaQCD.h"
+#include "SigmaSUSY.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// ProcessContainer class.
+// Information allowing the generation of a specific process.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of event tries to check maximization finding reliability.
+const int ProcessContainer::N12SAMPLE = 100;
+
+// Ditto, but increased for 2 -> 3 processes.
+const int ProcessContainer::N3SAMPLE = 1000;
+
+//*********
+
+// Initialize phase space and counters.
+
+bool ProcessContainer::init(Info* infoPtrIn, BeamParticle* beamAPtr,
+ BeamParticle* beamBPtr, AlphaStrong* alphaSPtr, AlphaEM* alphaEMPtr,
+ SigmaTotal* sigmaTotPtr, ResonanceDecays* resDecaysPtrIn,
+ SusyLesHouches* slhaPtr, UserHooks* userHooksPtr) {
+
+ // Extract info about current process from SigmaProcess object.
+ isLHA = sigmaProcessPtr->isLHA();
+ isMinBias = sigmaProcessPtr->isMinBias();
+ isResolved = sigmaProcessPtr->isResolved();
+ isDiffA = sigmaProcessPtr->isDiffA();
+ isDiffB = sigmaProcessPtr->isDiffB();
+ int nFin = sigmaProcessPtr->nFinal();
+ lhaStrat = (isLHA) ? lhaUpPtr->strategy() : 0;
+ lhaStratAbs = abs(lhaStrat);
+ allowNegSig = sigmaProcessPtr->allowNegativeSigma();
+
+ // Pick and create phase space generator. Send pointers where required.
+ if (isLHA) phaseSpacePtr = new PhaseSpaceLHA();
+ else if (isMinBias) phaseSpacePtr = new PhaseSpace2to2minbias();
+ else if (!isResolved && !isDiffA && !isDiffB )
+ phaseSpacePtr = new PhaseSpace2to2elastic();
+ else if (!isResolved) phaseSpacePtr = new PhaseSpace2to2diffractive(
+ isDiffA, isDiffB);
+ else if (nFin == 1) phaseSpacePtr = new PhaseSpace2to1tauy();
+ else if (nFin == 2) phaseSpacePtr = new PhaseSpace2to2tauyz();
+ else phaseSpacePtr = new PhaseSpace2to3tauycyl();
+
+ // Store pointers and perform simple initialization.
+ infoPtr = infoPtrIn;
+ resDecaysPtr = resDecaysPtrIn;
+ if (isLHA) {
+ sigmaProcessPtr->setLHAPtr(lhaUpPtr);
+ phaseSpacePtr->setLHAPtr(lhaUpPtr);
+ }
+ sigmaProcessPtr->init(infoPtr, beamAPtr, beamBPtr, alphaSPtr,
+ alphaEMPtr, sigmaTotPtr, slhaPtr);
+ phaseSpacePtr->init( sigmaProcessPtr, infoPtr, beamAPtr,
+ beamBPtr, sigmaTotPtr, userHooksPtr);
+
+ // Reset cross section statistics.
+ nTry = 0;
+ nSel = 0;
+ nAcc = 0;
+ nTryStat = 0;
+ sigmaMx = 0.;
+ sigmaSum = 0.;
+ sigma2Sum = 0.;
+ sigmaNeg = 0.;
+ sigmaAvg = 0.;
+ sigmaFin = 0.;
+ deltaFin = 0.;
+
+ // Initialize process and allowed incoming partons.
+ sigmaProcessPtr->initProc();
+ if (!sigmaProcessPtr->initFlux()) return false;
+
+ // Find maximum of differential cross section * phasespace.
+ bool physical = phaseSpacePtr->setupSampling();
+ sigmaMx = phaseSpacePtr->sigmaMax();
+ double sigmaHalfWay = sigmaMx;
+
+ // Separate signed maximum needed for LHA with negative weight.
+ sigmaSgn = phaseSpacePtr->sigmaSumSigned();
+
+ // Check maximum by a few events, and extrapolate a further increase.
+ if (physical & !isLHA) {
+ int nSample = (nFin < 3) ? N12SAMPLE : N3SAMPLE;
+ for (int iSample = 0; iSample < nSample; ++iSample)
+ while (!phaseSpacePtr->trialKin(false)) {
+ if (iSample == nSample/2) sigmaHalfWay = phaseSpacePtr->sigmaMax();
+ }
+ sigmaMx = pow2(phaseSpacePtr->sigmaMax()) / sigmaHalfWay;
+ phaseSpacePtr->setSigmaMax(sigmaMx);
+ }
+
+ // Done.
+ return physical;
+}
+
+//*********
+
+// Generate a trial event; selected or not.
+
+bool ProcessContainer::trialProcess() {
+
+ // Loop over tries only occurs for Les Houches strategy = +-2.
+ for (int iTry = 0; ; ++iTry) {
+
+ // Generate a trial phase space point, if meaningful.
+ if (sigmaMx == 0.) return false;
+ infoPtr->setEndOfFile(false);
+ bool repeatSame = (iTry > 0);
+ bool physical = phaseSpacePtr->trialKin(true, repeatSame);
+
+ // Possibly fail, e.g. if at end of Les Houches file, else cross section.
+ if (isLHA && !physical) infoPtr->setEndOfFile(true);
+ else ++nTry;
+ if (!physical) return false;
+ double sigmaNow = phaseSpacePtr->sigmaNow();
+
+ // Tell if this event comes with negative weight, or weight at all.
+ double weight = 1.;
+ if ( lhaStrat < 0 && sigmaNow < 0.) weight = -1.;
+ if ( lhaStratAbs == 4) weight = sigmaNow;
+ infoPtr->setWeight( weight);
+
+ // Check that not negative cross section when not allowed.
+ if (!allowNegSig) {
+ if (sigmaNow < sigmaNeg) {
+ infoPtr->errorMsg("Warning in ProcessContainer::trialProcess: neg"
+ "ative cross section set 0", "for " + sigmaProcessPtr->name() );
+ sigmaNeg = sigmaNow;
+ }
+ if (sigmaNow < 0.) sigmaNow = 0.;
+ }
+
+ // Update statistics. Check if maximum violated.
+ double sigmaAdd = sigmaNow;
+ if (lhaStratAbs == 2 || lhaStratAbs == 3) sigmaAdd = sigmaSgn;
+ sigmaSum += sigmaAdd;
+ sigma2Sum += pow2(sigmaAdd);
+ newSigmaMx = phaseSpacePtr->newSigmaMax();
+ if (newSigmaMx) sigmaMx = phaseSpacePtr->sigmaMax();
+
+ // Select or reject trial point.
+ bool select = true;
+ if (lhaStratAbs < 3) select
+ = (newSigmaMx || Rndm::flat() * abs(sigmaMx) < abs(sigmaNow));
+ if (select) ++nSel;
+ if (select || lhaStratAbs !=2) return select;
+ }
+
+}
+
+//*********
+
+// Give the hard subprocess.
+
+bool ProcessContainer::constructProcess( Event& process, bool isHardest) {
+
+ // Construct flavour and colours for selected event.
+ if (isResolved && !isMinBias) sigmaProcessPtr->pickInState();
+ sigmaProcessPtr->setIdColAcol();
+
+ // Construct kinematics from selected phase space point.
+ if (!phaseSpacePtr->finalKin()) return false;
+ int nFin = sigmaProcessPtr->nFinal();
+
+ // Basic info on process.
+ if (isHardest) infoPtr->setType( name(), code(), nFin, isMinBias,
+ isResolved, isDiffA, isDiffB, isLHA);
+
+ // Let hard process record begin with the event as a whole and
+ // the two incoming beam particles.
+ process.append( 90, -11, 0, 0, 0, 0, 0, 0,
+ Vec4(0., 0., 0., infoPtr->eCM()), infoPtr->eCM(), 0. );
+ process.append( infoPtr->idA(), -12, 0, 0, 3, 0, 0, 0,
+ Vec4(0., 0., infoPtr->pzA(), infoPtr->eA()), infoPtr->mA(), 0. );
+ process.append( infoPtr->idB(), -12, 0, 0, 4, 0, 0, 0,
+ Vec4(0., 0., infoPtr->pzB(), infoPtr->eB()), infoPtr->mB(), 0. );
+
+ // For minbias process no interaction selected so far, so done.
+ if (isMinBias) return true;
+ double scale = 0.;
+
+ // Insert the subprocess partons - resolved processes.
+ if (isResolved && !isLHA) {
+
+ // Find scale from which to begin MI/ISR/FSR evolution.
+ scale = sqrt(Q2Fac());
+ process.scale( scale );
+
+ // Loop over incoming and outgoing partons.
+ int colOffset = process.lastColTag();
+ for (int i = 1; i <= 2 + nFin; ++i) {
+
+ // Read out particle info from SigmaProcess object.
+ int id = sigmaProcessPtr->id(i);
+ int status = (i <= 2) ? -21 : 23;
+ int mother1 = (i <= 2) ? i : 3;
+ int mother2 = (i <= 2) ? 0 : 4;
+ int daughter1 = (i <= 2) ? 5 : 0;
+ int daughter2 = (i <= 2) ? 4 + nFin : 0;
+ int col = sigmaProcessPtr->col(i);
+ if (col > 0) col += colOffset;
+ int acol = sigmaProcessPtr->acol(i);
+ if (acol > 0) acol += colOffset;
+
+ // Append to process record.
+ int iNow = process.append( id, status, mother1, mother2,
+ daughter1, daughter2, col, acol, phaseSpacePtr->p(i),
+ phaseSpacePtr->m(i), scale);
+
+ // Pick lifetime where relevant, else not.
+ if (process[iNow].tau0() > 0.) process[iNow].tau(
+ process[iNow].tau0() * Rndm::exp() );
+ }
+ }
+
+ // Insert the outgoing particles - unresolved processes.
+ else if (!isLHA) {
+ process.append( sigmaProcessPtr->id(3), 23, 1, 0, 0, 0, 0, 0,
+ phaseSpacePtr->p(3), phaseSpacePtr->m(3));
+ process.append( sigmaProcessPtr->id(4), 23, 2, 0, 0, 0, 0, 0,
+ phaseSpacePtr->p(4), phaseSpacePtr->m(4));
+ }
+
+ // Insert the outgoing particles - Les Houches Accord processes.
+ else {
+
+ // Since LHA partons may be out of order, determine correct one.
+ // (Recall that zeroth particle is empty.)
+ vector<int> newPos;
+ newPos.reserve(lhaUpPtr->sizePart());
+ newPos.push_back(0);
+ for (int iNew = 0; iNew < lhaUpPtr->sizePart(); ++iNew) {
+ // For iNew == 0 look for the two incoming partons, then for
+ // partons having them as mothers, and so on layer by layer.
+ for (int i = 1; i < lhaUpPtr->sizePart(); ++i)
+ if (lhaUpPtr->mother1(i) == newPos[iNew]) newPos.push_back(i);
+ if (int(newPos.size()) <= iNew) break;
+ }
+
+ // Find scale from which to begin MI/ISR/FSR evolution.
+ scale = lhaUpPtr->scale();
+ process.scale( scale);
+
+ // Copy over info from LHA event to process, in proper order.
+ for (int i = 1; i < lhaUpPtr->sizePart(); ++i) {
+ int iOld = newPos[i];
+ int id = lhaUpPtr->id(iOld);
+
+ // Translate from LHA status codes.
+ int lhaStatus = lhaUpPtr->status(iOld);
+ int status = -21;
+ if (lhaStatus == 2 || lhaStatus == 3) status = -22;
+ if (lhaStatus == 1) status = 23;
+
+ // Find where mothers have been moved by reordering.
+ int mother1Old = lhaUpPtr->mother1(iOld);
+ int mother2Old = lhaUpPtr->mother2(iOld);
+ int mother1 = 0;
+ int mother2 = 0;
+ for (int im = 1; im < i; ++im) {
+ if (mother1Old == newPos[im]) mother1 = im + 2;
+ if (mother2Old == newPos[im]) mother2 = im + 2;
+ }
+ if (i <= 2) mother1 = i;
+
+ // Ensure that second mother = 0 except for bona fide carbon copies.
+ if (mother1 > 0 && mother2 == mother1) {
+ int sister1 = process[mother1].daughter1();
+ int sister2 = process[mother1].daughter2();
+ if (sister2 != sister1 && sister2 != 0) mother2 = 0;
+ }
+
+ // Find daughters and where they have been moved by reordering.
+ // (Values shifted two steps to account for inserted beams.)
+ int daughter1 = 0;
+ int daughter2 = 0;
+ for (int im = i + 1; im < lhaUpPtr->sizePart(); ++im) {
+ if (lhaUpPtr->mother1(newPos[im]) == iOld
+ || lhaUpPtr->mother2(newPos[im]) == iOld) {
+ if (daughter1 == 0 || im + 2 < daughter1) daughter1 = im + 2;
+ if (daughter2 == 0 || im + 2 > daughter2) daughter2 = im + 2;
+ }
+ }
+ // For 2 -> 1 hard scatterings reset second daughter to 0.
+ if (daughter2 == daughter1) daughter2 = 0;
+
+ // Colour trivial, except reset irrelevant colour indices.
+ int colType = ParticleDataTable::colType(id);
+ int col1 = (colType == 1 || colType == 2)
+ ? lhaUpPtr->col1(iOld) : 0;
+ int col2 = (colType == -1 || colType == 2)
+ ? lhaUpPtr->col2(iOld) : 0;
+
+ // Momentum trivial.
+ double px = lhaUpPtr->px(iOld);
+ double py = lhaUpPtr->py(iOld);
+ double pz = lhaUpPtr->pz(iOld);
+ double e = lhaUpPtr->e(iOld);
+ double m = lhaUpPtr->m(iOld);
+
+ // For resonance decay products use resonance mass as scale.
+ double scaleNow = scale;
+ if (mother1 > 4) scaleNow = process[mother1].m();
+
+ // Store Les Houches Accord partons.
+ int iNow = process.append( id, status, mother1, mother2, daughter1,
+ daughter2, col1, col2, Vec4(px, py, pz, e), m, scaleNow);
+
+ // Check if need to store lifetime.
+ double tau = lhaUpPtr->tau(iOld);
+ if (tau > 0.) process[iNow].tau(tau);
+ }
+ }
+
+ // Loop through decay chains and set secondary vertices when needed.
+ for (int i = 3; i < process.size(); ++i) {
+ int iMother = process[i].mother1();
+
+ // If sister to already assigned vertex then assign same.
+ if ( process[i - 1].mother1() == iMother && process[i - 1].hasVertex() )
+ process[i].vProd( process[i - 1].vProd() );
+
+ // Else if mother already has vertex and/or lifetime then assign.
+ else if ( process[iMother].hasVertex() || process[iMother].tau() > 0.)
+ process[i].vProd( process[iMother].vDec() );
+ }
+
+ // Further info on process. Reset quantities that may or may not be known.
+ int id1Now = process[3].id();
+ int id2Now = process[4].id();
+ double pdf1 = 0.;
+ double pdf2 = 0.;
+ double tHat = 0.;
+ double uHat = 0.;
+ double pTHat = 0.;
+ double m3 = 0.;
+ double m4 = 0.;
+ double theta = 0.;
+ double phi = 0.;
+ double Q2FacNow, alphaEM, alphaS, Q2Ren, x1Now, x2Now, sHat;
+
+ // Internally generated and stored information.
+ if (!isLHA) {
+ pdf1 = sigmaProcessPtr->pdf1();
+ pdf2 = sigmaProcessPtr->pdf2();
+ Q2FacNow = sigmaProcessPtr->Q2Fac();
+ alphaEM = sigmaProcessPtr->alphaEMRen();
+ alphaS = sigmaProcessPtr->alphaSRen();
+ Q2Ren = sigmaProcessPtr->Q2Ren();
+ x1Now = phaseSpacePtr->x1();
+ x2Now = phaseSpacePtr->x2();
+ sHat = phaseSpacePtr->sHat();
+ tHat = phaseSpacePtr->tHat();
+ uHat = phaseSpacePtr->uHat();
+ pTHat = phaseSpacePtr->pTHat();
+ m3 = phaseSpacePtr->m(3);
+ m4 = phaseSpacePtr->m(4);
+ theta = phaseSpacePtr->thetaHat();
+ phi = phaseSpacePtr->phiHat();
+ }
+
+ // Les Houches Accord process partly available, partly to be constructed.
+ else {
+ Q2FacNow = pow2(scale);
+ alphaEM = lhaUpPtr->alphaQED();
+ alphaS = lhaUpPtr->alphaQCD();
+ Q2Ren = Q2FacNow;
+ x1Now = 2. * process[3].e() / infoPtr->eCM();
+ x2Now = 2. * process[4].e() / infoPtr->eCM();
+ Vec4 pSum = process[3].p() + process[4].p();
+ sHat = pSum * pSum;
+
+ // Read info on parton densities if provided.
+ if (lhaUpPtr->pdfIsSet()) {
+ pdf1 = lhaUpPtr->xpdf1();
+ pdf2 = lhaUpPtr->xpdf2();
+ Q2FacNow = pow2(lhaUpPtr->scalePDF());
+ x1Now = lhaUpPtr->x1();
+ x2Now = lhaUpPtr->x2();
+ }
+
+ // Reconstruct kinematics of 2 -> 2 processes from momenta.
+ if (nFin == 2) {
+ Vec4 pDifT = process[3].p() - process[5].p();
+ tHat = pDifT * pDifT;
+ Vec4 pDifU = process[3].p() - process[6].p();
+ uHat = pDifU * pDifU;
+ pTHat = process[5].pT();
+ m3 = process[5].m();
+ m4 = process[6].m();
+ Vec4 p5 = process[5].p();
+ p5.bstback(pSum);
+ theta = p5.theta();
+ phi = process[5].phi();
+ }
+ }
+
+ // Store information.
+ if (isHardest) {
+ infoPtr->setPDFalpha( id1Now, id2Now, pdf1, pdf2, Q2FacNow,
+ alphaEM, alphaS, Q2Ren);
+ infoPtr->setKin( x1Now, x2Now, sHat, tHat, uHat, pTHat, m3, m4,
+ theta, phi);
+ }
+ infoPtr->setTypeMI( code(), pTHat);
+
+ // For Les Houches event store subprocess classification.
+ if (isLHA) {
+ int codeSub = lhaUpPtr->idProcess();
+ ostringstream nameSub;
+ nameSub << "user process " << codeSub;
+ infoPtr->setSubType( nameSub.str(), codeSub, nFin);
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Handle resonance decays.
+
+bool ProcessContainer::decayResonances( Event& process) {
+
+ // Save current event-record size.
+ process.saveSize();
+ bool physical = true;
+ bool newFlavours = false;
+
+ // Do sequential chain of uncorrelated isotropic decays.
+ do {
+ physical = resDecaysPtr->next( process);
+ if (!physical) return false;
+
+ // Check whether flavours should be correlated.
+ // (Currently only relevant for f fbar -> gamma*/Z0 gamma*/Z0.)
+ newFlavours = ( sigmaProcessPtr->weightDecayFlav( process)
+ < Rndm::flat() );
+
+ // Reset the decay chains if have to redo.
+ if (newFlavours) {
+ process.restoreSize();
+ for (int i = 5; i < process.size(); ++i) process[i].statusPos();
+ }
+
+ // Loop back where required to generate new decays with new flavours.
+ } while (newFlavours);
+
+ // Correct to nonisotropic decays.
+ phaseSpacePtr->decayKinematics( process);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Reset event generation statistics; but NOT maximum of cross section.
+
+void ProcessContainer::reset() {
+
+ nTry = 0;
+ nSel = 0;
+ nAcc = 0;
+ nTryStat = 0;
+ sigmaSum = 0.;
+ sigma2Sum = 0.;
+ sigmaNeg = 0.;
+ sigmaAvg = 0.;
+ sigmaFin = 0.;
+ deltaFin = 0.;
+
+}
+
+//*********
+
+// Estimate integrated cross section and its uncertainty.
+
+void ProcessContainer::sigmaDelta() {
+
+ // Initial values. No analysis meaningful unless accepted events.
+ nTryStat = nTry;
+ sigmaAvg = 0.;
+ sigmaFin = 0.;
+ deltaFin = 0.;
+ if (nAcc == 0) return;
+
+ // Average value.
+ double nTryInv = 1. / nTry;
+ double nSelInv = 1. / nSel;
+ double nAccInv = 1. / nAcc;
+ sigmaAvg = sigmaSum * nTryInv ;
+ double fracAcc = nAcc * nSelInv;
+ sigmaFin = sigmaAvg * fracAcc;
+
+ // Estimated error. Quadratic sum of cross section term and
+ // binomial from accept/reject step.
+ deltaFin = sigmaFin;
+ if (nAcc == 1) return;
+ double delta2Sig = (sigma2Sum *nTryInv - pow2(sigmaAvg)) * nTryInv
+ / pow2(sigmaAvg);
+ double delta2Veto = (nSel - nAcc) * nAccInv * nSelInv;
+ double delta2Sum = delta2Sig + delta2Veto;
+ deltaFin = sqrtpos(delta2Sum) * sigmaFin;
+
+}
+
+//**************************************************************************
+
+// SetupContainer class.
+// Turns list of user-desired processes into a vector of containers.
+
+//*********
+
+// Main routine to initialize list of processes.
+
+bool SetupContainers::init(vector<ProcessContainer*>& containerPtrs) {
+
+ // Reset process list, if filled in previous subrun.
+ if (containerPtrs.size() > 0) {
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ delete containerPtrs[i];
+ containerPtrs.clear();
+ }
+ SigmaProcess* sigmaPtr;
+
+ // Set up requested objects for soft QCD processes.
+ bool softQCD = Settings::flag("SoftQCD:all");
+ if (softQCD || Settings::flag("SoftQCD:minBias")) {
+ sigmaPtr = new Sigma0minBias;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (softQCD || Settings::flag("SoftQCD:elastic")) {
+ sigmaPtr = new Sigma0AB2AB;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (softQCD || Settings::flag("SoftQCD:singleDiffractive")) {
+ sigmaPtr = new Sigma0AB2XB;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma0AB2AX;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (softQCD || Settings::flag("SoftQCD:doubleDiffractive")) {
+ sigmaPtr = new Sigma0AB2XX;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for hard QCD processes.
+ bool hardQCD = Settings::flag("HardQCD:all");
+ if (hardQCD || Settings::flag("HardQCD:gg2gg")) {
+ sigmaPtr = new Sigma2gg2gg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:gg2qqbar")) {
+ sigmaPtr = new Sigma2gg2qqbar;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:qg2qg")) {
+ sigmaPtr = new Sigma2qg2qg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:qq2qq")) {
+ sigmaPtr = new Sigma2qq2qq;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:qqbar2gg")) {
+ sigmaPtr = new Sigma2qqbar2gg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:qqbar2qqbarNew")) {
+ sigmaPtr = new Sigma2qqbar2qqbarNew;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for c cbar and b bbar, also hard QCD.
+ if (hardQCD || Settings::flag("HardQCD:gg2ccbar")) {
+ sigmaPtr = new Sigma2gg2QQbar(4, 121);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:qqbar2ccbar")) {
+ sigmaPtr = new Sigma2qqbar2QQbar(4, 122);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:gg2bbbar")) {
+ sigmaPtr = new Sigma2gg2QQbar(5, 123);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (hardQCD || Settings::flag("HardQCD:qqbar2bbbar")) {
+ sigmaPtr = new Sigma2qqbar2QQbar(5, 124);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for prompt photon processes.
+ bool promptPhotons = Settings::flag("PromptPhoton:all");
+ if (promptPhotons
+ || Settings::flag("PromptPhoton:qg2qgamma")) {
+ sigmaPtr = new Sigma2qg2qgamma;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (promptPhotons
+ || Settings::flag("PromptPhoton:qqbar2ggamma")) {
+ sigmaPtr = new Sigma2qqbar2ggamma;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (promptPhotons
+ || Settings::flag("PromptPhoton:gg2ggamma")) {
+ sigmaPtr = new Sigma2gg2ggamma;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (promptPhotons
+ || Settings::flag("PromptPhoton:ffbar2gammagamma")) {
+ sigmaPtr = new Sigma2ffbar2gammagamma;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (promptPhotons
+ || Settings::flag("PromptPhoton:gg2gammagamma")) {
+ sigmaPtr = new Sigma2gg2gammagamma;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for weak gauge boson t-channel exchange.
+ bool weakBosonExchanges = Settings::flag("WeakBosonExchange:all");
+ if (weakBosonExchanges
+ || Settings::flag("WeakBosonExchange:ff2ff(t:gmZ)")) {
+ sigmaPtr = new Sigma2ff2fftgmZ;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonExchanges
+ || Settings::flag("WeakBosonExchange:ff2ff(t:W)")) {
+ sigmaPtr = new Sigma2ff2fftW;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for weak gauge boson processes.
+ bool weakSingleBosons = Settings::flag("WeakSingleBoson:all");
+ if (weakSingleBosons
+ || Settings::flag("WeakSingleBoson:ffbar2gmZ")) {
+ sigmaPtr = new Sigma1ffbar2gmZ;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakSingleBosons
+ || Settings::flag("WeakSingleBoson:ffbar2W")) {
+ sigmaPtr = new Sigma1ffbar2W;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested object for s-channel gamma exchange.
+ // Subset of gamma*/Z0 above, intended for Multiple interactions.
+ if (Settings::flag("WeakSingleBoson:ffbar2ffbar(s:gm)")) {
+ sigmaPtr = new Sigma2ffbar2ffbarsgm;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for weak gauge boson pair processes.
+ bool weakDoubleBosons = Settings::flag("WeakDoubleBoson:all");
+ if (weakDoubleBosons
+ || Settings::flag("WeakDoubleBoson:ffbar2gmZgmZ")) {
+ sigmaPtr = new Sigma2ffbar2gmZgmZ;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakDoubleBosons
+ || Settings::flag("WeakDoubleBoson:ffbar2ZW")) {
+ sigmaPtr = new Sigma2ffbar2ZW;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakDoubleBosons
+ || Settings::flag("WeakDoubleBoson:ffbar2WW")) {
+ sigmaPtr = new Sigma2ffbar2WW;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for weak gauge boson + parton processes.
+ bool weakBosonAndPartons = Settings::flag("WeakBosonAndParton:all");
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:qqbar2gmZg")) {
+ sigmaPtr = new Sigma2qqbar2gmZg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:qg2gmZq")) {
+ sigmaPtr = new Sigma2qg2gmZq;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:ffbar2gmZgm")) {
+ sigmaPtr = new Sigma2ffbar2gmZgm;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:fgm2gmZf")) {
+ sigmaPtr = new Sigma2fgm2gmZf;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:qqbar2Wg")) {
+ sigmaPtr = new Sigma2qqbar2Wg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:qg2Wq")) {
+ sigmaPtr = new Sigma2qg2Wq;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:ffbar2Wgm")) {
+ sigmaPtr = new Sigma2ffbar2Wgm;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (weakBosonAndPartons
+ || Settings::flag("WeakBosonAndParton:fgm2Wf")) {
+ sigmaPtr = new Sigma2fgm2Wf;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for charmonium production
+ bool charmoniums = Settings::flag("Charmonium:all");
+ if (charmoniums || Settings::flag("Charmonium:gg2QQbar[3S1(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3S11g(4, 401);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:gg2QQbar[3P0(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3PJ1g(4, 0, 402);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:gg2QQbar[3P1(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3PJ1g(4, 1, 403);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:gg2QQbar[3P2(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3PJ1g(4, 2, 404);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qg2QQbar[3P0(1)]q")) {
+ sigmaPtr = new Sigma2qg2QQbar3PJ1q(4, 0, 405);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qg2QQbar[3P1(1)]q")) {
+ sigmaPtr = new Sigma2qg2QQbar3PJ1q(4, 1, 406);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qg2QQbar[3P2(1)]q")) {
+ sigmaPtr = new Sigma2qg2QQbar3PJ1q(4, 2, 407);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qqbar2QQbar[3P0(1)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbar3PJ1g(4, 0, 408);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qqbar2QQbar[3P1(1)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbar3PJ1g(4, 1, 409);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qqbar2QQbar[3P2(1)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbar3PJ1g(4, 2, 410);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:gg2QQbar[3S1(8)]g")) {
+ sigmaPtr = new Sigma2gg2QQbarX8g(4, 0, 411);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:gg2QQbar[1S0(8)]g")) {
+ sigmaPtr = new Sigma2gg2QQbarX8g(4, 1, 412);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:gg2QQbar[3PJ(8)]g")) {
+ sigmaPtr = new Sigma2gg2QQbarX8g(4, 2, 413);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qg2QQbar[3S1(8)]q")) {
+ sigmaPtr = new Sigma2qg2QQbarX8q(4, 0, 414);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qg2QQbar[1S0(8)]q")) {
+ sigmaPtr = new Sigma2qg2QQbarX8q(4, 1, 415);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qg2QQbar[3PJ(8)]q")) {
+ sigmaPtr = new Sigma2qg2QQbarX8q(4, 2, 416);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qqbar2QQbar[3S1(8)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbarX8g(4, 0, 417);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qqbar2QQbar[1S0(8)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbarX8g(4, 1, 418);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (charmoniums || Settings::flag("Charmonium:qqbar2QQbar[3PJ(8)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbarX8g(4, 2, 419);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for bottomonium production
+ bool bottomoniums = Settings::flag("Bottomonium:all");
+ if (bottomoniums || Settings::flag("Bottomonium:gg2QQbar[3S1(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3S11g(5, 501);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:gg2QQbar[3P0(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3PJ1g(5, 0, 502);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:gg2QQbar[3P1(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3PJ1g(5, 1, 503);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:gg2QQbar[3P2(1)]g")) {
+ sigmaPtr = new Sigma2gg2QQbar3PJ1g(5, 2, 504);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qg2QQbar[3P0(1)]q")) {
+ sigmaPtr = new Sigma2qg2QQbar3PJ1q(5, 0, 505);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qg2QQbar[3P1(1)]q")) {
+ sigmaPtr = new Sigma2qg2QQbar3PJ1q(5, 1, 506);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qg2QQbar[3P2(1)]q")) {
+ sigmaPtr = new Sigma2qg2QQbar3PJ1q(5, 2, 507);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qqbar2QQbar[3P0(1)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbar3PJ1g(5, 0, 508);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qqbar2QQbar[3P1(1)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbar3PJ1g(5, 1, 509);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qqbar2QQbar[3P2(1)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbar3PJ1g(5, 2, 510);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:gg2QQbar[3S1(8)]g")) {
+ sigmaPtr = new Sigma2gg2QQbarX8g(5, 0, 511);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:gg2QQbar[1S0(8)]g")) {
+ sigmaPtr = new Sigma2gg2QQbarX8g(5, 1, 512);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:gg2QQbar[3PJ(8)]g")) {
+ sigmaPtr = new Sigma2gg2QQbarX8g(5, 2, 513);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qg2QQbar[3S1(8)]q")) {
+ sigmaPtr = new Sigma2qg2QQbarX8q(5, 0, 514);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qg2QQbar[1S0(8)]q")) {
+ sigmaPtr = new Sigma2qg2QQbarX8q(5, 1, 515);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qg2QQbar[3PJ(8)]q")) {
+ sigmaPtr = new Sigma2qg2QQbarX8q(5, 2, 516);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qqbar2QQbar[3S1(8)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbarX8g(5, 0, 517);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qqbar2QQbar[1S0(8)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbarX8g(5, 1, 518);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bottomoniums || Settings::flag("Bottomonium:qqbar2QQbar[3PJ(8)]g")) {
+ sigmaPtr = new Sigma2qqbar2QQbarX8g(5, 2, 519);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for top production
+ bool tops = Settings::flag("Top:all");
+ if (tops || Settings::flag("Top:gg2ttbar")) {
+ sigmaPtr = new Sigma2gg2QQbar(6, 601);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tops || Settings::flag("Top:qqbar2ttbar")) {
+ sigmaPtr = new Sigma2qqbar2QQbar(6, 602);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tops || Settings::flag("Top:qq2tq(t:W)")) {
+ sigmaPtr = new Sigma2qq2QqtW(6, 603);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tops || Settings::flag("Top:ffbar2ttbar(s:gmZ)")) {
+ sigmaPtr = new Sigma2ffbar2FFbarsgmZ(6, 604);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tops || Settings::flag("Top:ffbar2tqbar(s:W)")) {
+ sigmaPtr = new Sigma2ffbar2FfbarsW(6, 0, 605);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for fourth-generation b' production
+ bool bPrimes = Settings::flag("FourthBottom:all");
+ if (bPrimes || Settings::flag("FourthBottom:gg2bPrimebPrimebar")) {
+ sigmaPtr = new Sigma2gg2QQbar(7, 801);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bPrimes || Settings::flag("FourthBottom:qqbar2bPrimebPrimebar")) {
+ sigmaPtr = new Sigma2qqbar2QQbar(7, 802);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bPrimes || Settings::flag("FourthBottom:qq2bPrimeq(t:W)")) {
+ sigmaPtr = new Sigma2qq2QqtW(7, 803);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bPrimes || Settings::flag("FourthBottom:ffbar2bPrimebPrimebar(s:gmZ)")) {
+ sigmaPtr = new Sigma2ffbar2FFbarsgmZ(7, 804);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bPrimes || Settings::flag("FourthBottom:ffbar2bPrimeqbar(s:W)")) {
+ sigmaPtr = new Sigma2ffbar2FfbarsW(7, 0, 805);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (bPrimes || Settings::flag("FourthBottom:ffbar2bPrimetbar(s:W)")) {
+ sigmaPtr = new Sigma2ffbar2FfbarsW(7, 6, 806);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for fourth-generation t' production
+ bool tPrimes = Settings::flag("FourthTop:all");
+ if (tPrimes || Settings::flag("FourthTop:gg2tPrimetPrimebar")) {
+ sigmaPtr = new Sigma2gg2QQbar(8, 821);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tPrimes || Settings::flag("FourthTop:qqbar2tPrimetPrimebar")) {
+ sigmaPtr = new Sigma2qqbar2QQbar(8, 822);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tPrimes || Settings::flag("FourthTop:qq2tPrimeq(t:W)")) {
+ sigmaPtr = new Sigma2qq2QqtW(8, 823);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tPrimes || Settings::flag("FourthTop:ffbar2tPrimetPrimebar(s:gmZ)")) {
+ sigmaPtr = new Sigma2ffbar2FFbarsgmZ(8, 824);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (tPrimes || Settings::flag("FourthTop:ffbar2tPrimeqbar(s:W)")) {
+ sigmaPtr = new Sigma2ffbar2FfbarsW(8, 0, 825);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for two different fourth-generation fermions.
+ if (bPrimes || tPrimes
+ || Settings::flag("FourthPair:ffbar2tPrimebPrimebar(s:W)")) {
+ sigmaPtr = new Sigma2ffbar2FfbarsW(8, 7, 841);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("FourthPair:ffbar2tauPrimenuPrimebar(s:W)")) {
+ sigmaPtr = new Sigma2ffbar2FfbarsW(17, 18, 842);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Flag for global choice between SM and BSM Higgses.
+ bool useBSMHiggses = Settings::flag("Higgs:useBSM");
+
+ // Set up requested objects for Standard-Model Higgs production.
+ if (!useBSMHiggses) {
+ bool HiggsesSM = Settings::flag("HiggsSM:all");
+ if (HiggsesSM || Settings::flag("HiggsSM:ffbar2H")) {
+ sigmaPtr = new Sigma1ffbar2H(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:gg2H")) {
+ sigmaPtr = new Sigma1gg2H(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:gmgm2H")) {
+ sigmaPtr = new Sigma1gmgm2H(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:ffbar2HZ")) {
+ sigmaPtr = new Sigma2ffbar2HZ(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:ffbar2HW")) {
+ sigmaPtr = new Sigma2ffbar2HW(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:ff2Hff(t:ZZ)")) {
+ sigmaPtr = new Sigma3ff2HfftZZ(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:ff2Hff(t:WW)")) {
+ sigmaPtr = new Sigma3ff2HfftWW(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:gg2Httbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(6,0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesSM || Settings::flag("HiggsSM:qqbar2Httbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(6,0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Further Standard-Model Higgs processes, not included in "all".
+ if (Settings::flag("HiggsSM:qg2Hq")) {
+ sigmaPtr = new Sigma2qg2Hq(4,0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qg2Hq(5,0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsSM:gg2Hbbbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(5,0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsSM:qqbar2Hbbbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(5,0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsSM:gg2Hg(l:t)")) {
+ sigmaPtr = new Sigma2gg2Hglt(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsSM:qg2Hq(l:t)")) {
+ sigmaPtr = new Sigma2qg2Hqlt(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsSM:qqbar2Hg(l:t)")) {
+ sigmaPtr = new Sigma2qqbar2Hglt(0);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ }
+
+ // Common switch for the group of Higgs production BSM.
+ if (useBSMHiggses) {
+ bool HiggsesBSM = Settings::flag("HiggsBSM:all");
+
+ // Set up requested objects for BSM H1 production.
+ bool HiggsesH1 = Settings::flag("HiggsBSM:allH1");
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:ffbar2H1")) {
+ sigmaPtr = new Sigma1ffbar2H(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:gg2H1")) {
+ sigmaPtr = new Sigma1gg2H(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:gmgm2H1")) {
+ sigmaPtr = new Sigma1gmgm2H(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:ffbar2H1Z")) {
+ sigmaPtr = new Sigma2ffbar2HZ(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:ffbar2H1W")) {
+ sigmaPtr = new Sigma2ffbar2HW(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:ff2H1ff(t:ZZ)")) {
+ sigmaPtr = new Sigma3ff2HfftZZ(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:ff2H1ff(t:WW)")) {
+ sigmaPtr = new Sigma3ff2HfftWW(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:gg2H1ttbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(6,1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH1 || Settings::flag("HiggsBSM:qqbar2H1ttbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(6,1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Further BSM H1 processes, not included in "all".
+ if (Settings::flag("HiggsBSM:qg2H1q")) {
+ sigmaPtr = new Sigma2qg2Hq(4,1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qg2Hq(5,1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:gg2H1bbbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(5,1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qqbar2H1bbbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(5,1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:gg2H1g(l:t)")) {
+ sigmaPtr = new Sigma2gg2Hglt(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qg2H1q(l:t)")) {
+ sigmaPtr = new Sigma2qg2Hqlt(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qqbar2H1g(l:t)")) {
+ sigmaPtr = new Sigma2qqbar2Hglt(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for BSM H2 production.
+ bool HiggsesH2 = Settings::flag("HiggsBSM:allH2");
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:ffbar2H2")) {
+ sigmaPtr = new Sigma1ffbar2H(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:gg2H2")) {
+ sigmaPtr = new Sigma1gg2H(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:gmgm2H2")) {
+ sigmaPtr = new Sigma1gmgm2H(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:ffbar2H2Z")) {
+ sigmaPtr = new Sigma2ffbar2HZ(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:ffbar2H2W")) {
+ sigmaPtr = new Sigma2ffbar2HW(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:ff2H2ff(t:ZZ)")) {
+ sigmaPtr = new Sigma3ff2HfftZZ(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:ff2H2ff(t:WW)")) {
+ sigmaPtr = new Sigma3ff2HfftWW(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:gg2H2ttbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(6,2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesH2 || Settings::flag("HiggsBSM:qqbar2H2ttbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(6,2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Further BSM H2 processes, not included in "all".
+ if (Settings::flag("HiggsBSM:qg2H2q")) {
+ sigmaPtr = new Sigma2qg2Hq(4,2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qg2Hq(5,2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:gg2H2bbbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(5,2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qqbar2H2bbbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(5,2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:gg2H2g(l:t)")) {
+ sigmaPtr = new Sigma2gg2Hglt(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qg2H2q(l:t)")) {
+ sigmaPtr = new Sigma2qg2Hqlt(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qqbar2H2g(l:t)")) {
+ sigmaPtr = new Sigma2qqbar2Hglt(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for BSM A3 production.
+ bool HiggsesA3 = Settings::flag("HiggsBSM:allA3");
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:ffbar2A3")) {
+ sigmaPtr = new Sigma1ffbar2H(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:gg2A3")) {
+ sigmaPtr = new Sigma1gg2H(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:gmgm2A3")) {
+ sigmaPtr = new Sigma1gmgm2H(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:ffbar2A3Z")) {
+ sigmaPtr = new Sigma2ffbar2HZ(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:ffbar2A3W")) {
+ sigmaPtr = new Sigma2ffbar2HW(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:ff2A3ff(t:ZZ)")) {
+ sigmaPtr = new Sigma3ff2HfftZZ(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:ff2A3ff(t:WW)")) {
+ sigmaPtr = new Sigma3ff2HfftWW(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:gg2A3ttbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(6,3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesA3 || Settings::flag("HiggsBSM:qqbar2A3ttbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(6,3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Further BSM A3 processes, not included in "all".
+ if (Settings::flag("HiggsBSM:qg2A3q")) {
+ sigmaPtr = new Sigma2qg2Hq(4,3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qg2Hq(5,3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:gg2A3bbbar")) {
+ sigmaPtr = new Sigma3gg2HQQbar(5,3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qqbar2A3bbbar")) {
+ sigmaPtr = new Sigma3qqbar2HQQbar(5,3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:gg2A3g(l:t)")) {
+ sigmaPtr = new Sigma2gg2Hglt(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qg2A3q(l:t)")) {
+ sigmaPtr = new Sigma2qg2Hqlt(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("HiggsBSM:qqbar2A3g(l:t)")) {
+ sigmaPtr = new Sigma2qqbar2Hglt(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for Charged Higgs production
+ bool HiggsesChg = Settings::flag("HiggsBSM:allH+-");
+ if (HiggsesBSM || HiggsesChg || Settings::flag("HiggsBSM:ffbar2H+-")) {
+ sigmaPtr = new Sigma1ffbar2Hchg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesChg || Settings::flag("HiggsBSM:bg2H+-t")) {
+ sigmaPtr = new Sigma2qg2Hchgq(6, 1062, "b g -> H+- t");
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for Higgs pair-production
+ bool HiggsesPairs = Settings::flag("HiggsBSM:allHpair");
+ if (HiggsesBSM || HiggsesPairs || Settings::flag("HiggsBSM:ffbar2A3H1")) {
+ sigmaPtr = new Sigma2ffbar2A3H12(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesPairs || Settings::flag("HiggsBSM:ffbar2A3H2")) {
+ sigmaPtr = new Sigma2ffbar2A3H12(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesPairs || Settings::flag("HiggsBSM:ffbar2H+-H1")) {
+ sigmaPtr = new Sigma2ffbar2HchgH12(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesPairs || Settings::flag("HiggsBSM:ffbar2H+-H2")) {
+ sigmaPtr = new Sigma2ffbar2HchgH12(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (HiggsesBSM || HiggsesPairs || Settings::flag("HiggsBSM:ffbar2H+H-")) {
+ sigmaPtr = new Sigma2ffbar2HposHneg();
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ }
+
+ // Set up requested objects for neutralino pair processes.
+ bool SUSYs = Settings::flag("SUSY:all");
+ if (SUSYs || Settings::flag("SUSY:qqbar2chi0chi0")) {
+ sigmaPtr = new Sigma2qqbar2chi0chi0(1, 1, 1201);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(1, 2, 1202);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(1, 3, 1203);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(1, 4, 1204);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(2, 2, 1205);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(2, 3, 1206);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(2, 4, 1207);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(3, 3, 1208);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(3, 4, 1209);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2chi0chi0(4, 4, 1210);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for New-Gauge-Boson processes.
+ if (Settings::flag("NewGaugeBoson:ffbar2gmZZprime")) {
+ sigmaPtr = new Sigma1ffbar2gmZZprime();
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("NewGaugeBoson:ffbar2Wprime")) {
+ sigmaPtr = new Sigma1ffbar2Wprime();
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("NewGaugeBoson:ffbar2R0")) {
+ sigmaPtr = new Sigma1ffbar2Rhorizontal();
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for Left-Right-Symmetry processes.
+ bool leftrights = Settings::flag("LeftRightSymmmetry:all");
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ffbar2ZR")) {
+ sigmaPtr = new Sigma1ffbar2ZRight();
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ffbar2WR")) {
+ sigmaPtr = new Sigma1ffbar2WRight();
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ll2HL")) {
+ sigmaPtr = new Sigma1ll2Hchgchg(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:lgm2HLe")) {
+ sigmaPtr = new Sigma2lgm2Hchgchgl(1, 11);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:lgm2HLmu")) {
+ sigmaPtr = new Sigma2lgm2Hchgchgl(1, 13);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:lgm2HLtau")) {
+ sigmaPtr = new Sigma2lgm2Hchgchgl(1, 15);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ff2HLff")) {
+ sigmaPtr = new Sigma3ff2HchgchgfftWW(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ffbar2HLHL")) {
+ sigmaPtr = new Sigma2ffbar2HchgchgHchgchg(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ll2HR")) {
+ sigmaPtr = new Sigma1ll2Hchgchg(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:lgm2HRe")) {
+ sigmaPtr = new Sigma2lgm2Hchgchgl(2, 11);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:lgm2HRmu")) {
+ sigmaPtr = new Sigma2lgm2Hchgchgl(2, 13);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:lgm2HRtau")) {
+ sigmaPtr = new Sigma2lgm2Hchgchgl(2, 15);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ff2HRff")) {
+ sigmaPtr = new Sigma3ff2HchgchgfftWW(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leftrights || Settings::flag("LeftRightSymmmetry:ffbar2HRHR")) {
+ sigmaPtr = new Sigma2ffbar2HchgchgHchgchg(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for leptoquark LQ processes.
+ bool leptoquarks = Settings::flag("LeptoQuark:all");
+ if (leptoquarks || Settings::flag("LeptoQuark:ql2LQ")) {
+ sigmaPtr = new Sigma1ql2LeptoQuark;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leptoquarks || Settings::flag("LeptoQuark:qg2LQl")) {
+ sigmaPtr = new Sigma2qg2LeptoQuarkl;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leptoquarks || Settings::flag("LeptoQuark:gg2LQLQbar")) {
+ sigmaPtr = new Sigma2gg2LQLQbar;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (leptoquarks || Settings::flag("LeptoQuark:qqbar2LQLQbar")) {
+ sigmaPtr = new Sigma2qqbar2LQLQbar;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for excited-fermion processes.
+ bool excitedfermions = Settings::flag("ExcitedFermion:all");
+ if (excitedfermions || Settings::flag("ExcitedFermion:dg2dStar")) {
+ sigmaPtr = new Sigma1qg2qStar(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:ug2uStar")) {
+ sigmaPtr = new Sigma1qg2qStar(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:sg2sStar")) {
+ sigmaPtr = new Sigma1qg2qStar(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:cg2cStar")) {
+ sigmaPtr = new Sigma1qg2qStar(4);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:bg2bStar")) {
+ sigmaPtr = new Sigma1qg2qStar(5);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:egm2eStar")) {
+ sigmaPtr = new Sigma1lgm2lStar(11);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:mugm2muStar")) {
+ sigmaPtr = new Sigma1lgm2lStar(13);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:taugm2tauStar")) {
+ sigmaPtr = new Sigma1lgm2lStar(15);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qq2dStarq")) {
+ sigmaPtr = new Sigma2qq2qStarq(1);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qq2uStarq")) {
+ sigmaPtr = new Sigma2qq2qStarq(2);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qq2sStarq")) {
+ sigmaPtr = new Sigma2qq2qStarq(3);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qq2cStarq")) {
+ sigmaPtr = new Sigma2qq2qStarq(4);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qq2bStarq")) {
+ sigmaPtr = new Sigma2qq2qStarq(5);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qqbar2eStare")) {
+ sigmaPtr = new Sigma2qqbar2lStarlbar(11);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qqbar2nueStarnue")) {
+ sigmaPtr = new Sigma2qqbar2lStarlbar(12);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qqbar2muStarmu")) {
+ sigmaPtr = new Sigma2qqbar2lStarlbar(13);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qqbar2numuStarnumu")) {
+ sigmaPtr = new Sigma2qqbar2lStarlbar(14);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qqbar2tauStartau")) {
+ sigmaPtr = new Sigma2qqbar2lStarlbar(15);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (excitedfermions || Settings::flag("ExcitedFermion:qqbar2nutauStarnutau")) {
+ sigmaPtr = new Sigma2qqbar2lStarlbar(16);
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Set up requested objects for extra-dimensional G* processes.
+ bool extraDimGstars = Settings::flag("ExtraDimensionsG*:all");
+ if (extraDimGstars || Settings::flag("ExtraDimensionsG*:gg2G*")) {
+ sigmaPtr = new Sigma1gg2GravitonStar;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (extraDimGstars || Settings::flag("ExtraDimensionsG*:ffbar2G*")) {
+ sigmaPtr = new Sigma1ffbar2GravitonStar;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("ExtraDimensionsG*:gg2G*g")) {
+ sigmaPtr = new Sigma2gg2GravitonStarg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("ExtraDimensionsG*:qg2G*q")) {
+ sigmaPtr = new Sigma2qg2GravitonStarq;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+ if (Settings::flag("ExtraDimensionsG*:qqbar2G*g")) {
+ sigmaPtr = new Sigma2qqbar2GravitonStarg;
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Routine to initialize list of second hard processes.
+
+bool SetupContainers::init2(vector<ProcessContainer*>& container2Ptrs) {
+
+ // Reset process list, if filled in previous subrun.
+ if (container2Ptrs.size() > 0) {
+ for (int i = 0; i < int(container2Ptrs.size()); ++i)
+ delete container2Ptrs[i];
+ container2Ptrs.clear();
+ }
+ SigmaProcess* sigmaPtr;
+
+ // Two hard QCD jets.
+ if (Settings::flag("SecondHard:TwoJets")) {
+ sigmaPtr = new Sigma2gg2gg;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2gg2qqbar;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qg2qg;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qq2qq;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2gg;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2qqbarNew;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2gg2QQbar(4, 121);
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2QQbar(4, 122);
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2gg2QQbar(5, 123);
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2QQbar(5, 124);
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // A prompt photon and a hard jet.
+ if (Settings::flag("SecondHard:PhotonAndJet")) {
+ sigmaPtr = new Sigma2qg2qgamma;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2ggamma;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2gg2ggamma;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Two prompt photons.
+ if (Settings::flag("SecondHard:TwoPhotons")) {
+ sigmaPtr = new Sigma2ffbar2gammagamma;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2gg2gammagamma;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // A single gamma*/Z0.
+ if (Settings::flag("SecondHard:SingleGmZ")) {
+ sigmaPtr = new Sigma1ffbar2gmZ;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // A single W+-.
+ if (Settings::flag("SecondHard:SingleW")) {
+ sigmaPtr = new Sigma1ffbar2W;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // A gamma*/Z0 and a hard jet.
+ if (Settings::flag("SecondHard:GmZAndJet")) {
+ sigmaPtr = new Sigma2qqbar2gmZg;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qg2gmZq;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // A W+- and a hard jet.
+ if (Settings::flag("SecondHard:WAndJet")) {
+ sigmaPtr = new Sigma2qqbar2Wg;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qg2Wq;
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Two b jets - already part of TwoJets sample above.
+ if (Settings::flag("SecondHard:TwoBJets")) {
+ sigmaPtr = new Sigma2gg2QQbar(5, 123);
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ sigmaPtr = new Sigma2qqbar2QQbar(5, 124);
+ container2Ptrs.push_back( new ProcessContainer(sigmaPtr) );
+ }
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// ProcessLevel.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the ProcessLevel class.
+
+#include "ProcessLevel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ProcessLevel class.
+
+//*********
+
+// Destructor.
+
+ProcessLevel::~ProcessLevel() {
+
+ // Run through list of first hard processes and delete them.
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ delete containerPtrs[i];
+
+ // Run through list of second hard processes and delete them.
+ for (int i =0; i < int(container2Ptrs.size()); ++i)
+ delete container2Ptrs[i];
+
+}
+
+//*********
+
+// Main routine to initialize generation process.
+
+bool ProcessLevel::init( Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn, SigmaTotal* sigmaTotPtrIn, bool doLHA,
+ SusyLesHouches* slhaPtrIn, UserHooks* userHooksPtrIn,
+ vector<SigmaProcess*>& sigmaPtrs, ostream& os) {
+
+ // Store input pointers for future use.
+ infoPtr = infoPtrIn;
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+ sigmaTotPtr = sigmaTotPtrIn;
+ userHooksPtr = userHooksPtrIn;
+ slhaPtr = slhaPtrIn;
+
+ // Send on some input pointers.
+ resonanceDecays.init( infoPtr);
+
+ // Options to allow second hard interaction and resonance decays.
+ doSecondHard = Settings::flag("SecondHard:generate");
+ doResDecays = Settings::flag("ProcessLevel:resonanceDecays");
+
+ // Set up SigmaTotal. Store sigma_nondiffractive for future use.
+ sigmaTotPtr->init( infoPtr);
+ int idA = infoPtr->idA();
+ int idB = infoPtr->idB();
+ double eCM = infoPtr->eCM();
+ sigmaTotPtr->calc( idA, idB, eCM);
+ sigmaND = sigmaTotPtr->sigmaND();
+
+ // Initialize SUSY Les Houches Accord data
+ if (!initSLHA()) return false;
+
+ // Set up containers for all the internal hard processes.
+ SetupContainers setupContainers;
+ setupContainers.init(containerPtrs);
+
+ // Append containers for external hard processes, if any.
+ if (sigmaPtrs.size() > 0) {
+ for (int iSig = 0; iSig < int(sigmaPtrs.size()); ++iSig)
+ containerPtrs.push_back( new ProcessContainer(sigmaPtrs[iSig]) );
+ }
+
+ // Append single container for Les Houches processes, if any.
+ if (doLHA) {
+ SigmaProcess* sigmaPtr = new SigmaLHAProcess();
+ containerPtrs.push_back( new ProcessContainer(sigmaPtr) );
+
+ // Store location of this container, and send in LHA pointer.
+ iLHACont = containerPtrs.size() - 1;
+ containerPtrs[iLHACont]->setLHAPtr(lhaUpPtr);
+ }
+
+ // If no processes found then refuse to do anything.
+ if ( int(containerPtrs.size()) == 0) {
+ infoPtr->errorMsg("Error in ProcessLevel::init: "
+ "no process switched on");
+ return false;
+ }
+
+ // Initialize alphaStrong generation for SigmaProcess.
+ double alphaSvalue = Settings::parm("SigmaProcess:alphaSvalue");
+ int alphaSorder = Settings::mode("SigmaProcess:alphaSorder");
+ alphaS.init( alphaSvalue, alphaSorder);
+
+ // Initialize alphaEM generation for SigmaProcess.
+ int alphaEMorder = Settings::mode("SigmaProcess:alphaEMorder");
+ alphaEM.init( alphaEMorder);
+
+ // Initialize each process.
+ int numberOn = 0;
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ if (containerPtrs[i]->init(infoPtr, beamAPtr, beamBPtr, &alphaS,
+ &alphaEM, sigmaTotPtr, &resonanceDecays, slhaPtr, userHooksPtr))
+ ++numberOn;
+
+ // Sum maxima for Monte Carlo choice.
+ sigmaMaxSum = 0.;
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ sigmaMaxSum += containerPtrs[i]->sigmaMax();
+
+ // Option to pick a second hard interaction: repeat as above.
+ int number2On = 0;
+ if (doSecondHard) {
+ setupContainers.init2(container2Ptrs);
+ if ( int(container2Ptrs.size()) == 0) {
+ infoPtr->errorMsg("Error in ProcessLevel::init: "
+ "no second hard process switched on");
+ return false;
+ }
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ if (container2Ptrs[i2]->init(infoPtr, beamAPtr, beamBPtr, &alphaS,
+ &alphaEM, sigmaTotPtr, &resonanceDecays, slhaPtr, userHooksPtr))
+ ++number2On;
+ sigma2MaxSum = 0.;
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ sigma2MaxSum += container2Ptrs[i2]->sigmaMax();
+ }
+
+ // Construct string with incoming beams and for cm energy.
+ string collision = "We collide " + ParticleDataTable::name(idA)
+ + " with " + ParticleDataTable::name(idB) + " at a CM energy of ";
+ string pad( 51 - collision.length(), ' ');
+
+ // Print initialization information: header.
+ os << "\n *------- PYTHIA Process Initialization ---------"
+ << "-----------------*\n"
+ << " | "
+ << " |\n"
+ << " | " << collision << scientific << setprecision(3)<< setw(9) << eCM
+ << " GeV" << pad << " |\n"
+ << " | "
+ << " |\n"
+ << " |---------------------------------------------------"
+ << "---------------|\n"
+ << " | "
+ << " | |\n"
+ << " | Subprocess Code"
+ << " | Estimated |\n"
+ << " | "
+ << " | max (mb) |\n"
+ << " | "
+ << " | |\n"
+ << " |---------------------------------------------------"
+ << "---------------|\n"
+ << " | "
+ << " | |\n";
+
+
+ // Loop over existing processes: print individual process info.
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ os << " | " << left << setw(45) << containerPtrs[i]->name()
+ << right << setw(5) << containerPtrs[i]->code() << " | "
+ << scientific << setprecision(3) << setw(11)
+ << containerPtrs[i]->sigmaMax() << " |\n";
+
+ // Loop over second hard processes, if any, and repeat as above.
+ if (doSecondHard) {
+ os << " | "
+ << " | |\n"
+ << " |---------------------------------------------------"
+ <<"---------------|\n"
+ << " | "
+ <<" | |\n";
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ os << " | " << left << setw(45) << container2Ptrs[i2]->name()
+ << right << setw(5) << container2Ptrs[i2]->code() << " | "
+ << scientific << setprecision(3) << setw(11)
+ << container2Ptrs[i2]->sigmaMax() << " |\n";
+ }
+
+ // Listing finished.
+ os << " | "
+ << " |\n"
+ << " *------- End PYTHIA Process Initialization ----------"
+ <<"-------------*" << endl;
+
+ // If sum of maxima vanishes then refuse to do anything.
+ if ( numberOn == 0 || sigmaMaxSum <= 0.) {
+ infoPtr->errorMsg("Error in ProcessLevel::init: "
+ "all processes have vanishing cross sections");
+ return false;
+ }
+ if ( doSecondHard && (number2On == 0 || sigma2MaxSum <= 0.) ) {
+ infoPtr->errorMsg("Error in ProcessLevel::init: "
+ "all second hard processes have vanishing cross sections");
+ return false;
+ }
+
+ // If two hard processes then check whether some (but not all) agree.
+ allHardSame = true;
+ noneHardSame = true;
+ if (doSecondHard) {
+ bool foundMatch = false;
+
+ // Check for each first process if matched in second.
+ for (int i = 0; i < int(containerPtrs.size()); ++i) {
+ foundMatch = false;
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ if (container2Ptrs[i2]->code() == containerPtrs[i]->code())
+ foundMatch = true;
+ containerPtrs[i]->isSame( foundMatch );
+ if (!foundMatch) allHardSame = false;
+ if ( foundMatch) noneHardSame = false;
+ }
+
+ // Check for each second process if matched in first.
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2) {
+ foundMatch = false;
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ if (containerPtrs[i]->code() == container2Ptrs[i2]->code())
+ foundMatch = true;
+ container2Ptrs[i2]->isSame( foundMatch );
+ if (!foundMatch) allHardSame = false;
+ if ( foundMatch) noneHardSame = false;
+ }
+ }
+ someHardSame = !allHardSame && !noneHardSame;
+
+ // Reset counters for average impact-parameter enhancement.
+ nImpact = 0;
+ sumImpactFac = 0.;
+ sum2ImpactFac = 0.;
+
+ // Statistics for LHA events.
+ codeLHA.resize(0);
+ nEvtLHA.resize(0);
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Main routine to generate the hard process.
+
+bool ProcessLevel::next( Event& process) {
+
+ // Generate the next event with two or one hard interactions.
+ bool physical = (doSecondHard) ? nextTwo( process) : nextOne( process);
+
+ // Check that colour assignments make sense.
+ if (physical) physical = checkColours( process);
+
+ // Done.
+ return physical;
+}
+
+//*********
+
+// Accumulate and update statistics (after possible user veto).
+
+void ProcessLevel::accumulate() {
+
+ // Increase number of accepted events.
+ containerPtrs[iContainer]->accumulate();
+
+ // Provide current generated cross section estimate.
+ long nTrySum = 0;
+ long nSelSum = 0;
+ long nAccSum = 0;
+ double sigmaSum = 0.;
+ double delta2Sum = 0.;
+ double sigSelSum = 0.;
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ if (containerPtrs[i]->sigmaMax() != 0.) {
+ nTrySum += containerPtrs[i]->nTried();
+ nSelSum += containerPtrs[i]->nSelected();
+ nAccSum += containerPtrs[i]->nAccepted();
+ sigmaSum += containerPtrs[i]->sigmaMC();
+ delta2Sum += pow2(containerPtrs[i]->deltaMC());
+ sigSelSum += containerPtrs[i]->sigmaSelMC();
+ }
+
+ // For Les Houches events find subprocess type and update counter.
+ if (infoPtr->isLHA()) {
+ int codeLHANow = infoPtr->codeSub();
+ int iFill = -1;
+ for (int i = 0; i < int(codeLHA.size()); ++i)
+ if (codeLHANow == codeLHA[i]) iFill = i;
+ if (iFill >= 0) ++nEvtLHA[iFill];
+
+ // Add new process when new code and then arrange in order.
+ else {
+ codeLHA.push_back(codeLHANow);
+ nEvtLHA.push_back(1);
+ for (int i = int(codeLHA.size()) - 1; i > 0; --i) {
+ if (codeLHA[i] < codeLHA[i - 1]) {
+ swap(codeLHA[i], codeLHA[i - 1]);
+ swap(nEvtLHA[i], nEvtLHA[i - 1]);
+ }
+ else break;
+ }
+ }
+ }
+
+ // Normally only one hard interaction. Then store info and done.
+ if (!doSecondHard) {
+ double deltaSum = sqrtpos(delta2Sum);
+ infoPtr->setSigma( nTrySum, nSelSum, nAccSum, sigmaSum, deltaSum);
+ return;
+ }
+
+ // Increase counter for a second hard interaction.
+ container2Ptrs[i2Container]->accumulate();
+
+ // Update statistics on average impact factor.
+ ++nImpact;
+ sumImpactFac += infoPtr->enhanceMI();
+ sum2ImpactFac += pow2(infoPtr->enhanceMI());
+
+ // Cross section estimate for second hard process.
+ double sigma2Sum = 0.;
+ double sig2SelSum = 0.;
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ if (container2Ptrs[i2]->sigmaMax() != 0.) {
+ nTrySum += container2Ptrs[i2]->nTried();
+ sigma2Sum += container2Ptrs[i2]->sigmaMC();
+ sig2SelSum += container2Ptrs[i2]->sigmaSelMC();
+ }
+
+ // Average impact-parameter factor and error.
+ double invN = 1. / max(1, nImpact);
+ double impactFac = max( 1., sumImpactFac * invN);
+ double impactErr2 = ( sum2ImpactFac * invN / pow2(impactFac) - 1.) * invN;
+
+ // Cross section estimate for combination of first and second process.
+ // Combine two possible ways and take average.
+ double sigmaComb = 0.5 * (sigmaSum * sig2SelSum + sigSelSum * sigma2Sum);
+ sigmaComb *= impactFac / sigmaND;
+ if (allHardSame) sigmaComb *= 0.5;
+ double deltaComb = sqrtpos(2. / nAccSum + impactErr2) * sigmaComb;
+
+ // Store info and done.
+ infoPtr->setSigma( nTrySum, nSelSum, nAccSum, sigmaComb, deltaComb);
+
+}
+
+//*********
+
+// Print statistics on cross sections and number of events.
+
+void ProcessLevel::statistics(bool reset, ostream& os) {
+
+ // Special processing if two hard interactions selected.
+ if (doSecondHard) {
+ statistics2(reset, os);
+ return;
+ }
+
+ // Header.
+ os << "\n *------- PYTHIA Event and Cross Section Statistics ------"
+ << "-------------------------------------------------------*\n"
+ << " | "
+ << " |\n"
+ << " | Subprocess Code | "
+ << " Number of events | sigma +- delta |\n"
+ << " | | "
+ << "Tried Selected Accepted | (estimated) (mb) |\n"
+ << " | | "
+ << " | |\n"
+ << " |------------------------------------------------------------"
+ << "-----------------------------------------------------|\n"
+ << " | | "
+ << " | |\n";
+
+ // Reset sum counters.
+ long nTrySum = 0;
+ long nSelSum = 0;
+ long nAccSum = 0;
+ double sigmaSum = 0.;
+ double delta2Sum = 0.;
+
+ // Loop over existing processes.
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ if (containerPtrs[i]->sigmaMax() != 0.) {
+
+ // Read info for process. Sum counters.
+ long nTry = containerPtrs[i]->nTried();
+ long nSel = containerPtrs[i]->nSelected();
+ long nAcc = containerPtrs[i]->nAccepted();
+ double sigma = containerPtrs[i]->sigmaMC();
+ double delta = containerPtrs[i]->deltaMC();
+ nTrySum += nTry;
+ nSelSum += nSel;
+ nAccSum += nAcc;
+ sigmaSum += sigma;
+ delta2Sum += pow2(delta);
+
+ // Print individual process info.
+ os << " | " << left << setw(45) << containerPtrs[i]->name()
+ << right << setw(5) << containerPtrs[i]->code() << " | "
+ << setw(11) << nTry << " " << setw(10) << nSel << " "
+ << setw(10) << nAcc << " | " << scientific << setprecision(3)
+ << setw(11) << sigma << setw(11) << delta << " |\n";
+
+ // Print subdivision by user code for Les Houches process.
+ if (containerPtrs[i]->code() == 9999)
+ for (int j = 0; j < int(codeLHA.size()); ++j)
+ os << " | ... whereof user classification code " << setw(10)
+ << codeLHA[j] << " | " << setw(10)
+ << nEvtLHA[j] << " | | \n";
+ }
+
+ // Print summed process info.
+ os << " | | "
+ << " | |\n"
+ << " | " << left << setw(50) << "sum" << right << " | " << setw(11)
+ << nTrySum << " " << setw(10) << nSelSum << " " << setw(10)
+ << nAccSum << " | " << scientific << setprecision(3) << setw(11)
+ << sigmaSum << setw(11) << sqrtpos(delta2Sum) << " |\n";
+
+ // Listing finished.
+ os << " | "
+ << " |\n"
+ << " *------- End PYTHIA Event and Cross Section Statistics -----"
+ << "-----------------------------------------------------*" << endl;
+
+ // Optionally reset statistics contants.
+ if (reset) for (int i = 0; i < int(containerPtrs.size()); ++i)
+ containerPtrs[i]->reset();
+
+}
+
+//*********
+
+// Initialize SUSY Les Houches Accord data.
+
+bool ProcessLevel::initSLHA() {
+
+ // Check whether SUSY is on.
+ if ( !Settings::flag("SUSY") ) return true;
+
+ // Read SUSY Les Houches Accord File.
+ string slhaFile = Settings::word("SUSY:SusyLesHouchesFile");
+ int ifail = slhaPtr->readFile(slhaFile);
+
+ // In case of problems, print error and fail init.
+ if (ifail != 0) {
+ infoPtr->errorMsg("Error from Pythia::initSLHA: "
+ "problem reading SLHA file", slhaFile);
+ return false;
+ };
+
+ // Update particle data.
+ int id = slhaPtr->mass.first();
+ for (int i = 1; i <= slhaPtr->mass.size() ; i++) {
+ double mass = abs(slhaPtr->mass(id));
+ ParticleDataTable::m0(id,mass);
+ id = slhaPtr->mass.next();
+ };
+
+ // Check spectrum for consistency. Switch off SUSY if necessary.
+ ifail = slhaPtr->checkSpectrum();
+ if (ifail != 0) {
+ infoPtr->errorMsg("Warning from Pythia::initSLHA: "
+ "Problem with SLHA spectrum.",
+ "\n Only using masses and switching off SUSY.");
+ Settings::flag("SUSY", false);
+ slhaPtr->printSpectrum();
+ return true;
+ };
+
+ // Print spectrum. Done.
+ slhaPtr->printSpectrum();
+ return true;
+
+}
+
+//*********
+
+// Generate the next event with one interaction.
+
+bool ProcessLevel::nextOne( Event& process) {
+
+ // Update CM energy for phase space selection.
+ double eCM = infoPtr->eCM();
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ containerPtrs[i]->newECM(eCM);
+
+ // Loop over tries until trial event succeeds.
+ for ( ; ; ) {
+
+ // Pick one of the subprocesses.
+ double sigmaMaxNow = sigmaMaxSum * Rndm::flat();
+ int iMax = containerPtrs.size() - 1;
+ iContainer = -1;
+ do sigmaMaxNow -= containerPtrs[++iContainer]->sigmaMax();
+ while (sigmaMaxNow > 0. && iContainer < iMax);
+
+ // Do a trial event of this subprocess; accept or not.
+ if (containerPtrs[iContainer]->trialProcess()) break;
+
+ // Check for end-of-file condition for Les Houches events.
+ if (infoPtr->atEndOfFile()) return false;
+ }
+
+ // Update sum of maxima if current maximum violated.
+ if (containerPtrs[iContainer]->newSigmaMax()) {
+ sigmaMaxSum = 0.;
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ sigmaMaxSum += containerPtrs[i]->sigmaMax();
+ }
+
+ // Construct kinematics of acceptable process.
+ if ( !containerPtrs[iContainer]->constructProcess( process) ) return false;
+
+ // Do all resonance decays.
+ if ( doResDecays && !containerPtrs[iContainer]->decayResonances(
+ process) ) return false;
+
+ // Add any junctions to the process event record list.
+ findJunctions( process);
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Generate the next event with two hard interactions.
+
+bool ProcessLevel::nextTwo( Event& process) {
+
+ // Update CM energy for phase space selection.
+ double eCM = infoPtr->eCM();
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ containerPtrs[i]->newECM(eCM);
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ container2Ptrs[i2]->newECM(eCM);
+
+ // Loop over both hard processes to find consistent common kinematics.
+ for ( ; ; ) {
+
+ // Loop internally over tries for hardest process until succeeds.
+ for ( ; ; ) {
+
+ // Pick one of the subprocesses.
+ double sigmaMaxNow = sigmaMaxSum * Rndm::flat();
+ int iMax = containerPtrs.size() - 1;
+ iContainer = -1;
+ do sigmaMaxNow -= containerPtrs[++iContainer]->sigmaMax();
+ while (sigmaMaxNow > 0. && iContainer < iMax);
+
+ // Do a trial event of this subprocess; accept or not.
+ if (containerPtrs[iContainer]->trialProcess()) break;
+
+ // Check for end-of-file condition for Les Houches events.
+ if (infoPtr->atEndOfFile()) return false;
+ }
+
+ // Update sum of maxima if current maximum violated.
+ if (containerPtrs[iContainer]->newSigmaMax()) {
+ sigmaMaxSum = 0.;
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ sigmaMaxSum += containerPtrs[i]->sigmaMax();
+ }
+
+ // Loop internally over tries for second hardest process until succeeds.
+ for ( ; ; ) {
+
+ // Pick one of the subprocesses.
+ double sigma2MaxNow = sigma2MaxSum * Rndm::flat();
+ int i2Max = container2Ptrs.size() - 1;
+ i2Container = -1;
+ do sigma2MaxNow -= container2Ptrs[++i2Container]->sigmaMax();
+ while (sigma2MaxNow > 0. && i2Container < i2Max);
+
+ // Do a trial event of this subprocess; accept or not.
+ if (container2Ptrs[i2Container]->trialProcess()) break;
+ }
+
+ // Update sum of maxima if current maximum violated.
+ if (container2Ptrs[i2Container]->newSigmaMax()) {
+ sigma2MaxSum = 0.;
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ sigma2MaxSum += container2Ptrs[i2]->sigmaMax();
+ }
+
+ // Check whether common set of x values is kinematically possible.
+ double xA1 = containerPtrs[iContainer]->x1();
+ double xB1 = containerPtrs[iContainer]->x2();
+ double xA2 = container2Ptrs[i2Container]->x1();
+ double xB2 = container2Ptrs[i2Container]->x2();
+ if (xA1 + xA2 >= 1. || xB1 + xB2 >= 1.) continue;
+
+ // Reset beam contents. Naive parton densities for second interaction.
+ // (Subsequent procedure could be symmetrized, but would be overkill.)
+ beamAPtr->clear();
+ beamBPtr->clear();
+ int idA1 = containerPtrs[iContainer]->id1();
+ int idB1 = containerPtrs[iContainer]->id2();
+ int idA2 = container2Ptrs[i2Container]->id1();
+ int idB2 = container2Ptrs[i2Container]->id2();
+ double Q2Fac1 = containerPtrs[iContainer]->Q2Fac();
+ double Q2Fac2 = container2Ptrs[i2Container]->Q2Fac();
+ double pdfA2Raw = beamAPtr->xf( idA2, xA2,Q2Fac2);
+ double pdfB2Raw = beamBPtr->xf( idB2, xB2,Q2Fac2);
+
+ // Remove partons in first interaction from beams.
+ beamAPtr->append( 3, idA1, xA1);
+ beamAPtr->xfISR( 0, idA1, xA1, Q2Fac1);
+ beamAPtr->pickValSeaComp();
+ beamBPtr->append( 4, idB1, xB1);
+ beamBPtr->xfISR( 0, idB1, xB1, Q2Fac1);
+ beamBPtr->pickValSeaComp();
+
+ // Reevaluate pdf's for second interaction and weight by reduction.
+ double pdfA2Mod = beamAPtr->xfMI( idA2, xA2,Q2Fac2);
+ double pdfB2Mod = beamBPtr->xfMI( idB2, xB2,Q2Fac2);
+ double wtPdfMod = (pdfA2Mod * pdfB2Mod) / (pdfA2Raw * pdfB2Raw);
+ if (wtPdfMod < Rndm::flat()) continue;
+
+ // Reduce by a factor of 2 for identical processes when others not.
+ if ( someHardSame && containerPtrs[iContainer]->isSame()
+ && container2Ptrs[i2Container]->isSame() && Rndm::flat() > 0.5)
+ continue;
+
+ // If come this far then acceptable event.
+ break;
+ }
+
+ // Construct kinematics of acceptable processes.
+ Event process2;
+ process2.initColTag();
+ startColTag2 = process2.lastColTag();
+ if ( !containerPtrs[iContainer]->constructProcess( process) ) return false;
+ if ( !container2Ptrs[i2Container]->constructProcess( process2, false) )
+ return false;
+
+ // Do all resonance decays.
+ if ( doResDecays && !containerPtrs[iContainer]->decayResonances(
+ process) ) return false;
+ if ( doResDecays && !container2Ptrs[i2Container]->decayResonances(
+ process2) ) return false;
+
+ // Append second hard interaction to normal process object.
+ combineProcessRecords( process, process2);
+
+ // Add any junctions to the process event record list.
+ findJunctions( process);
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Append second hard interaction to normal process object.
+// Complication: all resonance decay chains must be put at the end.
+
+void ProcessLevel::combineProcessRecords( Event& process, Event& process2) {
+
+ // Find first event record size, excluding resonances.
+ int nSize = process.size();
+ int nHard = 5;
+ while (nHard < nSize && process[nHard].mother1() == 3) ++nHard;
+
+ // Save resonance products temporarily elsewhere.
+ vector<Particle> resProd;
+ if (nSize > nHard) {
+ for (int i = nHard; i < nSize; ++i) resProd.push_back( process[i] );
+ process.popBack(nSize - nHard);
+ }
+
+ // Find second event record size, excluding resonances.
+ int nSize2 = process2.size();
+ int nHard2 = 5;
+ while (nHard2 < nSize2 && process2[nHard2].mother1() == 3) ++nHard2;
+
+ // Find amount of necessary position and colour offset for second process.
+ int addPos = nHard - 3;
+ int addCol = process.lastColTag() - startColTag2;
+
+ // Loop over all particles (except beams) from second process.
+ for (int i = 3; i < nSize2; ++i) {
+
+ // Offset mother and daughter pointers and colour tags of particle.
+ process2[i].offsetHistory( 2, addPos, 2, addPos);
+ process2[i].offsetCol( addCol);
+
+ // Append hard-process particles from process2 to process.
+ if (i < nHard2) process.append( process2[i] );
+ }
+
+ // Reinsert resonance decay chains of first hard process.
+ int addPos2 = nHard2 - 3;
+ if (nHard < nSize) {
+
+ // Offset daughter pointers of unmoved mothers.
+ for (int i = 5; i < nHard; ++i)
+ process[i].offsetHistory( 0, 0, nHard - 1, addPos2);
+
+ // Modify history of resonance products when restoring.
+ for (int i = 0; i < int(resProd.size()); ++i) {
+ resProd[i].offsetHistory( nHard - 1, addPos2, nHard - 1, addPos2);
+ process.append( resProd[i] );
+ }
+ }
+
+ // Insert resonance decay chains of second hard process.
+ if (nHard2 < nSize2) {
+ int nHard3 = nHard + nHard2 - 3;
+ int addPos3 = nSize - nHard;
+
+ // Offset daughter pointers of second-process mothers.
+ for (int i = nHard + 2; i < nHard3; ++i)
+ process[i].offsetHistory( 0, 0, nHard3 - 1, addPos3);
+
+ // Modify history of second-process resonance products and insert.
+ for (int i = nHard2; i < nSize2; ++i) {
+ process2[i].offsetHistory( nHard3 - 1, addPos3, nHard3 - 1, addPos3);
+ process.append( process2[i] );
+ }
+ }
+
+ // Store PDF scale for second interaction.
+ process.scaleSecond( process2.scale() );
+
+}
+
+//*********
+
+// Add any junctions to the process event record list.
+// First try, so still incomplete. ??
+// Also check that do not doublebook if called repeatedly.
+
+void ProcessLevel::findJunctions( Event& junEvent) {
+
+ // Loop though event; isolate all uncoloured particles.
+ for (int i = 0; i < junEvent.size(); ++i)
+ if ( junEvent[i].col() == 0 && junEvent[i].acol() == 0) {
+
+ // Find all daughters and store daughter colours and anticolours.
+ vector<int> daughters = junEvent.daughterList(i);
+ vector<int> cols, acols;
+ for (int j = 0; j < int(daughters.size()); ++j) {
+ int colDau = junEvent[ daughters[j] ].col();
+ int acolDau = junEvent[ daughters[j] ].acol();
+ if (colDau > 0) cols.push_back( colDau);
+ if (acolDau > 0) acols.push_back( acolDau);
+ }
+
+ // Remove all matching colour-anticolour pairs.
+ bool foundPair = true;
+ while (foundPair && cols.size() > 0 && acols.size() > 0) {
+ foundPair = false;
+ for (int j = 0; j < int(cols.size()); ++j) {
+ for (int k = 0; k < int(acols.size()); ++k) {
+ if (acols[k] == cols[j]) {
+ cols[j] = cols.back();
+ cols.pop_back();
+ acols[k] = acols.back();
+ acols.pop_back();
+ foundPair = true;
+ break;
+ }
+ } if (foundPair) break;
+ }
+ }
+
+ // Store an (anti)junction when three (anti)coloured daughters.
+ if (cols.size() == 3 && acols.size() == 0)
+ junEvent.appendJunction( 1, cols[0], cols[1], cols[2]);
+ if (acols.size() == 3 && cols.size() == 0)
+ junEvent.appendJunction( 2, acols[0], acols[1], acols[2]);
+ }
+
+ // Done.
+}
+
+//*********
+
+// Check that colours match up.
+
+bool ProcessLevel::checkColours( Event& process) {
+
+ // Variables and arrays for common usage.
+ bool physical = true;
+ bool match;
+ int colType, col, acol, iPos, iNow, iNowA;
+ vector<int> colTags, colPos, acolPos;
+
+ // Check that each particle has the kind of colours expected of it.
+ for (int i = 0; i < process.size(); ++i) {
+ colType = process[i].colType();
+ col = process[i].col();
+ acol = process[i].acol();
+ if (colType == 0 && (col != 0 || acol != 0)) physical = false;
+ else if (colType == 1 && (col <= 0 || acol != 0)) physical = false;
+ else if (colType == -1 && (col != 0 || acol <= 0)) physical = false;
+ else if (colType == 2 && (col <= 0 || acol <= 0)) physical = false;
+ else if (colType < -1 || colType > 2) physical = false;
+
+ // Add to the list of colour tags.
+ if (col > 0) {
+ match = false;
+ for (int ic = 0; ic < int(colTags.size()) ; ++ic)
+ if (col == colTags[ic]) match = true;
+ if (!match) colTags.push_back(col);
+ } else if (acol > 0) {
+ match = false;
+ for (int ic = 0; ic < int(colTags.size()) ; ++ic)
+ if (acol == colTags[ic]) match = true;
+ if (!match) colTags.push_back(acol);
+ }
+ }
+
+ // Warn and give up if particles did not have the expected colours.
+ if (!physical) {
+ infoPtr->errorMsg("Error in ProcessLevel::checkColours: "
+ "incorrect colour assignment");
+ return false;
+ }
+
+ // Loop through all colour tags and find their positions (by sign).
+ for (int ic = 0; ic < int(colTags.size()); ++ic) {
+ col = colTags[ic];
+ colPos.resize(0);
+ acolPos.resize(0);
+ for (int i = 0; i < process.size(); ++i) {
+ if (process[i].col() == col) colPos.push_back(i);
+ if (process[i].acol() == col) acolPos.push_back(i);
+ }
+
+ // Trace colours back through decays; remove daughters.
+ while (colPos.size() > 1) {
+ iPos = colPos.size() - 1;
+ iNow = colPos[iPos];
+ if ( process[iNow].mother1() == colPos[iPos - 1]
+ && process[iNow].mother2() == 0) colPos.pop_back();
+ else break;
+ }
+ while (acolPos.size() > 1) {
+ iPos = acolPos.size() - 1;
+ iNow = acolPos[iPos];
+ if ( process[iNow].mother1() == acolPos[iPos - 1]
+ && process[iNow].mother2() == 0) acolPos.pop_back();
+ else break;
+ }
+
+ // Now colour should exist in only 2 copies.
+ if (colPos.size() + acolPos.size() != 2) physical = false;
+
+ // If both colours or both anticolours then one mother of the other.
+ else if (colPos.size() == 2) {
+ iNow = colPos[1];
+ if ( process[iNow].mother1() != colPos[0]
+ && process[iNow].mother2() != colPos[0] ) physical = false;
+ }
+ else if (acolPos.size() == 2) {
+ iNowA = acolPos[1];
+ if ( process[iNowA].mother1() != acolPos[0]
+ && process[iNowA].mother2() != acolPos[0] ) physical = false;
+ }
+
+ // If one of each then should have same mother(s), or point to beams.
+ else {
+ iNow = colPos[0];
+ iNowA = acolPos[0];
+ if ( process[iNow].status() == -21 && process[iNowA].status() == -21 );
+ else if ( (process[iNow].mother1() != process[iNowA].mother1())
+ || (process[iNow].mother2() != process[iNowA].mother2()) )
+ physical = false;
+ }
+
+ }
+
+ // Error message if problem found. Done.
+ if (!physical) infoPtr->errorMsg("Error in ProcessLevel::checkColours: "
+ "unphysical colour flow");
+ return physical;
+
+}
+
+//*********
+
+// Print statistics when two hard processes allowed.
+
+void ProcessLevel::statistics2(bool reset, ostream& os) {
+
+ // Average impact-parameter factor and error.
+ double invN = 1. / max(1, nImpact);
+ double impactFac = max( 1., sumImpactFac * invN);
+ double impactErr2 = ( sum2ImpactFac * invN / pow2(impactFac) - 1.) * invN;
+
+ // Derive scaling factor to be applied to first set of processes.
+ double sigma2SelSum = 0.;
+ int n2SelSum = 0;
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2) {
+ sigma2SelSum += container2Ptrs[i2]->sigmaSelMC();
+ n2SelSum += container2Ptrs[i2]->nSelected();
+ }
+ double factor1 = impactFac * sigma2SelSum / sigmaND;
+ double rel1Err = sqrt(1. / max(1, n2SelSum) + impactErr2);
+ if (allHardSame) factor1 *= 0.5;
+
+ // Derive scaling factor to be applied to second set of processes.
+ double sigma1SelSum = 0.;
+ int n1SelSum = 0;
+ for (int i = 0; i < int(containerPtrs.size()); ++i) {
+ sigma1SelSum += containerPtrs[i]->sigmaSelMC();
+ n1SelSum += containerPtrs[i]->nSelected();
+ }
+ double factor2 = impactFac * sigma1SelSum / sigmaND;
+ if (allHardSame) factor2 *= 0.5;
+ double rel2Err = sqrt(1. / max(1, n1SelSum) + impactErr2);
+
+ // Header.
+ os << "\n *------- PYTHIA Event and Cross Section Statistics ------"
+ << "--------------------------------------------------*\n"
+ << " | "
+ << " |\n"
+ << " | Subprocess Code | "
+ << "Number of events | sigma +- delta |\n"
+ << " | | Tried"
+ << " Selected Accepted | (estimated) (mb) |\n"
+ << " | | "
+ << " | |\n"
+ << " |------------------------------------------------------------"
+ << "------------------------------------------------|\n"
+ << " | | "
+ << " | |\n"
+ << " | First hard process: | "
+ << " | |\n"
+ << " | | "
+ << " | |\n";
+
+ // Reset sum counters.
+ long nTrySum = 0;
+ long nSelSum = 0;
+ long nAccSum = 0;
+ double sigmaSum = 0.;
+ double delta2Sum = 0.;
+
+ // Loop over existing first processes.
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ if (containerPtrs[i]->sigmaMax() != 0.) {
+
+ // Read info for process. Sum counters.
+ long nTry = containerPtrs[i]->nTried();
+ long nSel = containerPtrs[i]->nSelected();
+ long nAcc = containerPtrs[i]->nAccepted();
+ double sigma = containerPtrs[i]->sigmaMC() * factor1;
+ double delta2 = pow2( containerPtrs[i]->deltaMC() * factor1 );
+ nTrySum += nTry;
+ nSelSum += nSel;
+ nAccSum += nAcc;
+ sigmaSum += sigma;
+ delta2Sum += delta2;
+ delta2 += pow2( sigma * rel1Err );
+
+ // Print individual process info.
+ os << " | " << left << setw(40) << containerPtrs[i]->name()
+ << right << setw(5) << containerPtrs[i]->code() << " | "
+ << setw(11) << nTry << " " << setw(10) << nSel << " "
+ << setw(10) << nAcc << " | " << scientific << setprecision(3)
+ << setw(11) << sigma << setw(11) << sqrtpos(delta2) << " |\n";
+ }
+
+ // Print summed info for first processes.
+ delta2Sum += pow2( sigmaSum * rel1Err );
+ os << " | | "
+ << " | |\n"
+ << " | " << left << setw(45) << "sum" << right << " | " << setw(11)
+ << nTrySum << " " << setw(10) << nSelSum << " " << setw(10)
+ << nAccSum << " | " << scientific << setprecision(3) << setw(11)
+ << sigmaSum << setw(11) << sqrtpos(delta2Sum) << " |\n";
+
+
+ // Separation lines to second hard processes.
+ os << " | | "
+ << " | |\n"
+ << " |------------------------------------------------------------"
+ << "------------------------------------------------|\n"
+ << " | | "
+ << " | |\n"
+ << " | Second hard process: | "
+ << " | |\n"
+ << " | | "
+ << " | |\n";
+
+ // Reset sum counters.
+ nTrySum = 0;
+ nSelSum = 0;
+ nAccSum = 0;
+ sigmaSum = 0.;
+ delta2Sum = 0.;
+
+ // Loop over existing second processes.
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ if (container2Ptrs[i2]->sigmaMax() != 0.) {
+
+ // Read info for process. Sum counters.
+ long nTry = container2Ptrs[i2]->nTried();
+ long nSel = container2Ptrs[i2]->nSelected();
+ long nAcc = container2Ptrs[i2]->nAccepted();
+ double sigma = container2Ptrs[i2]->sigmaMC() * factor2;
+ double delta2 = pow2( container2Ptrs[i2]->deltaMC() * factor2 );
+ nTrySum += nTry;
+ nSelSum += nSel;
+ nAccSum += nAcc;
+ sigmaSum += sigma;
+ delta2Sum += delta2;
+ delta2 += pow2( sigma * rel2Err );
+
+ // Print individual process info.
+ os << " | " << left << setw(40) << container2Ptrs[i2]->name()
+ << right << setw(5) << container2Ptrs[i2]->code() << " | "
+ << setw(11) << nTry << " " << setw(10) << nSel << " "
+ << setw(10) << nAcc << " | " << scientific << setprecision(3)
+ << setw(11) << sigma << setw(11) << sqrtpos(delta2) << " |\n";
+ }
+
+ // Print summed info for second processes.
+ delta2Sum += pow2( sigmaSum * rel2Err );
+ os << " | | "
+ << " | |\n"
+ << " | " << left << setw(45) << "sum" << right << " | " << setw(11)
+ << nTrySum << " " << setw(10) << nSelSum << " " << setw(10)
+ << nAccSum << " | " << scientific << setprecision(3) << setw(11)
+ << sigmaSum << setw(11) << sqrtpos(delta2Sum) << " |\n";
+
+ // Print information on how the two processes were combined.
+ os << " | | "
+ << " | |\n"
+ << " |------------------------------------------------------------"
+ << "------------------------------------------------|\n"
+ << " | "
+ << " |\n"
+ << " | Uncombined cross sections for the two event sets were "
+ << setw(10) << sigma1SelSum << " and " << sigma2SelSum << " mb, "
+ << "respectively, combined |\n"
+ << " | using a sigma(nonDiffractive) of " << setw(10) << sigmaND
+ << " mb and an impact-parameter enhancement factor of "
+ << setw(10) << impactFac << ". |\n";
+
+ // Listing finished.
+ os << " | "
+ << " |\n"
+ << " *------- End PYTHIA Event and Cross Section Statistics -----"
+ << "------------------------------------------------*" << endl;
+
+ // Optionally reset statistics contants.
+ if (reset) {
+ for (int i = 0; i < int(containerPtrs.size()); ++i)
+ containerPtrs[i]->reset();
+ for (int i2 = 0; i2 < int(container2Ptrs.size()); ++i2)
+ container2Ptrs[i2]->reset();
+ }
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// Pythia.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the Pythia class.
+
+#include "Pythia.h"
+
+// Access time information.
+#include <ctime>
+
+// Allow string and character manipulation.
+#include <cctype>
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The Pythia class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maximum number of tries to produce parton level from given input.
+const int Pythia::NTRY = 10;
+
+// Negative integer to denote that no subrun has been set.
+const int Pythia::SUBRUNDEFAULT = -999;
+
+//*********
+
+// Constructor.
+
+Pythia::Pythia(string xmlDir) {
+
+ // Initial values for pointers to PDF's.
+ useNewPdfA = false;
+ useNewPdfB = false;
+ useNewPdfHard = false;
+ pdfAPtr = 0;
+ pdfBPtr = 0;
+ pdfHardAPtr = 0;
+ pdfHardBPtr = 0;
+
+ // Initial values for pointers to Les Houches Event objects.
+ doLHA = false;
+ useNewLHA = false;
+ lhaUpPtr = 0;
+
+ // Initial value for pointer to external decay handler.
+ decayHandlePtr = 0;
+
+ // Initial value for pointer to user hooks.
+ userHooksPtr = 0;
+
+ // Initial value for pointer to beam shape.
+ useNewBeamShape = false;
+ beamShapePtr = 0;
+
+ // Initial values for pointers to timelike and spacelike showers.
+ useNewTimes = false;
+ useNewSpace = false;
+ timesDecPtr = 0;
+ timesPtr = 0;
+ spacePtr = 0;
+
+ // Send Info pointer to handle error printout/counting correctly.
+ settings.initPtr( &info);
+ ParticleDataEntry::initPtr( &info);
+ particleData.initPtr( &info);
+
+ // Find path to data files, i.e. xmldoc directory location.
+ // Environment variable takes precedence, else use constructor input.
+ string path = "";
+ const char* PYTHIA8DATA = "PYTHIA8DATA";
+ char* envPath = getenv(PYTHIA8DATA);
+ if (envPath != 0 && *envPath != '\0') {
+ int i = 0;
+ while (*(envPath+i) != '\0') path += *(envPath+(i++));
+ }
+ else path = xmlDir;
+ if (path[ path.length() - 1 ] != '/') path += "/";
+
+ // Read in files with all flags, modes, parms and words.
+ string initFile = path + "Index.xml";
+ isConstructed = settings.init( initFile);
+ if (!isConstructed) {
+ info.errorMsg("Abort from Pythia::Pythia: settings unavailable");
+ return;
+ }
+
+ // Read in files with all particle data.
+ string dataFile = path + "ParticleData.xml";
+ isConstructed = particleData.init( dataFile);
+ if (!isConstructed) {
+ info.errorMsg("Abort from Pythia::Pythia: particle data unavailable");
+ return;
+ }
+
+ // Write the Pythia banner to output.
+ banner();
+
+ // Set headers to distinguish the two event listing kinds.
+ process.init("(hard process)");
+ event.init("(complete event)");
+
+ // Not initialized until at the end of initInternal.
+ isInit = false;
+
+}
+
+//*********
+
+// Destructor.
+
+Pythia::~Pythia() {
+
+ // Delete the PDF's created with new.
+ if (useNewPdfHard && pdfHardAPtr != pdfAPtr) delete pdfHardAPtr;
+ if (useNewPdfHard && pdfHardBPtr != pdfBPtr) delete pdfHardBPtr;
+ if (useNewPdfA) delete pdfAPtr;
+ if (useNewPdfB) delete pdfBPtr;
+
+ // Delete the Les Houches object created with new.
+ if (useNewLHA) delete lhaUpPtr;
+
+ // Delete the BeamShape object created with new.
+ if (useNewBeamShape) delete beamShapePtr;
+
+ // Delete the timelike and spacelike showers created with new.
+ if (useNewTimes) delete timesPtr;
+ if (useNewSpace) delete spacePtr;
+
+}
+
+//*********
+
+// Read in one update for a setting or particle data from a single line.
+
+bool Pythia::readString(string line, bool warn) {
+
+ // Check that constructor worked.
+ if (!isConstructed) return false;
+
+ // If empty line then done.
+ if (line.find_first_not_of(" ") == string::npos) return true;
+
+ // If first character is not a letter/digit, then taken to be a comment.
+ int firstChar = line.find_first_not_of(" ");
+ if (!isalnum(line[firstChar])) return true;
+
+ // Send on particle data to the ParticleData database.
+ if (isdigit(line[firstChar]))
+ return particleData.readString(line, warn);
+
+ // Everything else sent on to Settings.
+ return settings.readString(line, warn);
+
+}
+
+//*********
+
+// Read in updates for settings or particle data from user-defined file.
+
+bool Pythia::readFile(string fileName, bool warn, int subrun) {
+
+ // Check that constructor worked.
+ if (!isConstructed) return false;
+
+ // Open file with updates.
+ const char* cstring = fileName.c_str();
+ ifstream is(cstring);
+ if (!is) {
+ info.errorMsg("Error in Pythia::readFile: did not find file", fileName);
+ return false;
+ }
+
+ // Read in one line at a time.
+ string line;
+ bool accepted = true;
+ int subrunNow = SUBRUNDEFAULT;
+ while ( getline(is, line) ) {
+
+ // Check whether entered new subrun.
+ int subrunLine = readSubrun( line, warn);
+ if (subrunLine >= 0) subrunNow = subrunLine;
+
+ // Process the line if in correct subrun.
+ if ( (subrunNow == subrun || subrunNow == SUBRUNDEFAULT)
+ && !readString( line, warn) ) accepted = false;
+
+ // Reached end of input file.
+ };
+ return accepted;
+}
+
+//*********
+
+// Routine to pass in pointers to PDF's. Usage optional.
+
+bool Pythia::setPDFPtr( PDF* pdfAPtrIn, PDF* pdfBPtrIn, PDF* pdfHardAPtrIn,
+ PDF* pdfHardBPtrIn) {
+
+ // The routine can have no effect if PDF's already assigned.
+ if (pdfAPtr != 0 || pdfBPtr != 0) return false;
+
+ // The two PDF objects cannot be one and the same, or unassigned.
+ if (pdfAPtrIn == pdfBPtrIn || pdfAPtrIn == 0 || pdfBPtrIn == 0) return false;
+
+ // Save pointers.
+ pdfAPtr = pdfAPtrIn;
+ pdfBPtr = pdfBPtrIn;
+
+ // By default same pointers for hard-process PDF's.
+ pdfHardAPtr = pdfAPtrIn;
+ pdfHardBPtr = pdfBPtrIn;
+
+ // Optionally allow separate pointers for hard process.
+ if (pdfHardAPtrIn == 0 || pdfHardBPtrIn == 0) return true;
+ if (pdfHardAPtrIn == pdfHardBPtrIn) return false;
+ pdfHardAPtr = pdfHardAPtrIn;
+ pdfHardBPtr = pdfHardBPtrIn;
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Routine to initialize with CM energy.
+
+bool Pythia::init( int idAin, int idBin, double eCMin) {
+
+ // Read in and set values.
+ idA = idAin;
+ idB = idBin;
+ frameType = 1;
+ eCM = eCMin;
+ doLHA = false;
+
+ // Send on to common initialization.
+ bool status = initInternal();
+ if (!status) info.errorMsg("Abort from Pythia::init: initialization failed");
+ return status;
+
+}
+
+//*********
+
+// Routine to initialize with two collinear beams, energies specified.
+
+bool Pythia::init( int idAin, int idBin, double eAin, double eBin) {
+
+ // Read in and set values.
+ idA = idAin;
+ idB = idBin;
+ frameType = 2;
+ eA = eAin;
+ eB = eBin;
+ doLHA = false;
+
+ // Send on to common initialization.
+ bool status = initInternal();
+ if (!status) info.errorMsg("Abort from Pythia::init: initialization failed");
+ return status;
+
+}
+
+//*********
+
+// Routine to initialize with two beams specified by three-momenta.
+
+bool Pythia::init( int idAin, int idBin, double pxAin, double pyAin,
+ double pzAin, double pxBin, double pyBin, double pzBin) {
+
+ // Read in and set values.
+ idA = idAin;
+ idB = idBin;
+ frameType = 3;
+ pxA = pxAin;
+ pyA = pyAin;
+ pzA = pzAin;
+ pxB = pxBin;
+ pyB = pyBin;
+ pzB = pzBin;
+ doLHA = false;
+
+ // Send on to common initialization.
+ bool status = initInternal();
+ if (!status) info.errorMsg("Abort from Pythia::init: initialization failed");
+ return status;
+
+}
+
+//*********
+
+// Routine to initialize when all info is given in a Les Houches Event File.
+
+bool Pythia::init( string LesHouchesEventFile, bool skipInit) {
+
+ // Destroy any previous LHAup object.
+ if (useNewLHA) delete lhaUpPtr;
+
+ // Create LHAup object. Send in pointer to info.
+ const char* cstring = LesHouchesEventFile.c_str();
+ lhaUpPtr = new LHAupLHEF(cstring);
+ lhaUpPtr->setPtr( &info);
+ doLHA = true;
+ useNewLHA = true;
+
+ // Store or replace LHA pointer in other classes.
+ processLevel.setLHAPtr( lhaUpPtr);
+
+ // If second time around, only with new file, then simplify.
+ if (skipInit) return true;
+
+ // Set LHAinit information (in some external program).
+ if (!lhaUpPtr->setInit()) {
+ info.errorMsg("Abort from Pythia::init: "
+ "Les Houches initialization failed");
+ return false;
+ }
+
+ // Extract beams from values set in an LHAinit object.
+ idA = lhaUpPtr->idBeamA();
+ idB = lhaUpPtr->idBeamB();
+ eA = lhaUpPtr->eBeamA();
+ eB = lhaUpPtr->eBeamB();
+ frameType = 2;
+
+ // Now do normal initialization. List info if there.
+ bool status = initInternal();
+ lhaUpPtr->listInit();
+ if (!status) info.errorMsg("Abort from Pythia::init: initialization failed");
+ return status;
+
+}
+
+//*********
+
+// Routine to initialize with the variable values of the Beams kind.
+
+bool Pythia::init() {
+
+ // Check if to read from Les Houches Event File set, and is so send on.
+ if (mode("Beams:frameType") == 4) {
+ string lhef = word("Beams:LHEF");
+ bool skipInit = flag("Main:LHEFskipInit");
+ return init( lhef, skipInit);
+ }
+
+ // Read in and set values.
+ idA = mode("Beams:idA");
+ idB = mode("Beams:idB");
+ frameType = mode("Beams:frameType");
+ eCM = parm("Beams:eCM");
+ eA = parm("Beams:eA");
+ eB = parm("Beams:eB");
+ pxA = parm("Beams:pxA");
+ pyA = parm("Beams:pyA");
+ pzA = parm("Beams:pzA");
+ pxB = parm("Beams:pxB");
+ pyB = parm("Beams:pyB");
+ pzB = parm("Beams:pzB");
+ doLHA = false;
+
+ // Send on to common initialization.
+ bool status = initInternal();
+ if (!status) info.errorMsg("Abort from Pythia::init: initialization failed");
+ return status;
+
+}
+
+//*********
+
+// Routine to initialize when beam info is given in an LHAup object.
+
+bool Pythia::init( LHAup* lhaUpPtrIn) {
+
+ // Save and set flag for subsequent usage of LHAup object.
+ lhaUpPtr = lhaUpPtrIn;
+ doLHA = true;
+
+ // Store LHA pointer in other classes.
+ processLevel.setLHAPtr( lhaUpPtr);
+
+ // Set LHAinit information (in some external program).
+ if (!lhaUpPtr->setInit()) {
+ info.errorMsg("Abort from Pythia::init: "
+ "Les Houches initialization failed");
+ return false;
+ }
+
+ // Extract beams from values set in an LHAinit object.
+ idA = lhaUpPtr->idBeamA();
+ idB = lhaUpPtr->idBeamB();
+ eA = lhaUpPtr->eBeamA();
+ eB = lhaUpPtr->eBeamB();
+ frameType = 2;
+
+ // Now do normal initialization. List info if there.
+ bool status = initInternal();
+ lhaUpPtr->listInit();
+ if (!status) info.errorMsg("Abort from Pythia::init: initialization failed");
+ return status;
+
+}
+
+//*********
+
+// Main routine to initialize the generation process.
+// (The alternative init forms end up in this one.)
+
+bool Pythia::initInternal() {
+
+ // Check that constructor worked.
+ isInit = false;
+ if (!isConstructed) return false;
+
+ // Reset error counters.
+ nErrEvent = 0;
+ info.errorReset();
+
+ // Initialize data members extracted from database.
+ doProcessLevel = settings.flag("ProcessLevel:all");
+ doPartonLevel = settings.flag("PartonLevel:all") && doProcessLevel;
+ doHadronLevel = settings.flag("HadronLevel:all");
+ doMomentumSpread = settings.flag("Beams:allowMomentumSpread");
+ doVertexSpread = settings.flag("Beams:allowVertexSpread");
+ checkEvent = settings.flag("Check:event");
+ nErrList = settings.mode("Check:nErrList");
+ epTolErr = settings.parm("Check:epTolErr");
+ epTolWarn = settings.parm("Check:epTolWarn");
+
+ // Initialize the random number generator.
+ if ( settings.flag("Random:setSeed") )
+ Rndm::init( settings.mode("Random:seed") );
+
+ // Initialize tunes to e+e- and pp/ppbar data.
+ initTunes();
+
+ // Initialize couplings (needed to initialize resonances).
+ AlphaEM::initStatic();
+ CoupEW::initStatic();
+ VCKM::initStatic();
+
+ // Initialize some aspects of particle data, including resonances.
+ ParticleDataEntry::initStatic();
+ particleData.initBWmass();
+ particleData.initResonances(resonancePtrs);
+
+ // Set up values related to user hooks.
+ hasUserHooks = (userHooksPtr > 0);
+ doVetoProcess = (hasUserHooks)
+ ? userHooksPtr->canVetoProcessLevel() : false;
+ doVetoPartons = (hasUserHooks)
+ ? userHooksPtr->canVetoPartonLevel() : false;
+
+ // Set up values related to beam shape.
+ if (beamShapePtr == 0) {
+ beamShapePtr = new BeamShape();
+ useNewBeamShape = true;
+ }
+ beamShapePtr->init();
+
+ // Set up objects for timelike and spacelike showers.
+ if (timesDecPtr == 0 || timesPtr == 0) {
+ TimeShower* timesNow = new TimeShower();
+ if (timesDecPtr == 0) timesDecPtr = timesNow;
+ if (timesPtr == 0) timesPtr = timesNow;
+ useNewTimes = true;
+ }
+ if (spacePtr == 0) {
+ spacePtr = new SpaceShower();
+ useNewSpace = true;
+ }
+
+ // Initialize showers, especially for simple showers in decays.
+ timesPtr->initPtr( &info);
+ timesDecPtr->initPtr( &info);
+ spacePtr->initPtr( &info);
+ timesDecPtr->init( 0, 0);
+
+ // Check that beams and beam combination can be handled.
+ // Only allow neutrinos as beams when leptons unresolved.
+ bool canHandleBeams = false;
+ int idAabs = abs(idA);
+ int idBabs = abs(idB);
+ if (doProcessLevel) {
+ if (idAabs == 2212 && idBabs == 2212) canHandleBeams = true;
+ else if ( idAabs == idBabs && (idAabs == 11 || idAabs == 13
+ || idAabs == 15) ) canHandleBeams = true;
+ else if ( idAabs > 10 && idAabs < 17 && idA * idB < 0
+ && !settings.flag("PDF:lepton") ) {
+ if (idAabs == idBabs) canHandleBeams = true;
+ int idMax = max(idAabs, idBabs);
+ int idMin = min(idAabs, idBabs);
+ if (idMax - idMin == 1 && idMax%2 == 0) canHandleBeams = true;
+ }
+ if (!canHandleBeams) {
+ info.errorMsg("Error in Pythia::init: "
+ "cannot handle this beam combination");
+ return false;
+ }
+ }
+
+ // Do not set up beam kinematics when no process level.
+ if (!doProcessLevel) frameType = 1;
+ else {
+
+ // Set up beam kinematics.
+ if (!initKinematics()) return false;
+
+ // Set up the PDF's, if not already done.
+ if (pdfAPtr == 0) {
+ pdfAPtr = getPDFPtr(idA);
+ if (!pdfAPtr->isSetup()) return false;
+ pdfHardAPtr = pdfAPtr;
+ useNewPdfA = true;
+ }
+ if (pdfBPtr == 0) {
+ pdfBPtr = getPDFPtr(idB);
+ if (!pdfBPtr->isSetup()) return false;
+ pdfHardBPtr = pdfBPtr;
+ useNewPdfB = true;
+ }
+
+ // Optionally set up separate PDF's for hard process.
+ if (settings.flag("PDF:useHard")) {
+ pdfHardAPtr = getPDFPtr(idA, 2);
+ if (!pdfHardAPtr->isSetup()) return false;
+ pdfHardBPtr = getPDFPtr(idB, 2);
+ if (!pdfHardBPtr->isSetup()) return false;
+ useNewPdfHard = true;
+ }
+
+ // Set up the two beams and the common remnant system.
+ StringFlav* flavSel = hadronLevel.getStringFlavPtr();
+ bool isUnresolvedA = ( ParticleDataTable::isLepton(idA)
+ && !settings.flag("PDF:lepton") );
+ bool isUnresolvedB = ( ParticleDataTable::isLepton(idB)
+ && !settings.flag("PDF:lepton") );
+ beamA.init( idA, pzAcm, eA, mA, &info, pdfAPtr, pdfHardAPtr,
+ isUnresolvedA, flavSel);
+ beamB.init( idB, pzBcm, eB, mB, &info, pdfBPtr, pdfHardBPtr,
+ isUnresolvedB, flavSel);
+ }
+
+ // Send info/pointers to process level for initialization.
+ if ( doProcessLevel && !processLevel.init( &info, &beamA, &beamB,
+ &sigmaTot, doLHA, &slha, userHooksPtr, sigmaPtrs) ) return false;
+
+ // Send info/pointers to parton level for initialization.
+ if ( doPartonLevel && !partonLevel.init( &info, &beamA, &beamB,
+ &sigmaTot, timesDecPtr, timesPtr, spacePtr, userHooksPtr) )
+ return false;
+
+ // Send info/pointers to hadron level for initialization.
+ // Note: forceHadronLevel() can come, so we must always initialize.
+ if ( !hadronLevel.init( &info, timesDecPtr, decayHandlePtr,
+ handledParticles) ) return false;
+
+ // Optionally check particle data table for inconsistencies.
+ if ( settings.flag("Check:particleData") )
+ particleData.checkTable( settings.mode("Check:levelParticleData") );
+
+ // Succeeded.
+ isInit = true;
+ return true;
+}
+
+//*********
+
+// Calculate kinematics at initialization. Store beam four-momenta.
+
+bool Pythia::initKinematics() {
+
+ // Find masses. Initial guess that we are in CM frame.
+ mA = ParticleDataTable::m0(idA);
+ mB = ParticleDataTable::m0(idB);
+ betaZ = 0.;
+ gammaZ = 1.;
+
+ // Collinear beams not in CM frame: find CM energy.
+ if (frameType == 2) {
+ eA = max(eA, mA);
+ eB = max(eB, mB);
+ pzA = sqrt(eA*eA - mA*mA);
+ pzB = -sqrt(eB*eB - mB*mB);
+ pAinit = Vec4( 0., 0., pzA, eA);
+ pBinit = Vec4( 0., 0., pzB, eB);
+ eCM = sqrt( pow2(eA + eB) - pow2(pzA + pzB) );
+
+ // Find boost to rest frame.
+ betaZ = (pzA + pzB) / (eA + eB);
+ gammaZ = (eA + eB) / eCM;
+ if (abs(betaZ) < 1e-10) frameType = 1;
+ }
+
+ // Completely general beam directions: find CM energy.
+ else if (frameType == 3) {
+ eA = sqrt( pxA*pxA + pyA*pyA + pzA*pzA + mA*mA);
+ eB = sqrt( pxB*pxB + pyB*pyB + pzB*pzB + mB*mB);
+ pAinit = Vec4( pxA, pyA, pzA, eA);
+ pBinit = Vec4( pxB, pyB, pzB, eB);
+ eCM = (pAinit + pBinit).mCalc();
+
+ // Find boost+rotation needed to move from/to CM frame.
+ MfromCM.reset();
+ MfromCM.fromCMframe( pAinit, pBinit);
+ MtoCM = MfromCM;
+ MtoCM.invert();
+ }
+
+ // Fail if CM energy below beam masses.
+ if (eCM < mA + mB) return false;
+
+ // Set up CM-frame kinematics with beams along +-z axis.
+ pzAcm = 0.5 * sqrtpos( (eCM + mA + mB) * (eCM - mA - mB)
+ * (eCM - mA + mB) * (eCM + mA - mB) ) / eCM;
+ pzBcm = -pzAcm;
+ eA = sqrt(mA*mA + pzAcm*pzAcm);
+ eB = sqrt(mB*mB + pzBcm*pzBcm);
+
+ // If in CM frame then store beam four-vectors (else already done above).
+ if (frameType != 2 && frameType != 3) {
+ pAinit = Vec4( 0., 0., pzAcm, eA);
+ pBinit = Vec4( 0., 0., pzBcm, eB);
+ }
+
+ // Store main info for access in process generation.
+ info.setBeamA( idA, pzAcm, eA, mA);
+ info.setBeamB( idB, pzBcm, eB, mB);
+ info.setECM( eCM);
+
+ // Must allow for generic boost+rotation when beam momentum spread.
+ if (doMomentumSpread) frameType = 3;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Initialize tunes to e+e- and pp/ppbar data.
+
+void Pythia::initTunes() {
+
+ // Modes to use. Fast return if all is default.
+ int eeTune = settings.mode("Tune:ee");
+ int ppTune = settings.mode("Tune:pp");
+ if (eeTune == 0 && ppTune == 0) return;
+
+ // Marc Montull's tune to particle composition at LEP1.
+ if (eeTune == 101) {
+ settings.parm("StringZ:aLund", 0.76 );
+ settings.parm("StringZ:bLund", 0.58 ); // default
+ settings.parm("StringFlav:probStoUD", 0.22 );
+ settings.parm("StringFlav:probQQtoQ", 0.08 );
+ settings.parm("StringFlav:probSQtoQQ", 0.75 );
+ settings.parm("StringFlav:probQQ1toQQ0", 0.025 );
+ settings.parm("StringFlav:mesonUDvector", 0.5 );
+ settings.parm("StringFlav:mesonSvector", 0.6 );
+ settings.parm("StringFlav:mesonCvector", 1.5 );
+ settings.parm("StringFlav:mesonBvector", 2.5 );
+ settings.parm("StringFlav:etaSup", 0.60 );
+ settings.parm("StringFlav:etaPrimeSup", 0.15 );
+ settings.parm("StringFlav:popcornSpair", 1.0 );
+ settings.parm("StringFlav:popcornSmeson", 1.0 );
+ }
+
+}
+
+//*********
+
+// Main routine to generate the next event, using internal machinery.
+
+bool Pythia::next() {
+
+ // Simpler option when only HadronLevel to be generated.
+ if (!doProcessLevel) {
+
+ // Set correct energy for system.
+ Vec4 pSum = 0.;
+ for (int i = 1; i < event.size(); ++i)
+ if (event[i].isFinal()) pSum += event[i].p();
+ event[0].p( pSum );
+ event[0].m( pSum.mCalc() );
+
+ // Generate hadronization and decays.
+ return forceHadronLevel();
+ }
+
+ // Reset arrays.
+ info.clear();
+ process.clear();
+ event.clear();
+
+ // Can only generate event if initialization worked.
+ if (!isInit) {
+ info.errorMsg("Abort from Pythia::next: "
+ "not properly initialized so cannot generate events");
+ return false;
+ }
+
+ // Pick beam momentum spread and beam vertex.
+ if (doMomentumSpread || doVertexSpread) beamShapePtr->pick();
+
+ // Recalculate kinematics when beam momentum spread.
+ if (doMomentumSpread) nextKinematics();
+
+ // Outer loop over hard processes; only relevant for user-set vetoes.
+ for ( ; ; ) {
+ bool hasVetoed = false;
+
+ // Provide the hard process that starts it off. Only one try.
+ info.clear();
+ process.clear();
+ if ( !processLevel.next( process) ) {
+ info.errorMsg("Abort from Pythia::next: "
+ "processLevel failed; giving up");
+ return false;
+ }
+
+ // Possibility for a user veto of the process-level event.
+ if (doVetoProcess) {
+ hasVetoed = userHooksPtr->doVetoProcessLevel( process);
+ if (hasVetoed) continue;
+ }
+
+ // Possibility to stop the generation at this stage.
+ if (!doPartonLevel) {
+ boostAndVertex( true, true);
+ processLevel.accumulate();
+ return true;
+ }
+
+ // Allow up to ten tries for parton- and hadron-level processing.
+ bool physical = true;
+ bool hasBoosted = false;
+ for (int iTry = 0; iTry < NTRY; ++ iTry) {
+
+ physical = true;
+
+ // Restore process record to CM frame if it was boosted.
+ if (hasBoosted) {
+ boostAndVertex( false, false);
+ hasBoosted = false;
+ }
+
+ // Reset event record and (extracted partons from) beam remnants.
+ event.clear();
+ beamA.clear();
+ beamB.clear();
+
+ // Parton-level evolution: ISR, FSR, MI.
+ if ( !partonLevel.next( process, event) ) {
+ // Skip to next hard process for failure owing to deliberate veto.
+ hasVetoed = partonLevel.hasVetoed();
+ if (hasVetoed) break;
+ // Else make a new try for other failures.
+ info.errorMsg("Error in Pythia::next: "
+ "partonLevel failed; try again");
+ physical = false;
+ continue;
+ }
+
+ // Possibility for a user veto of the parton-level event.
+ if (doVetoPartons) {
+ hasVetoed = userHooksPtr->doVetoPartonLevel( event);
+ if (hasVetoed) break;
+ }
+
+ // Boost to lab frame (before decays, for vertices).
+ boostAndVertex( true, true);
+ if (frameType == 2 || frameType == 3) hasBoosted = true;
+
+ // Possibility to stop the generation at this stage.
+ if (!doHadronLevel) {
+ processLevel.accumulate();
+ partonLevel.accumulate();
+
+ // Optionally check final event for problems.
+ if (checkEvent && !check()) {
+ info.errorMsg("Abort from Pythia::next: "
+ "check of event revealed problems");
+ return false;
+ }
+ return true;
+ }
+
+ // Hadron-level: hadronization, decays.
+ if ( !hadronLevel.next( event) ) {
+ info.errorMsg("Error in Pythia::next: "
+ "hadronLevel failed; try again");
+ physical = false;
+ continue;
+ }
+
+ // Stop parton- and hadron-level looping if you got this far.
+ break;
+ }
+
+ // If event vetoed then to make a new try.
+ if (hasVetoed) continue;
+
+ // If event failed any other way (after ten tries) then give up.
+ if (!physical) {
+ info.errorMsg("Abort from Pythia::next: "
+ "parton+hadronLevel failed; giving up");
+ return false;
+ }
+
+ // Process- and parton-level statistics.
+ processLevel.accumulate();
+ partonLevel.accumulate();
+
+ // End of outer loop over hard processes. Done with normal option.
+ break;
+ }
+
+ // Optionally check final event for problems.
+ if (checkEvent && !check()) {
+ info.errorMsg("Abort from Pythia::next: "
+ "check of event revealed problems");
+ return false;
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Generate only the hadronization/decay stage, using internal machinery.
+// The "event" instance should already contain a parton-level configuration.
+
+bool Pythia::forceHadronLevel() {
+
+ // Can only generate event if initialization worked.
+ if (!isInit) {
+ info.errorMsg("Abort from Pythia::forceHadronLevel: "
+ "not properly initialized so cannot generate events");
+ return false;
+ }
+
+ // Check whether any junctions in system. (Normally done in ProcessLevel.)
+ event.clearJunctions();
+ processLevel.findJunctions( event);
+
+ // Save spare copy of event in case of failure.
+ Event spareEvent = event;
+
+ // Allow up to ten tries for hadron-level processing.
+ bool physical = true;
+ for (int iTry = 0; iTry < NTRY; ++ iTry) {
+ physical = true;
+
+ // Hadron-level: hadronization, decays.
+ if (hadronLevel.next( event)) break;
+
+ // If failure then warn, restore original configuration and try again.
+ info.errorMsg("Error in Pythia::forceHadronLevel: "
+ "hadronLevel failed; try again");
+ physical = false;
+ event = spareEvent;
+ }
+
+ // Done for simpler option.
+ if (!physical) {
+ info.errorMsg("Abort from Pythia::forceHadronLevel: "
+ "hadronLevel failed; giving up");
+ return false;
+ }
+
+ // Optionally check final event for problems.
+ if (checkEvent && !check()) {
+ info.errorMsg("Abort from Pythia::forceHadronLevel: "
+ "check of event revealed problems");
+ return false;
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Recalculate kinematics for each event when beam momentum has a spread.
+
+void Pythia::nextKinematics() {
+
+ // Read out momentum shift to give current beam momenta.
+ pAnow = pAinit + beamShapePtr->deltaPA();
+ pAnow.e( sqrt(pAnow.pAbs2() + mA * mA) );
+ pBnow = pBinit + beamShapePtr->deltaPB();
+ pBnow.e( sqrt(pBnow.pAbs2() + mB * mB) );
+
+ // Construct CM frame kinematics.
+ eCM = (pAnow + pBnow).mCalc();
+ pzAcm = 0.5 * sqrtpos( (eCM + mA + mB) * (eCM - mA - mB)
+ * (eCM - mA + mB) * (eCM + mA - mB) ) / eCM;
+ pzBcm = -pzAcm;
+ eA = sqrt(mA*mA + pzAcm*pzAcm);
+ eB = sqrt(mB*mB + pzBcm*pzBcm);
+
+ // Set relevant info for other classes to use.
+ info.setBeamA( idA, pzAcm, eA, mA);
+ info.setBeamB( idB, pzBcm, eB, mB);
+ info.setECM( eCM);
+ beamA.newPzE( pzAcm, eA);
+ beamB.newPzE( pzBcm, eB);
+
+ // Set boost/rotation matrices from/to CM frame.
+ MfromCM.reset();
+ MfromCM.fromCMframe( pAnow, pBnow);
+ MtoCM = MfromCM;
+ MtoCM.invert();
+
+}
+
+//*********
+
+// Boost from CM frame to lab frame, or inverse. Set production vertex.
+
+void Pythia::boostAndVertex( bool toLab, bool setVertex) {
+
+ // Boost process from CM frame to lab frame.
+ if (toLab) {
+ if (frameType == 2) process.bst(0., 0., betaZ, gammaZ);
+ else if (frameType == 3) process.rotbst(MfromCM);
+
+ // Boost nonempty event from CM frame to lab frame.
+ if (event.size() > 0) {
+ if (frameType == 2) event.bst(0., 0., betaZ, gammaZ);
+ else if (frameType == 3) event.rotbst(MfromCM);
+ }
+
+ // Boost process from lab frame to CM frame.
+ } else {
+ if (frameType == 2) process.bst(0., 0., -betaZ, gammaZ);
+ else if (frameType == 3) process.rotbst(MtoCM);
+
+ // Boost nonempty event from lab frame to CM frame.
+ if (event.size() > 0) {
+ if (frameType == 2) event.bst(0., 0., -betaZ, gammaZ);
+ else if (frameType == 3) event.rotbst(MtoCM);
+ }
+ }
+
+ // Set production vertex; assumes particles are in lab frame and at origin
+ if (setVertex && doVertexSpread) {
+ Vec4 vertex = beamShapePtr->vertex();
+ for (int i = 0; i < process.size(); ++i) process[i].vProd( vertex);
+ for (int i = 0; i < event.size(); ++i) event[i].vProd( vertex);
+ }
+
+}
+
+//*********
+
+// Print statistics on event generation.
+
+void Pythia::statistics(bool all, bool reset) {
+
+ // Statistics on cross section and number of events.
+ if (doProcessLevel) processLevel.statistics(reset);
+
+ // Statistics from other classes, e.g. multiple interactions.
+ if (all) partonLevel.statistics(reset);
+
+ // Summary of which and how many warnings/errors encountered.
+ info.errorStatistics();
+ if (reset) info.errorReset();
+
+}
+
+//*********
+
+// Write the Pythia banner, with symbol and version information.
+
+void Pythia::banner(ostream& os) {
+
+ // Read in version number and last date of change.
+ double versionNumber = Settings::parm("Pythia:versionNumber");
+ int versionDate = Settings::mode("Pythia:versionDate");
+ string month[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ // Get date and time.
+ time_t t = time(0);
+ char dateNow[12];
+ strftime(dateNow,12,"%d %b %Y",localtime(&t));
+ char timeNow[9];
+ strftime(timeNow,9,"%H:%M:%S",localtime(&t));
+
+
+ os << "\n"
+ << " *-------------------------------------------"
+ << "-----------------------------------------* \n"
+ << " | "
+ << " | \n"
+ << " | *----------------------------------------"
+ << "--------------------------------------* | \n"
+ << " | | "
+ << " | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | PPP Y Y TTTTT H H III A "
+ << " Welcome to the Lund Monte Carlo! | | \n"
+ << " | | P P Y Y T H H I A A "
+ << " This is PYTHIA version " << fixed << setprecision(3)
+ << setw(5) << versionNumber << " | | \n"
+ << " | | PPP Y T HHHHH I AAAAA"
+ << " Last date of change: " << setw(2) << versionDate%100
+ << " " << month[ (versionDate/100)%100 - 1 ]
+ << " " << setw(4) << versionDate/10000 << " | | \n"
+ << " | | P Y T H H I A A"
+ << " | | \n"
+ << " | | P Y T H H III A A"
+ << " Now is " << dateNow << " at " << timeNow << " | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | Main author: Torbjorn Sjostrand; CERN"
+ << "/PH, CH-1211 Geneva, Switzerland, | | \n"
+ << " | | and Department of Theoretical Physi"
+ << "cs, Lund University, Lund, Sweden; | | \n"
+ << " | | phone: + 41 - 22 - 767 82 27; e-mai"
+ << "l: torbjorn@thep.lu.se | | \n"
+ << " | | Author: Stephen Mrenna; Computing Div"
+ << "ision, Simulations Group, | | \n"
+ << " | | Fermi National Accelerator Laborato"
+ << "ry, MS 234, Batavia, IL 60510, USA; | | \n"
+ << " | | phone: + 1 - 630 - 840 - 2556; e-ma"
+ << "il: mrenna@fnal.gov | | \n"
+ << " | | Author: Peter Skands; CERN/PH, CH-121"
+ << "1 Geneva, Switzerland, | | \n"
+ << " | | and Theoretical Physics Department,"
+ << " | | \n"
+ << " | | Fermi National Accelerator Laborato"
+ << "ry, MS 106, Batavia, IL 60510, USA; | | \n"
+ << " | | phone: + 41 - 22 - 767 24 59; e-mai"
+ << "l: skands@fnal.gov | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | The main program reference is the 'Br"
+ << "ief Introduction to PYTHIA 8.1', | | \n"
+ << " | | T. Sjostrand, S. Mrenna and P. Skands"
+ << ", arXiv:0710.3820 | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | The main physics reference is the 'PY"
+ << "THIA 6.4 Physics and Manual', | | \n"
+ << " | | T. Sjostrand, S. Mrenna and P. Skands"
+ << ", JHEP05 (2006) 026 [hep-ph/0603175]. | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | An archive of program versions and do"
+ << "cumentation is found on the web: | | \n"
+ << " | | http://www.thep.lu.se/~torbjorn/Pythi"
+ << "a.html | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | This program is released under the GN"
+ << "U General Public Licence version 2. | | \n"
+ << " | | Please respect the MCnet Guidelines f"
+ << "or Event Generator Authors and Users. | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | Disclaimer: this program comes withou"
+ << "t any guarantees. | | \n"
+ << " | | Beware of errors and use common sense"
+ << " when interpreting results. | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | Copyright (C) 2008 Torbjorn Sjostrand"
+ << " | | \n"
+ << " | | "
+ << " | | \n"
+ << " | | "
+ << " | | \n"
+ << " | *----------------------------------------"
+ << "--------------------------------------* | \n"
+ << " | "
+ << " | \n"
+ << " *-------------------------------------------"
+ << "-----------------------------------------* \n" << endl;
+
+}
+
+//*********
+
+// Check for lines in file that mark the beginning of new subrun.
+
+int Pythia::readSubrun(string line, bool warn, ostream& os) {
+
+ // If empty line then done.
+ int subrunLine = SUBRUNDEFAULT;
+ if (line.find_first_not_of(" ") == string::npos) return subrunLine;
+
+ // If first character is not a letter, then done.
+ string lineNow = line;
+ int firstChar = lineNow.find_first_not_of(" ");
+ if (!isalpha(lineNow[firstChar])) return subrunLine;
+
+ // Replace an equal sign by a blank to make parsing simpler.
+ while (lineNow.find("=") != string::npos) {
+ int firstEqual = lineNow.find_first_of("=");
+ lineNow.replace(firstEqual, 1, " ");
+ }
+
+ // Get first word of a line.
+ istringstream splitLine(lineNow);
+ string name;
+ splitLine >> name;
+
+ // Replace two colons by one (:: -> :) to allow for such mistakes.
+ while (name.find("::") != string::npos) {
+ int firstColonColon = name.find_first_of("::");
+ name.replace(firstColonColon, 2, ":");
+ }
+
+ // Convert to lowercase.
+ for (int i = 0; i < int(name.length()); ++i)
+ name[i] = std::tolower(name[i]);
+
+ // If no match then done.
+ if (name != "main:subrun") return subrunLine;
+
+ // Else find new subrun number and return it.
+ splitLine >> subrunLine;
+ if (!splitLine) {
+ if (warn) os << "\n PYTHIA Warning: Main:subrun number not"
+ << " recognized; skip:\n " << line << endl;
+ subrunLine = SUBRUNDEFAULT;
+ }
+ return subrunLine;
+
+}
+
+//*********
+
+// Check that the final event makes sense: no unknown id codes;
+// charge and energy-momentum conserved.
+
+bool Pythia::check(ostream& os) {
+
+ // Reset.
+ bool physical = true;
+ iErrId.resize(0);
+ iErrCol.resize(0);
+ iErrNan.resize(0);
+ Vec4 pSum;
+ double chargeSum = 0.;
+
+ // Incoming beams counted with negative momentum and charge.
+ if (doProcessLevel) {
+ pSum = - (event[1].p() + event[2].p());
+ chargeSum = - (event[1].charge() + event[2].charge());
+
+ // If no ProcessLevel then sum momentum and charge in initial state.
+ } else {
+ pSum = - event[0].p();
+ for (int i = 0; i < process.size(); ++i)
+ if (process[i].isFinal()) chargeSum -= process[i].charge();
+ }
+ double eLab = abs(pSum.e());
+
+ // Loop over particles in the event.
+ for (int i = 0; i < event.size(); ++i) {
+
+ // Look for any unrecognized particle codes.
+ int id = event[i].id();
+ if (id == 0 || !ParticleDataTable::isParticle(id)) {
+ ostringstream errCode;
+ errCode << ", id = " << id;
+ info.errorMsg("Error in Pythia::check: "
+ "unknown particle code", errCode.str());
+ physical = false;
+ iErrId.push_back(i);
+
+ // Check that colour assignments are the expected ones.
+ } else {
+ int colType = event[i].colType();
+ int col = event[i].col();
+ int acol = event[i].acol();
+ if ( (colType == 0 && (col > 0 || acol > 0))
+ || (colType == 1 && (col <= 0 || acol > 0))
+ || (colType == -1 && (col > 0 || acol <= 0))
+ || (colType == 2 && (col <= 0 || acol <= 0)) ) {
+ ostringstream errCode;
+ errCode << ", id = " << id << " cols = " << col << " " << acol;
+ info.errorMsg("Error in Pythia::check: "
+ "incorrect colours", errCode.str());
+ physical = false;
+ iErrCol.push_back(i);
+ }
+ }
+
+ // Look for particles with not-a-number energy/momentum/mass.
+ if (abs(event[i].px()) >= 0. && abs(event[i].py()) >= 0.
+ && abs(event[i].pz()) >= 0. && abs(event[i].e()) >= 0.
+ && abs(event[i].m()) >= 0.) ;
+ else {
+ info.errorMsg("Error in Pythia::check: "
+ "not-a-number energy/momentum/mass");
+ physical = false;
+ iErrNan.push_back(i);
+ }
+
+ // Add final-state four-momentum and charge.
+ if (event[i].isFinal()) {
+ pSum += event[i].p();
+ chargeSum += event[i].charge();
+ }
+
+ // End of particle loop.
+ }
+
+ // Check energy-momentum/charge conservation.
+ double epDev = abs(pSum.e()) + abs(pSum.px()) + abs(pSum.py())
+ + abs(pSum.pz());
+ if (epDev > epTolErr * eLab) {
+ info.errorMsg("Error in Pythia::check: energy-momentum not conserved");
+ physical = false;
+ } else if (epDev > epTolWarn * eLab) {
+ info.errorMsg("Warning in Pythia::check: "
+ "energy-momentum not quite conserved");
+ }
+ if (abs(chargeSum) > 0.1) {
+ info.errorMsg("Error in Pythia::check: charge not conserved");
+ physical = false;
+ }
+
+ // Done for sensible events.
+ if (physical) return true;
+
+ // Print (the first few) flawed events.
+ if (nErrEvent < nErrList) {
+ os << " PYTHIA erroneous event info: \n";
+ if (iErrId.size() > 0) {
+ os << " unknown particle codes in lines ";
+ for (int i = 0; i < int(iErrId.size()); ++i)
+ os << iErrId[i] << " ";
+ os << "\n";
+ }
+ if (iErrCol.size() > 0) {
+ os << " incorrect colour assignments in lines ";
+ for (int i = 0; i < int(iErrCol.size()); ++i)
+ os << iErrCol[i] << " ";
+ os << "\n";
+ }
+ if (iErrNan.size() > 0) {
+ os << " not-a-number energy/momentum/mass in lines ";
+ for (int i = 0; i < int(iErrNan.size()); ++i)
+ os << iErrNan[i] << " ";
+ os << "\n";
+ }
+ if (epDev > epTolErr * eLab) os << scientific << setprecision(3)
+ << " total energy-momentum non-conservation = " << epDev << "\n";
+ if (abs(chargeSum) > 0.1) os << fixed << setprecision(2)
+ << " total charge non-conservation = " << chargeSum << "\n";
+ info.list();
+ event.list();
+ }
+
+ // Update error counter. Done also for flawed event.
+ ++nErrEvent;
+ return false;
+
+}
+
+//*********
+
+// Routine to set up a PDF pointer.
+
+PDF* Pythia::getPDFPtr(int idIn, int sequence) {
+
+ PDF* tempPDFPtr;
+
+ // Proton beam, normal choice.
+ if (abs(idIn) == 2212 && sequence == 1) {
+ int pSet = settings.mode("PDF:pSet");
+ bool useLHAPDF = settings.flag("PDF:useLHAPDF");
+
+ // Use internal sets.
+ if (!useLHAPDF) {
+ if (pSet == 1) tempPDFPtr = new GRV94L(idIn);
+ else tempPDFPtr = new CTEQ5L(idIn);
+ }
+
+ // Use sets from LHAPDF.
+ else {
+ string LHAPDFset = settings.word("PDF:LHAPDFset");
+ int LHAPDFmember = settings.mode("PDF:LHAPDFmember");
+ tempPDFPtr = new LHAPDF(idIn, LHAPDFset, LHAPDFmember, 1, &info);
+
+ // Optionally allow extrapolation beyond x and Q2 limits.
+ tempPDFPtr->setExtrapolate( settings.flag("PDF:extrapolateLHAPDF") );
+ }
+ }
+
+ // Proton beam, special choice for the hard process..
+ else if (abs(idIn) == 2212) {
+ int pSet = settings.mode("PDF:pHardSet");
+ bool useLHAPDF = settings.flag("PDF:useHardLHAPDF");
+
+ // Use internal sets.
+ if (!useLHAPDF) {
+ if (pSet == 1) tempPDFPtr = new GRV94L(idIn);
+ else tempPDFPtr = new CTEQ5L(idIn);
+ }
+
+ // Use sets from LHAPDF.
+ else {
+ string LHAPDFset = settings.word("PDF:hardLHAPDFset");
+ int LHAPDFmember = settings.mode("PDF:hardLHAPDFmember");
+ tempPDFPtr = new LHAPDF(idIn, LHAPDFset, LHAPDFmember, 2, &info);
+
+ // Optionally allow extrapolation beyond x and Q2 limits.
+ tempPDFPtr->setExtrapolate( settings.flag("PDF:extrapolateLHAPDF") );
+ }
+ }
+
+ // Lepton beam; resolved or not.
+ else {
+ if (settings.flag("PDF:lepton") && abs(idIn)%2 == 1)
+ tempPDFPtr = new Lepton(idIn);
+ else tempPDFPtr = new LeptonPoint(idIn);
+ }
+
+ // Done.
+ return tempPDFPtr;
+}
+
+//*********
+
+} // end namespace Pythia8
+
+
--- /dev/null
+// ResonanceDecays.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for
+// the ResonanceDecays class.
+
+#include "ResonanceDecays.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ResonanceDecays class.
+// Do all resonance decays sequentially.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of tries to pick a decay channel.
+const int ResonanceDecays::NTRYCHANNEL = 10;
+
+// Number of tries to pick a set of daughter masses.
+const int ResonanceDecays::NTRYMASSES = 10000;
+
+// Mass above threshold for allowed decays.
+const double ResonanceDecays::MSAFETY = 0.1;
+
+// When constrainted kinematics cut high-mass tail of Breit-Wigner.
+const double ResonanceDecays::WIDTHCUT = 5.;
+
+// Small number (relative to 1) to protect against roundoff errors.
+const double ResonanceDecays::TINY = 1e-10;
+
+// These numbers are hardwired empirical parameters,
+// intended to speed up the M-generator.
+const double ResonanceDecays::WTCORRECTION[11] = { 1., 1., 1.,
+ 2., 5., 15., 60., 250., 1250., 7000., 50000. };
+
+//*********
+
+bool ResonanceDecays::next( Event& process) {
+
+ // Loop over all entries to find resonances that should decay.
+ int iDec = 0;
+ do {
+ Particle& decayer = process[iDec];
+ if (decayer.isFinal() && decayer.canDecay() && decayer.mayDecay()
+ && decayer.isResonance() ) {
+
+ // Fill the decaying particle in slot 0 of arrays.
+ id0 = decayer.id();
+ m0 = decayer.m();
+ idProd.resize(0);
+ mProd.resize(0);
+ idProd.push_back( id0 );
+ mProd.push_back( m0 );
+
+ // Mother flavour - relevant for gamma*/Z0 mixing. (Not always??)
+ int idIn = process[decayer.mother1()].id();
+
+ // Prepare decay selection.
+ decayer.particleData().preparePick(id0, m0, idIn);
+
+ // Pick a decay channel; allow up to ten tries.
+ bool foundChannel = false;
+ for (int iTryChannel = 0; iTryChannel < NTRYCHANNEL; ++iTryChannel) {
+
+ // Pick decay channel. Find multiplicity.
+ DecayChannel& channel = decayer.particleData().pickChannel();
+ mult = channel.multiplicity();
+
+ // Read out flavours.
+ idProd.resize(1);
+ int idNow;
+ for (int i = 1; i <= mult; ++i) {
+ idNow = channel.product(i - 1);
+ if (id0 < 0 && ParticleDataTable::hasAnti(idNow)) idNow = -idNow;
+ idProd.push_back( idNow);
+ }
+
+ // Pick masses. Pick new channel if fail.
+ if (!pickMasses()) continue;
+ foundChannel = true;
+ break;
+ }
+
+ // Failed to find acceptable decays.
+ if (!foundChannel) {
+ infoPtr->errorMsg("Error in ResonanceDecays::next:"
+ " failed to find workable decay channel");
+ return false;
+ }
+
+ // Select colours in decay.
+ if (!pickColours(iDec, process)) return false;
+
+ // Select four-momenta in decay, boosted to lab frame.
+ pProd.resize(0);
+ pProd.push_back( decayer.p() );
+ if (!pickKinematics()) return false;
+
+ // Append decay products to the process event record.
+ int iFirst = process.size();
+ for (int i = 1; i <= mult; ++i) {
+ process.append( idProd[i], 23, iDec, 0, 0, 0, cols[i], acols[i],
+ pProd[i], mProd[i], m0);
+ }
+ int iLast = process.size() - 1;
+
+ // Modify mother status and daughters.
+ decayer.status(-22);
+ decayer.daughters(iFirst, iLast);
+
+ // End of loop over all entries.
+ }
+ } while (++iDec < process.size());
+
+ // Done.
+ return true;
+
+}
+
+// Select masses of decay products.
+
+bool ResonanceDecays::pickMasses() {
+
+ // Arrays with properties of particles. Fill with dummy values for mother.
+ vector<bool> useBW;
+ vector<double> m0BW, mMinBW, mMaxBW, widthBW;
+ double mMother = mProd[0];
+ double m2Mother = mMother * mMother;
+ useBW.push_back( false );
+ m0BW.push_back( mMother );
+ mMinBW.push_back( mMother );
+ mMaxBW.push_back( mMother );
+ widthBW.push_back( 0. );
+
+ // Loop throught products for masses and widths. Set nominal mass.
+ bool useBWNow;
+ double m0Now, mMinNow, mMaxNow, widthNow;
+ for (int i = 1; i <= mult; ++i) {
+ useBWNow = ParticleDataTable::useBreitWigner( idProd[i] );
+ m0Now = ParticleDataTable::m0( idProd[i] );
+ mMinNow = ParticleDataTable::m0Min( idProd[i] );
+ mMaxNow = ParticleDataTable::m0Max( idProd[i] );
+ if (useBWNow && mMaxNow < mMinNow) mMaxNow = mMother;
+ widthNow = ParticleDataTable::mWidth( idProd[i] );
+ useBW.push_back( useBWNow );
+ m0BW.push_back( m0Now );
+ mMinBW.push_back( mMinNow );
+ mMaxBW.push_back( mMaxNow );
+ widthBW.push_back( widthNow );
+ mProd.push_back( m0Now );
+ }
+
+ // Find number of Breit-Wigners and summed (minimal) masses.
+ int nBW = 0;
+ double mSum = 0.;
+ double mSumMin = 0.;
+ for (int i = 1; i <= mult; ++i) {
+ if (useBW[i]) ++nBW;
+ mSum += max( m0BW[i], mMinBW[i]);
+ mSumMin += mMinBW[i];
+ }
+
+ // If sum of minimal masses above mother mass then give up.
+ if (mSumMin + MSAFETY > mMother) return false;
+
+ // If sum of masses below and no Breit-Wigners then done.
+ if (mSum + 0.5 * MSAFETY < mMother && nBW == 0) return true;
+
+ // Else if below then retry Breit-Wigners, with simple treshold.
+ if (mSum + MSAFETY < mMother) {
+ double wtMax = 2. * sqrtpos(1. - mSum*mSum / m2Mother);
+ double wt;
+ for (int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
+ if (iTryMasses == NTRYMASSES) return false;
+ mSum = 0.;
+ for (int i = 1; i <= mult; ++i) {
+ if (useBW[i]) mProd[i] = ParticleDataTable::mass( idProd[i] );
+ mSum += mProd[i];
+ }
+ wt = (mSum + 0.5 * MSAFETY < mMother)
+ ? sqrtpos(1. - mSum*mSum / m2Mother) : 0.;
+ if (wt > Rndm::flat() * wtMax) break;
+ }
+ return true;
+ }
+
+ // From now on some particles will have to be forced off shell.
+
+ // Order Breit-Wigners in decreasing widths. Sum of other masses.
+ vector<int> iBW;
+ double mSum0 = 0.;
+ for (int i = 1; i <= mult; ++i) {
+ if (useBW[i]) iBW.push_back(i);
+ else mSum0 += mProd[i];
+ }
+ for (int i = 1; i < nBW; ++i) {
+ for (int j = i - 1; j >= 0; --j) {
+ if (widthBW[iBW[j+1]] > widthBW[iBW[j]]) swap (iBW[j+1], iBW[j]);
+ else break;
+ }
+ }
+
+ // Do all but broadest two in increasing-width order. Includes only one.
+ if (nBW != 2) {
+ int iMin = (nBW == 1) ? 0 : 2;
+ for (int i = nBW - 1; i >= iMin; --i) {
+ int iBWi = iBW[i];
+
+ // Find allowed mass range of current resonance.
+ double mMax = mMother - mSum0 - MSAFETY;
+ if (nBW != 1) for (int j = 0; j < i; ++j) mMax -= mMinBW[iBW[j]];
+ mMax = min( mMaxBW[iBWi], mMax );
+ double mMin = min( mMinBW[iBWi], mMax - MSAFETY);
+ if (mMin < 0.) return false;
+
+ // Parameters for Breit-Wigner choice, with constrained mass range.
+ double m2Nom = pow2( m0BW[iBWi] );
+ double m2Max = mMax * mMax;
+ double m2Min = mMin * mMin;
+ double mmWid = m0BW[iBWi] * widthBW[iBWi];
+ double atanMin = atan( (m2Min - m2Nom) / mmWid );
+ double atanMax = atan( (m2Max - m2Nom) / mmWid );
+ double atanDif = atanMax - atanMin;
+
+ // Retry mass according to Breit-Wigner, with simple threshold factor.
+ double mr1 = mSum0*mSum0 / m2Mother;
+ double mr2 = m2Min / m2Mother;
+ double wtMax = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+ double m2Now, wt;
+ for (int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
+ if (iTryMasses == NTRYMASSES) return false;
+ m2Now = m2Nom + mmWid * tan(atanMin + Rndm::flat() * atanDif);
+ mr2 = m2Now / m2Mother;
+ wt = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+ if (wt > Rndm::flat() * wtMax) break;
+ }
+
+ // Prepare to iterate for more. Done for one Breit-Wigner.
+ mProd[iBWi] = sqrt(m2Now);
+ mSum0 += mProd[iBWi];
+ }
+ if (nBW == 1) return true;
+ }
+
+ // Left to do two broadest Breit-Wigners correlated, i.e. more realistic.
+ int iBW1 = iBW[0];
+ int iBW2 = iBW[1];
+ int idMother = abs(idProd[0]);
+ int idDau1 = abs(idProd[iBW1]);
+ int idDau2 = abs(idProd[iBW2]);
+
+ // In some cases known phase-space behaviour; else simple beta factor.
+ int psMode = 1 ;
+ if ( (idMother == 25 || idMother == 35) && idDau1 < 19
+ && idDau2 == idDau1 ) psMode = 3;
+ if ( (idMother == 25 || idMother == 35 || idMother == 36)
+ && (idDau1 == 23 || idDau1 == 24) && idDau2 == idDau1 ) psMode = 5;
+
+ // Find allowed mass ranges
+ double mRem = mMother - mSum0 - MSAFETY;
+ double mMax1 = min( mMaxBW[iBW1], mRem - mMinBW[iBW2] );
+ double mMin1 = min( mMinBW[iBW1], mMax1 - MSAFETY);
+ double mMax2 = min( mMaxBW[iBW2], mRem - mMinBW[iBW1] );
+ double mMin2 = min( mMinBW[iBW2], mMax2 - MSAFETY);
+
+ // At least one range must extend below half remaining mass.
+ double mMid = 0.5 * mRem;
+ bool hasMid1 = (mMin1 < 0.5 * mRem);
+ bool hasMid2 = (mMin2 < 0.5 * mRem);
+ if (!hasMid1 && !hasMid2) return false;
+
+ // Parameters for Breit-Wigner choice, with constrained mass range.
+ double m2Nom1 = pow2( m0BW[iBW1] );
+ double m2Max1 = mMax1 * mMax1;
+ double m2Min1 = mMin1 * mMin1;
+ double mmWid1 = m0BW[iBW1] * widthBW[iBW1];
+ double atanMin1 = atan( (m2Min1 - m2Nom1) / mmWid1 );
+ double atanMax1 = atan( (m2Max1 - m2Nom1) / mmWid1 );
+ double atanMid1 = (hasMid1) ? atan( (mMid*mMid - m2Nom1) / mmWid1 ) : 0.;
+ double m2Nom2 = pow2( m0BW[iBW2] );
+ double m2Max2 = mMax1 * mMax2;
+ double m2Min2 = mMin1 * mMin2;
+ double mmWid2 = m0BW[iBW2] * widthBW[iBW2];
+ double atanMin2 = atan( (m2Min2 - m2Nom2) / mmWid2 );
+ double atanMax2 = atan( (m2Max2 - m2Nom2) / mmWid2 );
+ double atanMid2 = (hasMid2) ? atan( (mMid*mMid - m2Nom2) / mmWid2 ) : 0.;
+
+ // Relative weight to pick either below half remaining mass.
+ double probLow1 = (hasMid1) ? 1. : 0.;
+ if (hasMid1 && hasMid2) probLow1 = (atanMid1 - atanMin1)
+ / ( (atanMid1 - atanMin1) + (atanMid2 - atanMin1) );
+
+ // Maximum matrix element times phase space weight.
+ double m2Rem = mRem * mRem;
+ double mr1 = m2Min1 / m2Rem;
+ double mr2 = m2Min2 / m2Rem;
+ double psMax = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+ double wtMax = 1.;
+ if (psMode == 1) wtMax = psMax;
+ else if (psMode == 2) wtMax = psMax * psMax;
+ else if (psMode == 3) wtMax = pow3(psMax);
+ else if (psMode == 5) wtMax = psMax
+ * (pow2(1. - mr1 - mr2) + 8. * mr1 * mr2);
+
+ // Retry mass according to Breit-Wigners, with simple threshold factor.
+ double atanDif1, atanDif2, m2Now1, m2Now2, mNow1, mNow2, ps, wt;
+ for (int iTryMasses = 0; iTryMasses <= NTRYMASSES; ++ iTryMasses) {
+ if (iTryMasses == NTRYMASSES) return false;
+
+ // Pick either below half remaining mass.
+ if (Rndm::flat() < probLow1) {
+ atanDif1 = atanMid1 - atanMin1;
+ atanDif2 = atanMax2 - atanMin2;
+ } else {
+ atanDif1 = atanMax1 - atanMin1;
+ atanDif2 = atanMid2 - atanMin2;
+ }
+ m2Now1 = m2Nom1 + mmWid1 * tan(atanMin1 + Rndm::flat() * atanDif1);
+ m2Now2 = m2Nom2 + mmWid2 * tan(atanMin2 + Rndm::flat() * atanDif2);
+ mNow1 = sqrt(m2Now1);
+ mNow2 = sqrt(m2Now2);
+
+ // Threshold weight.
+ mr1 = m2Now1 / m2Rem;
+ mr2 = m2Now2 / m2Rem;
+ wt = 0.;
+ if (mNow1 + mNow2 + MSAFETY < mMother) {
+ ps = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+ wt = 1.;
+ if (psMode == 1) wt = ps;
+ else if (psMode == 2) wt = ps * ps;
+ else if (psMode == 3) wt = pow3(ps);
+ else if (psMode == 5) wt = ps
+ * (pow2(1. - mr1 - mr2) + 8. * mr1 * mr2);
+ }
+ if (wt > Rndm::flat() * wtMax) break;
+ }
+ mProd[iBW1] = mNow1;
+ mProd[iBW2] = mNow2;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Select colours of decay products.
+
+bool ResonanceDecays::pickColours(int iDec, Event& process) {
+
+ // Reset or create arrays with colour info.
+ cols.resize(0);
+ acols.resize(0);
+ vector<int> iTriplet, iAtriplet, iOctet, iDipCol, iDipAcol;
+
+ // Mother colours already known.
+ int col0 = process[iDec].col();
+ int acol0 = process[iDec].acol();
+ cols.push_back( col0);
+ acols.push_back(acol0);
+
+ // Loop through all daughters.
+ int colTypeNow;
+ for (int i = 1; i <= mult; ++i) {
+ // Daughter colours initially empty, so that all is set for singlet.
+ cols.push_back(0);
+ acols.push_back(0);
+ // Find character (singlet, triplet, antitriplet, octet) of daughters.
+ colTypeNow = ParticleDataTable::colType( idProd[i] );
+ if (colTypeNow == 0);
+ else if (colTypeNow == 1) iTriplet.push_back(i);
+ else if (colTypeNow == -1) iAtriplet.push_back(i);
+ else if (colTypeNow == 2) iOctet.push_back(i);
+ else {
+ infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
+ " unknown colour type encountered");
+ return false;
+ }
+ }
+
+ // Check excess of colours and anticolours in final over initial state.
+ int nCol = iTriplet.size();
+ if (col0 != 0) --nCol;
+ int nAcol = iAtriplet.size();
+ if (acol0 != 0) --nAcol;
+
+ // If net creation of three colours then find junction kind:
+ // mother is 1 = singlet, 3 = antitriplet, 5 = octet.
+ if (nCol - nAcol == 3) {
+ int kindJun = (col0 == 0) ? ((acol0 == 0) ? 1 : 3) : 5;
+
+ // Set colours in three junction legs and store junction.
+ int colJun[3];
+ colJun[0] = (kindJun == 1) ? process.nextColTag() : acol0;
+ colJun[1] = process.nextColTag();
+ colJun[2] = process.nextColTag();
+ process.appendJunction( kindJun, colJun[0], colJun[1], colJun[2]);
+
+ // Loop over three legs. Remove an incoming anticolour on first leg.
+ for (int leg = 0; leg < 3; ++leg) {
+ if (leg == 0 && kindJun != 1) acol0 = 0;
+
+ // Pick final-state triplets to carry these new colours.
+ else {
+ int pickT = (iTriplet.size() == 1) ? 0
+ : int( TINY + Rndm::flat() * (iTriplet.size() - TINY) );
+ int iPickT = iTriplet[pickT];
+ cols[iPickT] = colJun[leg];
+
+ // Remove matched triplet and store new colour dipole ends.
+ iTriplet[pickT] = iTriplet.back();
+ iTriplet.pop_back();
+ iDipCol.push_back(iPickT);
+ iDipAcol.push_back(0);
+ }
+ }
+
+ // Update colour counter. Done with junction.
+ nCol -= 3;
+ }
+
+ // If net creation of three anticolours then find antijunction kind:
+ // mother is 2 = singlet, 4 = triplet, 6 = octet.
+ if (nAcol - nCol == 3) {
+ int kindJun = (acol0 == 0) ? ((col0 == 0) ? 2 : 4) : 6;
+
+ // Set anticolours in three antijunction legs and store antijunction.
+ int acolJun[3];
+ acolJun[0] = (kindJun == 2) ? process.nextColTag() : col0;
+ acolJun[1] = process.nextColTag();
+ acolJun[2] = process.nextColTag();
+ process.appendJunction( kindJun, acolJun[0], acolJun[1], acolJun[2]);
+
+ // Loop over three legs. Remove an incoming colour on first leg.
+ for (int leg = 0; leg < 3; ++leg) {
+ if (leg == 0 && kindJun != 2) col0 = 0;
+
+ // Pick final-state antitriplets to carry these new anticolours.
+ else {
+ int pickA = (iAtriplet.size() == 1) ? 0
+ : int( TINY + Rndm::flat() * (iAtriplet.size() - TINY) );
+ int iPickA = iAtriplet[pickA];
+ acols[iPickA] = acolJun[leg];
+
+ // Remove matched antitriplet and store new colour dipole ends.
+ iAtriplet[pickA] = iAtriplet.back();
+ iAtriplet.pop_back();
+ iDipCol.push_back(0);
+ iDipAcol.push_back(iPickA);
+ }
+ }
+
+ // Update anticolour counter. Done with antijunction.
+ nAcol -= 3;
+ }
+
+ // If colours and anticolours do not match now then unphysical.
+ if (nCol != nAcol) {
+ infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
+ " inconsistent colour tags");
+ return false;
+ }
+
+ // Pick final-state triplet (if any) to carry initial colour.
+ if (col0 != 0 && iTriplet.size() > 0) {
+ int pickT = (iTriplet.size() == 1) ? 0
+ : int( TINY + Rndm::flat() * (iTriplet.size() - TINY) );
+ int iPickT = iTriplet[pickT];
+ cols[iPickT] = col0;
+
+ // Remove matched triplet and store new colour dipole ends.
+ col0 = 0;
+ iTriplet[pickT] = iTriplet.back();
+ iTriplet.pop_back();
+ iDipCol.push_back(iPickT);
+ iDipAcol.push_back(0);
+ }
+
+ // Pick final-state antitriplet (if any) to carry initial anticolour.
+ if (acol0 != 0 && iAtriplet.size() > 0) {
+ int pickA = (iAtriplet.size() == 1) ? 0
+ : int( TINY + Rndm::flat() * (iAtriplet.size() - TINY) );
+ int iPickA = iAtriplet[pickA];
+ acols[iPickA] = acol0;
+
+ // Remove matched antitriplet and store new colour dipole ends.
+ acol0 = 0;
+ iAtriplet[pickA] = iAtriplet.back();
+ iAtriplet.pop_back();
+ iDipCol.push_back(0);
+ iDipAcol.push_back(iPickA);
+ }
+
+ // Error checks that amount of leftover colours and anticolours match.
+ if ( (iTriplet.size() != iAtriplet.size())
+ || (col0 != 0 && acol0 == 0) || (col0 == 0 && acol0 != 0) ) {
+ infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
+ " inconsistent colour tags");
+ return false;
+ }
+
+ // Match triplets to antitriplets in the final state.
+ for (int pickT = 0; pickT < int(iTriplet.size()); ++pickT) {
+ int iPickT = iTriplet[pickT];
+ int pickA = (iAtriplet.size() == 1) ? 0
+ : int( TINY + Rndm::flat() * (iAtriplet.size() - TINY) );
+ int iPickA = iAtriplet[pickA];
+
+ // Connect pair with new colour tag.
+ cols[iPickT] = process.nextColTag();
+ acols[iPickA] = cols[iPickT];
+
+ // Remove matched antitriplet and store new colour dipole ends.
+ iAtriplet[pickT] = iAtriplet.back();
+ iAtriplet.pop_back();
+ iDipCol.push_back(iPickT);
+ iDipAcol.push_back(iPickA);
+ }
+
+ // If no octets are around then matching is done.
+ if (col0 == 0 && acol0 == 0 && iOctet.size() == 0) return true;
+
+ // If initial-state octet remains then store as (first!) new dipole.
+ if (col0 != 0) {
+ iDipCol.push_back(0);
+ iDipAcol.push_back(0);
+ }
+
+ // Now attach all final-state octets at random to existing dipoles.
+ for (int i = 0; i < int(iOctet.size()); ++i) {
+ int iOct = iOctet[i];
+
+ // If no dipole then start new one. (Happens for singlet -> octets.)
+ if (iDipCol.size() == 0) {
+ cols[iOct] = process.nextColTag();
+ acols[iOct] = cols[iOct] ;
+ iDipCol.push_back(iOct);
+ iDipAcol.push_back(iOct);
+ }
+
+ // Else attach to existing dipole picked at random.
+ else {
+ int pickDip = (iDipCol.size() == 1) ? 0
+ : int( TINY + Rndm::flat() * (iDipCol.size() - TINY) );
+
+ // Case with dipole in initial state: reattach existing colours.
+ if (iDipCol[pickDip] == 0 && iDipAcol[pickDip] == 0) {
+ cols[iOct] = col0;
+ acols[iOct] = acol0;
+ iDipAcol[pickDip] = iOct;
+ iDipCol.push_back(iOct);
+ iDipAcol.push_back(0);
+
+ // Case with dipole from colour in initial state: also new colour.
+ } else if (iDipAcol[pickDip] == 0) {
+ int iPickCol = iDipCol[pickDip];
+ cols[iOct] = cols[iPickCol];
+ acols[iOct] = process.nextColTag();
+ cols[iPickCol] = acols[iOct];
+ iDipCol[pickDip] = iOct;
+ iDipCol.push_back(iPickCol);
+ iDipAcol.push_back(iOct);
+
+ // Remaining cases with dipole from anticolour in initial state
+ // or dipole inside final state: also new colour.
+ } else {
+ int iPickAcol = iDipAcol[pickDip];
+ acols[iOct] = acols[iPickAcol];
+ cols[iOct] = process.nextColTag();
+ acols[iPickAcol] = cols[iOct];
+ iDipAcol[pickDip] = iOct;
+ iDipCol.push_back(iOct);
+ iDipAcol.push_back(iPickAcol);
+ }
+ }
+ }
+
+ // Must now have at least two dipoles (no 1 -> 8 or 8 -> 1).
+ if (iDipCol.size() < 2) {
+ infoPtr->errorMsg("Error in ResonanceDecays::pickColours:"
+ " inconsistent colour tags");
+ return false;
+ }
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Select decay products momenta isotropically in phase space.
+// Process-dependent angular distributions may be imposed in SigmaProcess.
+
+bool ResonanceDecays::pickKinematics() {
+
+ // Description of two-body decays as simple special case.
+ if (mult == 2) {
+
+ // Masses.
+ m0 = mProd[0];
+ double m1 = mProd[1];
+ double m2 = mProd[2];
+
+ // Energies and absolute momentum in the rest frame.
+ double e1 = 0.5 * (m0*m0 + m1*m1 - m2*m2) / m0;
+ double e2 = 0.5 * (m0*m0 + m2*m2 - m1*m1) / m0;
+ double pAbs = 0.5 * sqrtpos( (m0 - m1 - m2) * (m0 + m1 + m2)
+ * (m0 + m1 - m2) * (m0 - m1 + m2) ) / m0;
+
+ // Pick isotropic angles to give three-momentum.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi = 2. * M_PI * Rndm::flat();
+ double pX = pAbs * sinTheta * cos(phi);
+ double pY = pAbs * sinTheta * sin(phi);
+ double pZ = pAbs * cosTheta;
+
+ // Fill four-momenta in mother rest frame and then boost to lab frame.
+ pProd.push_back( Vec4( pX, pY, pZ, e1) );
+ pProd.push_back( Vec4( -pX, -pY, -pZ, e2) );
+ pProd[1].bst( pProd[0] );
+ pProd[2].bst( pProd[0] );
+
+ // Done for two-body decay.
+ return true;
+ }
+
+ // Description of three-body decays as semi-simple special case.
+ if (mult == 3) {
+
+ // Masses.
+ m0 = mProd[0];
+ double m1 = mProd[1];
+ double m2 = mProd[2];
+ double m3 = mProd[3];
+ double mDiff = m0 - (m1 + m2 + m3);
+
+ // Kinematical limits for 2+3 mass. Maximum phase-space weight.
+ double m23Min = m2 + m3;
+ double m23Max = m0 - m1;
+ double p1Max = 0.5 * sqrtpos( (m0 - m1 - m23Min) * (m0 + m1 + m23Min)
+ * (m0 + m1 - m23Min) * (m0 - m1 + m23Min) ) / m0;
+ double p23Max = 0.5 * sqrtpos( (m23Max - m2 - m3) * (m23Max + m2 + m3)
+ * (m23Max + m2 - m3) * (m23Max - m2 + m3) ) / m23Max;
+ double wtPSmax = 0.5 * p1Max * p23Max;
+
+ // Pick an intermediate mass m23 flat in the allowed range.
+ double wtPS, m23, p1Abs, p23Abs;
+ do {
+ m23 = m23Min + Rndm::flat() * mDiff;
+
+ // Translate into relative momenta and find phase-space weight.
+ p1Abs = 0.5 * sqrtpos( (m0 - m1 - m23) * (m0 + m1 + m23)
+ * (m0 + m1 - m23) * (m0 - m1 + m23) ) / m0;
+ p23Abs = 0.5 * sqrtpos( (m23 - m2 - m3) * (m23 + m2 + m3)
+ * (m23 + m2 - m3) * (m23 - m2 + m3) ) / m23;
+ wtPS = p1Abs * p23Abs;
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtPS < Rndm::flat() * wtPSmax );
+
+ // Set up m23 -> m2 + m3 isotropic in its rest frame.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi = 2. * M_PI * Rndm::flat();
+ double pX = p23Abs * sinTheta * cos(phi);
+ double pY = p23Abs * sinTheta * sin(phi);
+ double pZ = p23Abs * cosTheta;
+ double e2 = sqrt( m2*m2 + p23Abs*p23Abs);
+ double e3 = sqrt( m3*m3 + p23Abs*p23Abs);
+ Vec4 p2( pX, pY, pZ, e2);
+ Vec4 p3( -pX, -pY, -pZ, e3);
+
+ // Set up 0 -> 1 + 23 isotropic in its rest frame.
+ cosTheta = 2. * Rndm::flat() - 1.;
+ sinTheta = sqrt(1. - cosTheta*cosTheta);
+ phi = 2. * M_PI * Rndm::flat();
+ pX = p1Abs * sinTheta * cos(phi);
+ pY = p1Abs * sinTheta * sin(phi);
+ pZ = p1Abs * cosTheta;
+ double e1 = sqrt( m1*m1 + p1Abs*p1Abs);
+ double e23 = sqrt( m23*m23 + p1Abs*p1Abs);
+ pProd.push_back( Vec4( pX, pY, pZ, e1) );
+
+ // Boost 2 + 3 to the 0 rest frame and then boost to lab frame.
+ Vec4 p23( -pX, -pY, -pZ, e23);
+ p2.bst( p23 );
+ p3.bst( p23 );
+ pProd.push_back( p2 );
+ pProd.push_back( p3 );
+ pProd[1].bst( pProd[0] );
+ pProd[2].bst( pProd[0] );
+ pProd[3].bst( pProd[0] );
+
+ // Done for three-body decay.
+ return true;
+ }
+
+ // Do a multibody decay using the M-generator algorithm.
+
+ // Mother and sum daughter masses.
+ m0 = mProd[0];
+ double mSum = mProd[1];
+ for (int i = 2; i <= mult; ++i) mSum += mProd[i];
+ double mDiff = m0 - mSum;
+
+ // Begin setup of intermediate invariant masses.
+ vector<double> mInv;
+ for (int i = 0; i <= mult; ++i) mInv.push_back( mProd[i]);
+
+ // Calculate the maximum weight in the decay.
+ double wtPSmax = 1. / WTCORRECTION[mult];
+ double mMax = mDiff + mProd[mult];
+ double mMin = 0.;
+ for (int i = mult - 1; i > 0; --i) {
+ mMax += mProd[i];
+ mMin += mProd[i+1];
+ double mNow = mProd[i];
+ wtPSmax *= 0.5 * sqrtpos( (mMax - mMin - mNow) * (mMax + mMin + mNow)
+ * (mMax + mMin - mNow) * (mMax - mMin + mNow) ) / mMax;
+ }
+
+ // Begin loop to find the set of intermediate invariant masses.
+ vector<double> rndmOrd;
+ double wtPS;
+ do {
+ wtPS = 1.;
+
+ // Find and order random numbers in descending order.
+ rndmOrd.resize(0);
+ rndmOrd.push_back(1.);
+ for (int i = 1; i < mult - 1; ++i) {
+ double rndm = Rndm::flat();
+ rndmOrd.push_back(rndm);
+ for (int j = i - 1; j > 0; --j) {
+ if (rndm > rndmOrd[j]) swap( rndmOrd[j], rndmOrd[j+1] );
+ else break;
+ }
+ }
+ rndmOrd.push_back(0.);
+
+ // Translate into intermediate masses and find weight.
+ for (int i = mult - 1; i > 0; --i) {
+ mInv[i] = mInv[i+1] + mProd[i] + (rndmOrd[i-1] - rndmOrd[i]) * mDiff;
+ wtPS *= 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
+ * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
+ * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
+ }
+
+ // If rejected, try again with new invariant masses.
+ } while ( wtPS < Rndm::flat() * wtPSmax );
+
+ // Perform two-particle decays in the respective rest frame.
+ vector<Vec4> pInv;
+ pInv.resize(mult + 1);
+ for (int i = 1; i < mult; ++i) {
+ double pAbs = 0.5 * sqrtpos( (mInv[i] - mInv[i+1] - mProd[i])
+ * (mInv[i] + mInv[i+1] + mProd[i]) * (mInv[i] + mInv[i+1] - mProd[i])
+ * (mInv[i] - mInv[i+1] + mProd[i]) ) / mInv[i];
+
+ // Isotropic angles give three-momentum.
+ double cosTheta = 2. * Rndm::flat() - 1.;
+ double sinTheta = sqrt(1. - cosTheta*cosTheta);
+ double phi = 2. * M_PI * Rndm::flat();
+ double pX = pAbs * sinTheta * cos(phi);
+ double pY = pAbs * sinTheta * sin(phi);
+ double pZ = pAbs * cosTheta;
+
+ // Calculate energies, fill four-momenta.
+ double eHad = sqrt( mProd[i]*mProd[i] + pAbs*pAbs);
+ double eInv = sqrt( mInv[i+1]*mInv[i+1] + pAbs*pAbs);
+ pProd.push_back( Vec4( pX, pY, pZ, eHad) );
+ pInv[i+1].p( -pX, -pY, -pZ, eInv);
+ }
+ pProd.push_back( pInv[mult] );
+
+ // Boost decay products to the mother rest frame and on to lab frame.
+ pInv[1] = pProd[0];
+ for (int iFrame = mult - 1; iFrame > 0; --iFrame)
+ for (int i = iFrame; i <= mult; ++i) pProd[i].bst(pInv[iFrame]);
+
+ // Done for multibody decay.
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// ResonanceWidths.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for
+// the ResonanceWidths class and classes derived from it.
+
+#include "ResonanceWidths.h"
+#include "PythiaComplex.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The ResonanceWidths class.
+// Base class for the various resonances.
+
+//*********
+
+// Definitions of static variables and functions.
+// (Values will be overwritten in initStatic call, so are purely dummy.)
+
+int ResonanceWidths::alphaSorder = 1;
+int ResonanceWidths::alphaEMorder = 1;
+double ResonanceWidths::alphaSvalue = 0.1265;
+double ResonanceWidths::minWidth = 1e-20;
+double ResonanceWidths::minThreshold = 0.1;
+AlphaStrong ResonanceWidths::alphaS;
+AlphaEM ResonanceWidths::alphaEM;
+
+// Static copy of Info - not optimal solution??
+Info* ResonanceWidths::infoPtr = 0;
+
+// Number of points in integration direction for numInt routines.
+const int ResonanceWidths::NPOINT = 100;
+
+// The sum of product masses must not be too close to the resonance mass.
+const double ResonanceWidths::MASSMARGIN = 0.1;
+
+//*********
+
+// Initialize static data members.
+
+void ResonanceWidths::initStatic(Info* infoPtrIn) {
+
+ // Save pointer.
+ infoPtr = infoPtrIn;
+
+ // Parameters of alphaStrong generation .
+ alphaSvalue = Settings::parm("SigmaProcess:alphaSvalue");
+ alphaSorder = Settings::mode("SigmaProcess:alphaSorder");
+
+ // Initialize alphaStrong generation.
+ alphaS.init( alphaSvalue, alphaSorder);
+
+ // Parameters of alphaEM generation.
+ alphaEMorder = Settings::mode("SigmaProcess:alphaEMorder");
+
+ // Initialize alphaEM generation.
+ alphaEM.init( alphaEMorder);
+
+ // Minimal decaying-resonance width. Minimal phase space for meMode = 103.
+ minWidth = Settings::parm("ResonanceWidths:minWidth");
+ minThreshold = Settings::parm("ResonanceWidths:minThreshold");
+
+}
+
+//*********
+
+// Initialize data members.
+// Calculate and store partial and total widths at the nominal mass.
+
+void ResonanceWidths::init() {
+
+ // Initialize constants used for a resonance.
+ initConstants();
+
+ // Calculate various common prefactors for the current mass.
+ mHat = mRes;
+ calcPreFac(true);
+
+ // Reset quantities to sum. Declare variables inside loop.
+ double widTot = 0.;
+ double widPos = 0.;
+ double widNeg = 0.;
+ int idNow, idAnti;
+ double openSecPos, openSecNeg;
+
+ // Loop over all decay channels. Basic properties of channel.
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ iChannel = i;
+ onMode = particlePtr->decay[i].onMode();
+ meMode = particlePtr->decay[i].meMode();
+ mult = particlePtr->decay[i].multiplicity();
+ widNow = 0.;
+
+ // Channels with meMode < 100 must be implemented in derived classes.
+ if (meMode < 100) {
+
+ // Read out information on channel: primarily use first two.
+ id1 = particlePtr->decay[i].product(0);
+ id2 = particlePtr->decay[i].product(1);
+ id1Abs = abs(id1);
+ id2Abs = abs(id2);
+
+ // Order first two in descending order of absolute values.
+ if (id2Abs > id1Abs) {swap( id1, id2); swap( id1Abs, id2Abs);}
+
+ // Allow for third product to be treated in derived classes.
+ if (mult > 2) {
+ id3 = particlePtr->decay[i].product(2);
+ id3Abs = abs(id3);
+
+ // Also order third into descending order of absolute values.
+ if (id3Abs > id2Abs) {swap( id2, id3); swap( id2Abs, id3Abs);}
+ if (id2Abs > id1Abs) {swap( id1, id2); swap( id1Abs, id2Abs);}
+ }
+
+ // Read out masses. Calculate two-body phase space.
+ mf1 = ParticleDataTable::m0(id1Abs);
+ mf2 = ParticleDataTable::m0(id2Abs);
+ mr1 = pow2(mf1 / mHat);
+ mr2 = pow2(mf2 / mHat);
+ ps = (mHat < mf1 + mf2 + MASSMARGIN) ? 0.
+ : sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+ if (mult > 2) {
+ mf3 = ParticleDataTable::m0(id3Abs);
+ mr3 = pow2(mf3 / mHat);
+ }
+
+ // Let derived class calculate width for channel provided.
+ calcWidth(true);
+ }
+
+ // Channels with meMode >= 100 are caculated based on stored values.
+ else widNow = GammaRes * particlePtr->decay[i].bRatio();
+
+ // Find secondary open fractions of partial width.
+ openSecPos = 1.;
+ openSecNeg = 1.;
+ for (int j = 0; j < mult; ++j) {
+ idNow = particlePtr->decay[i].product(j);
+ idAnti = (ParticleDataTable::hasAnti(idNow)) ? -idNow : idNow;
+ openSecPos *= ParticleDataTable::resOpenFrac(idNow);
+ openSecNeg *= ParticleDataTable::resOpenFrac(idAnti);
+ }
+
+ // Store partial widths and secondary open fractions.
+ particlePtr->decay[i].onShellWidth(widNow);
+ particlePtr->decay[i].openSec( idRes, openSecPos);
+ particlePtr->decay[i].openSec(-idRes, openSecNeg);
+
+ // Update sum over all channnels and over open channels only.
+ widTot += widNow;
+ if (onMode == 1 || onMode == 2) widPos += widNow * openSecPos;
+ if (onMode == 1 || onMode == 3) widNeg += widNow * openSecNeg;
+ }
+
+ // If no decay channels are open then set particle stable and done.
+ if (widTot < minWidth) {
+ particlePtr->setMayDecay(false, false);
+ particlePtr->setMWidth(0., false);
+ for (int i = 0; i < particlePtr->decay.size(); ++i)
+ particlePtr->decay[i].bRatio( 0., false);
+ return;
+ }
+
+ // Normalize branching ratios to unity.
+ double bRatio;
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ bRatio = particlePtr->decay[i].onShellWidth() / widTot;
+ particlePtr->decay[i].bRatio( bRatio, false);
+ }
+
+ // Optionally force total width by rescaling of all partial ones.
+ if (doForceWidth) {
+ forceFactor = GammaRes / widTot;
+ for (int i = 0; i < particlePtr->decay.size(); ++i)
+ particlePtr->decay[i].onShellWidthFactor( forceFactor);
+ }
+
+ // Else update newly calculated partial width.
+ else {
+ particlePtr->setMWidth(widTot, false);
+ GammaRes = widTot;
+ }
+
+ // Updated width-to-mass ratio. Secondary widths for open.
+ GamMRat = GammaRes / mRes;
+ openPos = widPos / widTot;
+ openNeg = widNeg / widTot;
+
+}
+
+//*********
+
+// Calculate the total width and store phase-space-weighted coupling sums.
+
+double ResonanceWidths::width(int idSgn, double mHatIn, int idInFlavIn,
+ bool openOnly, bool setBR, int idOutFlav1, int idOutFlav2) {
+
+ // Calculate various prefactors for the current mass.
+ mHat = mHatIn;
+ idInFlav = idInFlavIn;
+ calcPreFac(false);
+
+ // Reset quantities to sum. Declare variables inside loop.
+ double widSum = 0.;
+ double mfSum, psOnShell;
+
+ // Loop over all decay channels. Basic properties of channel.
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ iChannel = i;
+ onMode = particlePtr->decay[i].onMode();
+ meMode = particlePtr->decay[i].meMode();
+ mult = particlePtr->decay[i].multiplicity();
+
+ // Initially assume vanishing branching ratio.
+ widNow = 0.;
+ if (setBR) particlePtr->decay[i].currentBR(widNow);
+
+ // Optionally only consider specific (two-body) decay channel.
+ // Currently only used for Higgs -> q qbar, g g or gamma gamma.
+ if (idOutFlav1 > 0 || idOutFlav2 > 0) {
+ if (mult > 2) continue;
+ if (particlePtr->decay[i].product(0) != idOutFlav1) continue;
+ if (particlePtr->decay[i].product(1) != idOutFlav2) continue;
+ }
+
+ // Optionally only consider open channels.
+ if (openOnly) {
+ if (idSgn > 0 && onMode !=1 && onMode != 2) continue;
+ if (idSgn < 0 && onMode !=1 && onMode != 3) continue;
+ }
+
+ // Channels with meMode < 100 must be implemented in derived classes.
+ if (meMode < 100) {
+
+ // Read out information on channel: primarily use first two.
+ id1 = particlePtr->decay[i].product(0);
+ id2 = particlePtr->decay[i].product(1);
+ id1Abs = abs(id1);
+ id2Abs = abs(id2);
+
+ // Order first two in descending order of absolute values.
+ if (id2Abs > id1Abs) {swap( id1, id2); swap( id1Abs, id2Abs);}
+
+ // Allow for third product to be treated in derived classes.
+ if (mult > 2) {
+ id3 = particlePtr->decay[i].product(2);
+ id3Abs = abs(id3);
+
+ // Also order third into descending order of absolute values.
+ if (id3Abs > id2Abs) {swap( id2, id3); swap( id2Abs, id3Abs);}
+ if (id2Abs > id1Abs) {swap( id1, id2); swap( id1Abs, id2Abs);}
+ }
+
+ // Read out masses. Calculate two-body phase space.
+ mf1 = ParticleDataTable::m0(id1Abs);
+ mf2 = ParticleDataTable::m0(id2Abs);
+ mr1 = pow2(mf1 / mHat);
+ mr2 = pow2(mf2 / mHat);
+ ps = (mHat < mf1 + mf2 + MASSMARGIN) ? 0.
+ : sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+ if (mult > 2) {
+ mf3 = ParticleDataTable::m0(id3Abs);
+ mr3 = pow2(mf3 / mHat);
+ }
+
+ // Let derived class calculate width for channel provided.
+ calcWidth(false);
+ }
+
+ // Now on to meMode >= 100. First case: no correction at all.
+ else if (meMode == 100)
+ widNow = GammaRes * particlePtr->decay[i].bRatio();
+
+ // Correction by step at threshold.
+ else if (meMode == 101) {
+ mfSum = 0.;
+ for (int j = 0; j < mult; ++j) mfSum
+ += ParticleDataTable::m0( particlePtr->decay[i].product(j) );
+ if (mfSum + MASSMARGIN < mHat)
+ widNow = GammaRes * particlePtr->decay[i].bRatio();
+ }
+
+ // Correction by a phase space factor for two-body decays.
+ else if ( (meMode == 102 || meMode == 103) && mult == 2) {
+ mf1 = ParticleDataTable::m0( particlePtr->decay[i].product(0) );
+ mf2 = ParticleDataTable::m0( particlePtr->decay[i].product(1) );
+ mr1 = pow2(mf1 / mHat);
+ mr2 = pow2(mf2 / mHat);
+ ps = (mHat < mf1 + mf2 + MASSMARGIN) ? 0.
+ : sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+ mr1 = pow2(mf1 / mRes);
+ mr2 = pow2(mf2 / mRes);
+ psOnShell = (meMode == 102) ? 1. : max( minThreshold,
+ sqrtpos( pow2(1.- mr1 - mr2) - 4. * mr1 * mr2) );
+ widNow = GammaRes * particlePtr->decay[i].bRatio() * ps / psOnShell;
+ }
+
+ // Correction by simple threshold factor for multibody decay.
+ else if (meMode == 102 || meMode == 103) {
+ mfSum = 0.;
+ for (int j = 0; j < mult; ++j) mfSum
+ += ParticleDataTable::m0( particlePtr->decay[i].product(j) );
+ ps = sqrtpos(1. - mfSum / mHat);
+ psOnShell = (meMode == 102) ? 1. : max( minThreshold,
+ sqrtpos(1. - mfSum / mRes) );
+ widNow = GammaRes * particlePtr->decay[i].bRatio() * ps / psOnShell;
+ }
+
+ // Optionally multiply by secondary widths.
+ if (openOnly) widNow *= particlePtr->decay[i].openSec(idSgn);
+
+ // Optionally include factor to force to fixed width??
+ // Optionally multiply by current/nominal resonance mass??
+
+ // Sum back up.
+ widSum += widNow;
+
+ // Optionally store partial widths for later decay channel choice.
+ if (setBR) particlePtr->decay[i].currentBR(widNow);
+ }
+
+ // Done.
+ return widSum;
+
+}
+
+//*********
+
+// Initialize particle properties always present.
+
+bool ResonanceWidths::initBasic(int idResIn) {
+
+ // Resonance identity code and pointer to/from particle species.
+ idRes = idResIn;
+ particlePtr = ParticleDataTable::particleDataPtr(idRes);
+ if (particlePtr == 0) {
+ infoPtr->errorMsg("Error in ResonanceWidths::initBasic:"
+ " unknown resonance identity code");
+ return false;
+ }
+ particlePtr->setResonancePtr(this);
+
+ // Resonance properties: antiparticle, mass, width
+ hasAntiRes = particlePtr->hasAnti();
+ mRes = particlePtr->m0();
+ GammaRes = particlePtr->mWidth();
+ m2Res = mRes*mRes;
+
+ // For very narrow resonances assign fictitious small width.
+ if (GammaRes < minWidth) GammaRes = 0.1 * minWidth;
+ GamMRat = GammaRes / mRes;
+
+ // Secondary decay chains by default all on.
+ openPos = 1.;
+ openNeg = 1.;
+
+ // Allow option where on-shell width is forced to current value.
+ doForceWidth = particlePtr->doForceWidth();
+ forceFactor = 1.;
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Numerical integration of matrix-element in two-body decay,
+// where one particle is described by a Breit-Wigner mass distribution.
+// Normalization to unit integral if matrix element is unity
+// and there are no phase-space restrictions.
+
+double ResonanceWidths::numInt1BW(double mHatIn, double m1, double Gamma1,
+ double mMin1, double m2, int psMode) {
+
+ // Check that phase space is open for integration.
+ if (mMin1 + m2 > mHatIn) return 0.;
+
+ // Precalculate coefficients for Breit-Wigner selection.
+ double s1 = m1 * m1;
+ double mG1 = m1 * Gamma1;
+ double mMax1 = mHatIn - m2;
+ double atanMin1 = atan( (mMin1 * mMin1 - s1) / mG1 );
+ double atanMax1 = atan( (mMax1 * mMax1 - s1) / mG1 );
+ double atanDif1 = atanMax1 - atanMin1;
+ double wtDif1 = atanDif1 / (M_PI * NPOINT);
+
+ // Step size in atan-mapped variable.
+ double xStep = 1. / NPOINT;
+
+ // Variables used in loop over integration points.
+ double sum = 0.;
+ double mrNow2 = pow2(m2 / mHatIn);
+ double xNow1, sNow1, mNow1, mrNow1, psNow, value;
+
+ // Loop with first-particle mass selection.
+ for (int ip1 = 0; ip1 < NPOINT; ++ip1) {
+ xNow1 = xStep * (ip1 + 0.5);
+ sNow1 = s1 + mG1 * tan(atanMin1 + xNow1 * atanDif1);
+ mNow1 = min( mMax1, max( mMin1, sqrtpos(sNow1) ) );
+ mrNow1 = pow2(mNow1 / mHatIn);
+
+ // Evaluate value and add to sum. Different matrix elements.
+ psNow = sqrtpos( pow2(1. - mrNow1 - mrNow2)
+ - 4. * mrNow1 * mrNow2);
+ value = 1.;
+ if (psMode == 1) value = psNow;
+ if (psMode == 2) value = psNow * psNow;
+ if (psMode == 3) value = pow3(psNow);
+ if (psMode == 5) value = psNow *
+ (pow2(1. - mrNow1 - mrNow2) + 8. * mrNow1 * mrNow2);
+ sum += value;
+
+ // End of loop over integration points. Overall normalization.
+ }
+ sum *= wtDif1;
+
+ // Done.
+ return sum;
+}
+
+//*********
+
+// Numerical integration of matrix-element in two-body decay,
+// where both particles are described by Breit-Wigner mass distributions.
+// Normalization to unit integral if matrix element is unity
+// and there are no phase-space restrictions.
+
+double ResonanceWidths::numInt2BW(double mHatIn, double m1, double Gamma1,
+ double mMin1, double m2, double Gamma2, double mMin2, int psMode) {
+
+ // Check that phase space is open for integration.
+ if (mMin1 + mMin2 > mHatIn) return 0.;
+
+ // Precalculate coefficients for Breit-Wigner selection.
+ double s1 = m1 * m1;
+ double mG1 = m1 * Gamma1;
+ double mMax1 = mHatIn - mMin2;
+ double atanMin1 = atan( (mMin1 * mMin1 - s1) / mG1 );
+ double atanMax1 = atan( (mMax1 * mMax1 - s1) / mG1 );
+ double atanDif1 = atanMax1 - atanMin1;
+ double wtDif1 = atanDif1 / (M_PI * NPOINT);
+ double s2 = m2 * m2;
+ double mG2 = m2 * Gamma2;
+ double mMax2 = mHatIn - mMin1;
+ double atanMin2 = atan( (mMin2 * mMin2 - s2) / mG2 );
+ double atanMax2 = atan( (mMax2 * mMax2 - s2) / mG2 );
+ double atanDif2 = atanMax2 - atanMin2;
+ double wtDif2 = atanDif2 / (M_PI * NPOINT);
+
+ // If on-shell decay forbidden then split integration range
+ // to ensure that low-mass region is not forgotten.
+ bool mustDiv = false;
+ double mDiv1 = 0.;
+ double atanDiv1 = 0.;
+ double atanDLo1 = 0.;
+ double atanDHi1 = 0.;
+ double wtDLo1 = 0.;
+ double wtDHi1 = 0.;
+ double mDiv2 = 0.;
+ double atanDiv2 = 0.;
+ double atanDLo2 = 0.;
+ double atanDHi2 = 0.;
+ double wtDLo2 = 0.;
+ double wtDHi2 = 0.;
+ if (m1 + m2 > mHatIn) {
+ mustDiv = true;
+ double tmpDiv = (mHatIn - m1 - m2) / (Gamma1 + Gamma2);
+ mDiv1 = m1 + Gamma1 * tmpDiv;
+ atanDiv1 = atan( (mDiv1 * mDiv1 - s1) / mG1 );
+ atanDLo1 = atanDiv1 - atanMin1;
+ atanDHi1 = atanMax1 - atanDiv1;
+ wtDLo1 = atanDLo1 / (M_PI * NPOINT);
+ wtDHi1 = atanDHi1 / (M_PI * NPOINT);
+ mDiv2 = m2 + Gamma2 * tmpDiv;
+ atanDiv2 = atan( (mDiv2 * mDiv2 - s2) / mG2 );
+ atanDLo2 = atanDiv2 - atanMin2;
+ atanDHi2 = atanMax2 - atanDiv2;
+ wtDLo2 = atanDLo2 / (M_PI * NPOINT);
+ wtDHi2 = atanDHi2 / (M_PI * NPOINT);
+ }
+
+ // Step size in atan-mapped variable.
+ double xStep = 1. / NPOINT;
+ int nIter = (mustDiv) ? 2 * NPOINT : NPOINT;
+
+ // Variables used in loop over integration points.
+ double sum = 0.;
+ double xNow1, sNow1, mNow1, mrNow1, xNow2, sNow2, mNow2, mrNow2, psNow,
+ value;
+ double wtNow1 = wtDif1;
+ double wtNow2 = wtDif2;
+
+ // Outer loop with first-particle mass selection.
+ for (int ip1 = 0; ip1 < nIter; ++ip1) {
+ if (!mustDiv) {
+ xNow1 = xStep * (ip1 + 0.5);
+ sNow1 = s1 + mG1 * tan(atanMin1 + xNow1 * atanDif1);
+ } else if (ip1 < NPOINT) {
+ xNow1 = xStep * (ip1 + 0.5);
+ sNow1 = s1 + mG1 * tan(atanMin1 + xNow1 * atanDLo1);
+ wtNow1 = wtDLo1;
+ } else {
+ xNow1 = xStep * (ip1 - NPOINT + 0.5);
+ sNow1 = s1 + mG1 * tan(atanDiv1 + xNow1 * atanDHi1);
+ wtNow1 = wtDHi1;
+ }
+ mNow1 = min( mMax1, max( mMin1, sqrtpos(sNow1) ) );
+ mrNow1 = pow2(mNow1 / mHatIn);
+
+ // Inner loop with second-particle mass selection.
+ for (int ip2 = 0; ip2 < nIter; ++ip2) {
+ if (!mustDiv) {
+ xNow2 = xStep * (ip2 + 0.5);
+ sNow2 = s2 + mG2 * tan(atanMin2 + xNow2 * atanDif2);
+ } else if (ip2 < NPOINT) {
+ xNow2 = xStep * (ip2 + 0.5);
+ sNow2 = s2 + mG2 * tan(atanMin2 + xNow2 * atanDLo2);
+ wtNow2 = wtDLo2;
+ } else {
+ xNow2 = xStep * (ip2 - NPOINT + 0.5);
+ sNow2 = s2 + mG2 * tan(atanDiv2 + xNow2 * atanDHi2);
+ wtNow2 = wtDHi2;
+ }
+ mNow2 = min( mMax2, max( mMin2, sqrtpos(sNow2) ) );
+ mrNow2 = pow2(mNow2 / mHatIn);
+
+ // Check that point is inside phase space.
+ if (mNow1 + mNow2 > mHatIn) break;
+
+ // Evaluate value and add to sum. Different matrix elements.
+ psNow = sqrtpos( pow2(1. - mrNow1 - mrNow2)
+ - 4. * mrNow1 * mrNow2);
+ value = 1.;
+ if (psMode == 1) value = psNow;
+ else if (psMode == 2) value = psNow * psNow;
+ else if (psMode == 3) value = pow3(psNow);
+ else if (psMode == 5) value = psNow
+ * (pow2(1. - mrNow1 - mrNow2) + 8. * mrNow1 * mrNow2);
+ sum += value * wtNow1 * wtNow2;
+
+ // End of second and first loop over integration points.
+ }
+ }
+
+ // Done.
+ return sum;
+}
+
+//**************************************************************************
+
+// The ResonanceGmZ class.
+// Derived class for gamma*/Z0 properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceGmZ::initConstants() {
+
+ // Locally stored properties and couplings.
+ gmZmode = Settings::mode("WeakZ0:gmZmode");
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceGmZ::calcPreFac(bool calledFromInit) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * mHat / 3.;
+
+ // When call for incoming flavour need to consider gamma*/Z0 mix.
+ if (!calledFromInit) {
+
+ // Couplings when an incoming fermion is specified; elso only pure Z0.
+ ei2 = 0.;
+ eivi = 0.;
+ vi2ai2 = 1.;
+ int idInFlavAbs = abs(idInFlav);
+ if (idInFlavAbs > 0 && idInFlavAbs < 19) {
+ ei2 = CoupEW::ef2(idInFlavAbs);
+ eivi = CoupEW::efvf(idInFlavAbs);
+ vi2ai2 = CoupEW::vf2af2(idInFlavAbs);
+ }
+
+ // Calculate prefactors for gamma/interference/Z0 terms.
+ double sH = mHat * mHat;
+ gamNorm = ei2;
+ intNorm = 2. * eivi * thetaWRat * sH * (sH - m2Res)
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ resNorm = vi2ai2 * pow2(thetaWRat * sH)
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+
+ // Rescale Z0 height normalization to compensate for a width one??
+ //if (doForceWidth) {
+ // intNorm *= forceFactor;
+ // resNorm *= forceFactor;
+ //}
+
+ // Optionally only keep gamma* or Z0 term.
+ if (gmZmode == 1) {intNorm = 0.; resNorm = 0.;}
+ if (gmZmode == 2) {gamNorm = 0.; intNorm = 0.;}
+ }
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceGmZ::calcWidth(bool calledFromInit) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // Only contributions from three fermion generations, except top.
+ if ( (id1Abs > 5 && id1Abs < 11) || id1Abs > 16 ) return;
+
+ // At initialization only the pure Z0 should be considered.
+ if (calledFromInit) {
+
+ // Combine kinematics with colour factor and couplings.
+ widNow = preFac * ps * (CoupEW::vf2(id1Abs) * (1. + 2. * mr1)
+ + CoupEW::af2(id1Abs) * ps*ps);
+ if (id1Abs < 6) widNow *= colQ;
+ }
+
+ // When call for incoming flavour need to consider gamma*/Z0 mix.
+ else {
+
+ // Kinematical factors and couplings.
+ double kinFacV = ps * (1. + 2. * mr1);
+ double ef2 = CoupEW::ef2(id1Abs) * kinFacV;
+ double efvf = CoupEW::efvf(id1Abs) * kinFacV;
+ double vf2af2 = CoupEW::vf2(id1Abs) * kinFacV
+ + CoupEW::af2(id1Abs) * pow3(ps);
+
+ // Relative outwidths: combine instate, propagator and outstate.
+ widNow = gamNorm * ef2 + intNorm * efvf + resNorm * vf2af2;
+
+ // Colour factor.
+ if (id1Abs < 6) widNow *= colQ;
+ }
+
+}
+
+//**************************************************************************
+
+// The ResonanceW class.
+// Derived class for W+- properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceW::initConstants() {
+
+ // Locally stored properties and couplings.
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceW::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * mHat;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceW::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // Only contributions from three fermion generations, except top.
+ if ( (id1Abs > 5 && id1Abs < 11) || id1Abs > 16 ) return;
+
+
+ // Combine kinematics with colour factor and couplings.
+ widNow = preFac * ps
+ * (1. - 0.5 * (mr1 + mr2) - 0.5 * pow2(mr1 - mr2));
+ if (id1Abs < 6) widNow *= colQ * VCKM::V2id(id1Abs, id2Abs);
+
+}
+
+//**************************************************************************
+
+// The ResonanceTop class.
+// Derived class for top/antitop properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceTop::initConstants() {
+
+ // Locally stored properties and couplings.
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW());
+ m2W = pow2(ParticleDataTable::m0(24));
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceTop::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 1. - 2.5 * alpS / M_PI;
+ preFac = alpEM * thetaWRat * pow3(mHat) / m2W;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceTop::calcWidth(bool) {
+
+ // Only contributions from W + quark.
+ if (id1Abs != 24 || id2Abs > 5) return;
+
+ // Check that above threshold. Kinematical factor.
+ if (ps == 0.) return;
+ widNow = preFac * ps
+ * ( pow2(1. - mr2) + (1. + mr2) * mr1 - 2. * mr1 * mr1 );
+
+ // Combine with colour factor and CKM couplings.
+ widNow *= colQ * VCKM::V2id(6, id2Abs);
+
+}
+
+//**************************************************************************
+
+// The ResonanceFour class.
+// Derived class for fourth-generation properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceFour::initConstants() {
+
+ // Locally stored properties and couplings.
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW());
+ m2W = pow2(ParticleDataTable::m0(24));
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceFour::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = (idRes < 9) ? 1. - 2.5 * alpS / M_PI : 1.;
+ preFac = alpEM * thetaWRat * pow3(mHat) / m2W;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceFour::calcWidth(bool) {
+
+ // Only contributions from W + fermion.
+ if (id1Abs != 24 || id2Abs > 18) return;
+
+ // Check that above threshold. Kinematical factor.
+ if (ps == 0.) return;
+ widNow = preFac * ps
+ * ( pow2(1. - mr2) + (1. + mr2) * mr1 - 2. * mr1 * mr1 );
+
+ // Combine with colour factor and CKM couplings.
+ if (idRes < 9) widNow *= colQ * VCKM::V2id(idRes, id2Abs);
+
+}
+
+//**************************************************************************
+
+// The ResonanceH class.
+// Derived class for SM and BSM Higgs properties.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Minimal mass for W, Z, top in integration over respective Breit-Wigner.
+const double ResonanceH::MASSMIN = 10.;
+
+// Number of widths above threshold where B-W integration not needed.
+const double ResonanceH::GAMMAMARGIN = 10.;
+
+//*********
+
+// Initialize constants.
+
+void ResonanceH::initConstants() {
+
+ // Locally stored properties and couplings.
+ useCubicWidth = Settings::flag("Higgs:cubicWidth");
+ useRunLoopMass = Settings::flag("Higgs:runningLoopMass");
+ sin2tW = CoupEW::sin2thetaW();
+ cos2tW = 1. - sin2tW;
+ mT = ParticleDataTable::m0(6);
+ mZ = ParticleDataTable::m0(23);
+ mW = ParticleDataTable::m0(24);
+ mHchg = ParticleDataTable::m0(37);
+ GammaT = ParticleDataTable::mWidth(6);
+ GammaZ = ParticleDataTable::mWidth(23);
+ GammaW = ParticleDataTable::mWidth(24);
+
+ // Couplings to fermions, Z and W, depending on Higgs type.
+ coup2d = 1.;
+ coup2u = 1.;
+ coup2l = 1.;
+ coup2Z = 1.;
+ coup2W = 1.;
+ coup2Hchg = 0.;
+ coup2H1H1 = 0.;
+ coup2A3A3 = 0.;
+ coup2H1Z = 0.;
+ coup2A3Z = 0.;
+ coup2A3H1 = 0.;
+ coup2HchgW = 0.;
+ if (higgsType == 1) {
+ coup2d = Settings::parm("HiggsH1:coup2d");
+ coup2u = Settings::parm("HiggsH1:coup2u");
+ coup2l = Settings::parm("HiggsH1:coup2l");
+ coup2Z = Settings::parm("HiggsH1:coup2Z");
+ coup2W = Settings::parm("HiggsH1:coup2W");
+ coup2Hchg = Settings::parm("HiggsH1:coup2Hchg");
+ } else if (higgsType == 2) {
+ coup2d = Settings::parm("HiggsH2:coup2d");
+ coup2u = Settings::parm("HiggsH2:coup2u");
+ coup2l = Settings::parm("HiggsH2:coup2l");
+ coup2Z = Settings::parm("HiggsH2:coup2Z");
+ coup2W = Settings::parm("HiggsH2:coup2W");
+ coup2Hchg = Settings::parm("HiggsH2:coup2Hchg");
+ coup2H1H1 = Settings::parm("HiggsH2:coup2H1H1");
+ coup2A3A3 = Settings::parm("HiggsH2:coup2A3A3");
+ coup2H1Z = Settings::parm("HiggsH2:coup2H1Z");
+ coup2A3Z = Settings::parm("HiggsA3:coup2H2Z");
+ coup2A3H1 = Settings::parm("HiggsH2:coup2A3H1");
+ coup2HchgW = Settings::parm("HiggsH2:coup2HchgW");
+ } else if (higgsType == 3) {
+ coup2d = Settings::parm("HiggsA3:coup2d");
+ coup2u = Settings::parm("HiggsA3:coup2u");
+ coup2l = Settings::parm("HiggsA3:coup2l");
+ coup2Z = Settings::parm("HiggsA3:coup2Z");
+ coup2W = Settings::parm("HiggsA3:coup2W");
+ coup2Hchg = Settings::parm("HiggsA3:coup2Hchg");
+ coup2H1H1 = Settings::parm("HiggsA3:coup2H1H1");
+ coup2H1Z = Settings::parm("HiggsA3:coup2H1Z");
+ coup2HchgW = Settings::parm("HiggsA3:coup2Hchg");
+ }
+
+ // Initialization of threshold kinematical factor by stepwise
+ // numerical integration of H -> t tbar, Z0 Z0 and W+ W-.
+ int psMode = (higgsType < 3) ? 3 : 1;
+ for (int i = 0; i <= 100; ++i) {
+ kinFacT[i] = numInt2BW( (0.5 + 0.025 * i) * mT,
+ mT, GammaT, MASSMIN, mT, GammaT, MASSMIN, psMode);
+ kinFacZ[i] = numInt2BW( (0.5 + 0.025 * i) * mZ,
+ mZ, GammaZ, MASSMIN, mZ, GammaZ, MASSMIN, 5);
+ kinFacW[i] = numInt2BW( (0.5 + 0.025 * i) * mW,
+ mW, GammaW, MASSMIN, mW, GammaW, MASSMIN, 5);
+ }
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceH::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = (alpEM / (8. * sin2tW)) * pow3(mHat) / pow2(mW);
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceH::calcWidth(bool) {
+
+ // Widths of decays Higgs -> f + fbar.
+ if ( id2Abs == id1Abs && ( (id1Abs > 0 && id1Abs < 7)
+ || (id1Abs > 10 && id1Abs < 17) ) ) {
+ kinFac = 0.;
+
+ // Check that above threshold (well above for top). Kinematical factor.
+ if ( (id1Abs != 6 && mHat > 2. * mf1 + MASSMARGIN)
+ || (id1Abs == 6 && mHat > 3. * mT ) ) {
+ // A0 behaves like beta, h0 and H0 like beta**3.
+ kinFac = (higgsType < 3) ? pow3(ps) : ps;
+ }
+
+ // Top near or below threshold: interpolate in table or extrapolate below.
+ else if (id1Abs == 6 && mHat > 0.5 * mT) {
+ double xTab = 40. * (mHat / mT - 0.5);
+ int iTab = max( 0, min( 99, int(xTab) ) );
+ kinFac = kinFacT[iTab]
+ * pow( kinFacT[iTab + 1] / kinFacT[iTab], xTab - iTab);
+ }
+ else if (id1Abs == 6) kinFac = kinFacT[0]
+ * 2. / (1. + pow6(0.5 * mT / mHat));
+
+ // Coupling from mass and from BSM deviation from SM.
+ double coupFac = pow2(ParticleDataTable::mRun(id1Abs, mHat) / mHat);
+ if (id1Abs < 7 && id1Abs%2 == 1) coupFac *= coup2d * coup2d;
+ else if (id1Abs < 7) coupFac *= coup2u * coup2u;
+ else coupFac *= coup2l * coup2l;
+
+ // Combine couplings and phase space with colour factor.
+ widNow = preFac * coupFac * kinFac;
+ if (id1Abs < 7) widNow *= colQ;
+ }
+
+ // Widths of decays Higgs -> g + g.
+ else if (id1Abs == 21 && id2Abs == 21)
+ widNow = preFac * pow2(alpS / M_PI) * eta2gg();
+
+ // Widths of decays Higgs -> gamma + gamma.
+ else if (id1Abs == 22 && id2Abs == 22)
+ widNow = preFac * pow2(alpEM / M_PI) * 0.5 * eta2gaga();
+
+ // Widths of decays Higgs -> Z0 + gamma0.
+ else if (id1Abs == 23 && id2Abs == 22)
+ widNow = preFac * pow2(alpEM / M_PI) * pow3(ps) * eta2gaZ();
+
+ // Widths of decays Higgs (h0, H0) -> Z0 + Z0.
+ else if (id1Abs == 23 && id2Abs == 23) {
+ // If Higgs heavy use on-shell expression, else interpolation in table
+ if (mHat > 3. * mZ) kinFac = (1. - 4. * mr1 + 12. * mr1 * mr1) * ps;
+ else if (mHat > 0.5 * mZ) {
+ double xTab = 40. * (mHat / mZ - 0.5);
+ int iTab = max( 0, min( 99, int(xTab) ) );
+ kinFac = kinFacZ[iTab]
+ * pow( kinFacZ[iTab + 1] / kinFacZ[iTab], xTab - iTab );
+ }
+ else kinFac = kinFacZ[0] * 2. / (1. + pow6(0.5 * mZ / mHat));
+ // Prefactor, normally rescaled to mRes^2 * mHat rather than mHat^3.
+ widNow = 0.25 * preFac * pow2(coup2Z) * kinFac;
+ if (!useCubicWidth) widNow *= pow2(mRes / mHat);
+ }
+
+ // Widths of decays Higgs (h0, H0) -> W+ + W-.
+ else if (id1Abs == 24 && id2Abs == 24) {
+ // If Higgs heavy use on-shell expression, else interpolation in table.
+ if (mHat > 3. * mW) kinFac = (1. - 4. * mr1 + 12. * mr1 * mr1) * ps;
+ else if (mHat > 0.5 * mW) {
+ double xTab = 40. * (mHat / mW - 0.5);
+ int iTab = max( 0, min( 99, int(xTab) ) );
+ kinFac = kinFacW[iTab]
+ * pow( kinFacW[iTab + 1] / kinFacW[iTab], xTab - iTab);
+ }
+ else kinFac = kinFacW[0] * 2. / (1. + pow6(0.5 * mW / mHat));
+ // Prefactor, normally rescaled to mRes^2 * mHat rather than mHat^3.
+ widNow = 0.5 * preFac * pow2(coup2W) * kinFac;
+ if (!useCubicWidth) widNow *= pow2(mRes / mHat);
+ }
+
+ // Widths of decays Higgs (H0) -> h0 + h0.
+ else if (id1Abs == 25 && id2Abs == 25)
+ widNow = 0.25 * preFac * pow4(mZ / mHat) * ps * pow2(coup2H1H1);
+
+ // Widths of decays Higgs (H0) -> A0 + A0.
+ else if (id1Abs == 36 && id2Abs == 36)
+ widNow = 0.5 * preFac * pow4(mZ / mHat) * ps * pow2(coup2A3A3);
+
+ // Widths of decays Higgs (A0) -> h0 + Z0.
+ else if (id1Abs == 25 && id2Abs == 23)
+ widNow = 0.5 * preFac * pow3(ps) * pow2(coup2H1Z);
+
+ // Widths of decays Higgs (H0) -> A0 + Z0.
+ else if (id1Abs == 36 && id2Abs == 23)
+ widNow = 0.5 * preFac * pow3(ps) * pow2(coup2A3Z);
+
+ // Widths of decays Higgs (H0) -> A0 + h0.
+ else if (id1Abs == 36 && id2Abs == 25)
+ widNow = 0.25 * preFac * pow4(mZ / mHat) * ps * pow2(coup2A3H1);
+
+ // Widths of decays Higgs -> H+- + W-+.
+ else if (id1Abs == 37 && id2Abs == 24)
+ widNow = 0.5 * preFac * pow3(ps) * pow2(coup2HchgW);
+
+}
+
+//*********
+
+// Sum up quark loop contributions in Higgs -> g + g.
+// Note: running quark masses are used, unlike Pythia6 (not negligible shift).
+
+double ResonanceH::eta2gg() {
+
+ // Initial values.
+ complex eta = complex(0., 0.);
+ double mLoop, epsilon, root, rootLog;
+ complex phi, etaNow;
+
+ // Loop over s, c, b, t quark flavours.
+ for (int idNow = 3; idNow < 7; ++idNow) {
+ mLoop = (useRunLoopMass) ? ParticleDataTable::mRun(idNow, mHat)
+ : ParticleDataTable::m0(idNow);
+ epsilon = pow2(2. * mLoop / mHat);
+
+ // Value of loop integral.
+ if (epsilon <= 1.) {
+ root = sqrt(1. - epsilon);
+ rootLog = (epsilon < 1e-4) ? log(4. / epsilon - 2.)
+ : log( (1. + root) / (1. - root) );
+ phi = complex( -0.25 * (pow2(rootLog) - pow2(M_PI)),
+ 0.5 * M_PI * rootLog );
+ }
+ else phi = complex( pow2( asin(1. / sqrt(epsilon)) ), 0.);
+
+ // Factors that depend on Higgs and flavour type.
+ if (higgsType < 3) etaNow = -0.5 * epsilon
+ * (complex(1., 0.) + (1. - epsilon) * phi);
+ else etaNow = -0.5 * epsilon * phi;
+ if (idNow%2 == 1) etaNow *= coup2d;
+ else etaNow *= coup2u;
+
+ // Sum up contribution and return square of absolute value.
+ eta += etaNow;
+ }
+ return (pow2(eta.real()) + pow2(eta.imag()));
+
+}
+
+//*********
+
+// Sum up quark, lepton, W+- and (for BSM) H+- loop contributions
+// in Higgs -> gamma + gamma.
+
+double ResonanceH::eta2gaga() {
+
+ // Initial values.
+ complex eta = complex(0., 0.);
+ int idNow;
+ double ef, mLoop, epsilon, root, rootLog;
+ complex phi, etaNow;
+
+ // Loop over s, c, b, t, mu, tau, W+-, H+- flavours.
+ for (int idLoop = 0; idLoop < 8; ++idLoop) {
+ if (idLoop < 4) idNow = idLoop + 3;
+ else if (idLoop < 6) idNow = 2 * idLoop + 5;
+ else if (idLoop < 7) idNow = 24;
+ else idNow = 37;
+ if (idNow == 37 && higgsType == 0) continue;
+
+ // Charge and loop integral parameter.
+ ef = (idNow < 20) ? CoupEW::ef(idNow) : 1.;
+ mLoop = (useRunLoopMass) ? ParticleDataTable::mRun(idNow, mHat)
+ : ParticleDataTable::m0(idNow);
+ epsilon = pow2(2. * mLoop / mHat);
+
+ // Value of loop integral.
+ if (epsilon <= 1.) {
+ root = sqrt(1. - epsilon);
+ rootLog = (epsilon < 1e-4) ? log(4. / epsilon - 2.)
+ : log( (1. + root) / (1. - root) );
+ phi = complex( -0.25 * (pow2(rootLog) - pow2(M_PI)),
+ 0.5 * M_PI * rootLog );
+ }
+ else phi = complex( pow2( asin(1. / sqrt(epsilon)) ), 0.);
+
+ // Expressions for quarks and leptons that depend on Higgs type.
+ if (idNow < 17) {
+ if (higgsType < 3) etaNow = -0.5 * epsilon
+ * (complex(1., 0.) + (1. - epsilon) * phi);
+ else etaNow = -0.5 * epsilon * phi;
+ if (idNow < 7 && idNow%2 == 1) etaNow *= 3. * pow2(ef) * coup2d;
+ else if (idNow < 7 ) etaNow *= 3. * pow2(ef) * coup2u;
+ else etaNow *= pow2(ef) * coup2l;
+ }
+
+ // Expression for W+-.
+ else if (idNow == 24) etaNow = (complex(0.5 + 0.75 * epsilon, 0.)
+ + 0.75 * epsilon * (2. - epsilon) * phi) * coup2W;
+
+ // Expression for H+-.
+ else etaNow = (complex(epsilon, 0.) - epsilon * epsilon * phi)
+ * pow2(mW / mHchg) * coup2Hchg;
+
+ // Sum up contribution and return square of absolute value.
+ eta += etaNow;
+ }
+ return (pow2(eta.real()) + pow2(eta.imag()));
+
+}
+
+//*********
+
+// Sum up quark, lepton, W+- and (for BSM) H+- loop contributions
+// in Higgs -> gamma + Z0.
+
+double ResonanceH::eta2gaZ() {
+
+ // Initial values.
+ complex eta = complex(0., 0.);
+ int idNow;
+ double ef, vf, mLoop, epsilon, epsPrime, root, rootLog, asinEps;
+ complex phi, psi, phiPrime, psiPrime, fXY, f1, etaNow;
+
+ // Loop over s, c, b, t, mu , tau, W+-, H+- flavours.
+ for (int idLoop = 0; idLoop < 7; ++idLoop) {
+ if (idLoop < 4) idNow = idLoop + 3;
+ else if (idLoop < 6) idNow = 2 * idLoop + 5;
+ else if (idLoop < 7) idNow = 24;
+ else idNow = 37;
+
+ // Electroweak charges and loop integral parameters.
+ ef = (idNow < 20) ? CoupEW::ef(idNow) : 1.;
+ vf = (idNow < 20) ? CoupEW::vf(idNow) : 0.;
+ mLoop = (useRunLoopMass) ? ParticleDataTable::mRun(idNow, mHat)
+ : ParticleDataTable::m0(idNow);
+ epsilon = pow2(2. * mLoop / mHat);
+ epsPrime = pow2(2. * mLoop / mZ);
+
+ // Value of loop integral for epsilon = 4 m^2 / sHat.
+ if (epsilon <= 1.) {
+ root = sqrt(1. - epsilon);
+ rootLog = (epsilon < 1e-4) ? log(4. / epsilon - 2.)
+ : log( (1. + root) / (1. - root) );
+ phi = complex( -0.25 * (pow2(rootLog) - pow2(M_PI)),
+ 0.5 * M_PI * rootLog );
+ psi = 0.5 * root * complex( rootLog, -M_PI);
+ } else {
+ asinEps = asin(1. / sqrt(epsilon));
+ phi = complex( pow2(asinEps), 0.);
+ psi = complex( sqrt(epsilon - 1.) * asinEps, 0.);
+ }
+
+ // Value of loop integral for epsilonPrime = 4 m^2 / m_Z^2.
+ if (epsPrime <= 1.) {
+ root = sqrt(1. - epsPrime);
+ rootLog = (epsPrime < 1e-4) ? log(4. / epsPrime - 2.)
+ : log( (1. + root) / (1. - root) );
+ phiPrime = complex( -0.25 * (pow2(rootLog) - pow2(M_PI)),
+ 0.5 * M_PI * rootLog );
+ psiPrime = 0.5 * root * complex( rootLog, -M_PI);
+ } else {
+ asinEps = asin(1. / sqrt(epsPrime));
+ phiPrime = complex( pow2(asinEps), 0.);
+ psiPrime = complex( sqrt(epsPrime - 1.) * asinEps, 0.);
+ }
+
+ // Combine the two loop integrals.
+ fXY = (epsilon * epsPrime / (8. * pow2(epsilon - epsPrime)))
+ * ( complex(epsilon - epsPrime, 0)
+ + epsilon * epsPrime * (phi - phiPrime)
+ + 2. * epsilon * (psi - psiPrime) );
+ f1 = - (epsilon * epsPrime / (2. * (epsilon - epsPrime)))
+ * (phi - phiPrime);
+
+ // Expressions for quarks and leptons that depend on Higgs type.
+ if (idNow < 17) {
+ etaNow = (higgsType < 3) ? -fXY + 0.25 * f1 : 0.25 * f1;
+ if (idNow < 7 && idNow%2 == 1) etaNow *= 3. * ef * vf * coup2d;
+ else if (idNow < 7) etaNow *= 3. * ef * vf * coup2u;
+ else etaNow *= ef * vf * coup2l;
+
+ // Expression for W+-.
+ } else if (idNow == 24) {
+ double coef1 = 3. - sin2tW / cos2tW;
+ double coefXY = (1. + 2. / epsilon) * sin2tW / cos2tW
+ - (5. + 2. / epsilon);
+ etaNow = -cos2tW * (coef1 * f1 + coefXY * fXY) * coup2W;
+
+ // Expression for H+-.
+ } else etaNow = (1. - 2. * sin2tW) * fXY * pow2(mW / mHchg)
+ * coup2Hchg;
+
+ // Sum up contribution and return square of absolute value.
+ eta += etaNow;
+ }
+ return ( (pow2(eta.real()) + pow2(eta.imag())) / (sin2tW * cos2tW) );
+
+}
+
+//**************************************************************************
+
+// The ResonanceHchg class.
+// Derived class for H+- properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceHchg::initConstants() {
+
+ // Locally stored properties and couplings.
+ useCubicWidth = Settings::flag("Higgs:cubicWidth");
+ thetaWRat = 1. / (8. * CoupEW::sin2thetaW());
+ mW = ParticleDataTable::m0(24);
+ tanBeta = Settings::parm("HiggsHchg:tanBeta");
+ tan2Beta = tanBeta * tanBeta;
+ coup2H1W = Settings::parm("HiggsHchg:coup2H1W");
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceHchg::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * pow3(mHat) / pow2(mW);
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceHchg::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // H+- decay to fermions involves running masses.
+ if (id1Abs < 17 && (id1Abs < 7 || id1Abs > 10)) {
+ double mRun1 = ParticleDataTable::mRun(id1Abs, mHat);
+ double mRun2 = ParticleDataTable::mRun(id2Abs, mHat);
+ double mrRunDn = pow2(mRun1 / mHat);
+ double mrRunUp = pow2(mRun2 / mHat);
+ if (id1Abs%2 == 0) swap( mrRunDn, mrRunUp);
+
+ // Width to fermions: couplings, kinematics, colour factor.
+ widNow = preFac * max( 0., (mrRunDn * tan2Beta + mrRunUp / tan2Beta)
+ * (1. - mrRunDn - mrRunUp) - 4. *mrRunDn * mrRunUp ) * ps;
+ if (id1Abs < 7) widNow *= colQ;
+ }
+
+ // H+- decay to h0 + W+-.
+ else if (id1Abs == 25 && id2Abs == 24)
+ widNow = 0.5 * preFac * pow3(ps) * pow2(coup2H1W);
+
+}
+
+//**************************************************************************
+
+// The ResonanceZprime class.
+// Derived class for gamma*/Z0/Z'^0 properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceZprime::initConstants() {
+
+ // Locally stored properties and couplings.
+ gmZmode = Settings::mode("Zprime:gmZmode");
+ sin2tW = CoupEW::sin2thetaW();
+ cos2tW = 1. - sin2tW;
+ thetaWRat = 1. / (16. * sin2tW * cos2tW);
+
+ // Properties of Z resonance.
+ mZ = ParticleDataTable::m0(23);
+ GammaZ = ParticleDataTable::mWidth(23);
+ m2Z = mZ*mZ;
+ GamMRatZ = GammaZ / mZ;
+
+ // Ensure that arrays initially empty.
+ for (int i = 0; i < 20; ++i) afZp[i] = 0.;
+ for (int i = 0; i < 20; ++i) vfZp[i] = 0.;
+
+ // Store first-generation axial and vector couplings.
+ afZp[1] = Settings::parm("Zprime:ad");
+ afZp[2] = Settings::parm("Zprime:au");
+ afZp[11] = Settings::parm("Zprime:ae");
+ afZp[12] = Settings::parm("Zprime:anue");
+ vfZp[1] = Settings::parm("Zprime:vd");
+ vfZp[2] = Settings::parm("Zprime:vu");
+ vfZp[11] = Settings::parm("Zprime:ve");
+ vfZp[12] = Settings::parm("Zprime:vnue");
+
+ // Second and third generation could be carbon copy of this...
+ if (Settings::flag("Zprime:universality")) {
+ for (int i = 3; i <= 6; ++i) {
+ afZp[i] = afZp[i-2];
+ vfZp[i] = vfZp[i-2];
+ afZp[i+10] = afZp[i+8];
+ vfZp[i+10] = vfZp[i+8];
+ }
+
+ // ... or could have different couplings.
+ } else {
+ afZp[3] = Settings::parm("Zprime:as");
+ afZp[4] = Settings::parm("Zprime:ac");
+ afZp[5] = Settings::parm("Zprime:ab");
+ afZp[6] = Settings::parm("Zprime:at");
+ afZp[13] = Settings::parm("Zprime:amu");
+ afZp[14] = Settings::parm("Zprime:anumu");
+ afZp[15] = Settings::parm("Zprime:atau");
+ afZp[16] = Settings::parm("Zprime:anutau");
+ vfZp[3] = Settings::parm("Zprime:vs");
+ vfZp[4] = Settings::parm("Zprime:vc");
+ vfZp[5] = Settings::parm("Zprime:vb");
+ vfZp[6] = Settings::parm("Zprime:vt");
+ vfZp[13] = Settings::parm("Zprime:vmu");
+ vfZp[14] = Settings::parm("Zprime:vnumu");
+ vfZp[15] = Settings::parm("Zprime:vtau");
+ vfZp[16] = Settings::parm("Zprime:vnutau");
+ }
+
+ // Coupling for Z' -> W+ W-.
+ coupZpWW = Settings::parm("Zprime:coup2WW");
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceZprime::calcPreFac(bool calledFromInit) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * mHat / 3.;
+
+ // When call for incoming flavour need to consider gamma*/Z0 mix.
+ if (!calledFromInit) {
+
+ // Couplings when an incoming fermion is specified; elso only pure Z'0.
+ ei2 = 0.;
+ eivi = 0.;
+ vai2 = 0.;
+ eivpi = 0.;
+ vaivapi = 0.,
+ vapi2 = 1.;
+ int idInFlavAbs = abs(idInFlav);
+ if (idInFlavAbs > 0 && idInFlavAbs < 19) {
+ double ei = CoupEW::ef(idInFlavAbs);
+ double ai = CoupEW::af(idInFlavAbs);
+ double vi = CoupEW::vf(idInFlavAbs);
+ double api = afZp[idInFlavAbs];
+ double vpi = vfZp[idInFlavAbs];
+ ei2 = ei * ei;
+ eivi = ei * vi;
+ vai2 = vi * vi + ai * ai;
+ eivpi = ei * vpi;
+ vaivapi = vi * vpi + ai * api;;
+ vapi2 = vpi * vpi + api * api;
+ }
+
+ // Calculate prefactors for gamma/interference/Z0 terms.
+ double sH = mHat * mHat;
+ double propZ = sH / ( pow2(sH - m2Z) + pow2(sH * GamMRatZ) );
+ double propZp = sH / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ gamNorm = ei2;
+ gamZNorm = 2. * eivi * thetaWRat * (sH - m2Z) * propZ;
+ ZNorm = vai2 * pow2(thetaWRat) * sH * propZ;
+ gamZpNorm = 2. * eivpi * thetaWRat * (sH - m2Res) * propZp;
+ ZZpNorm = 2. * vaivapi * pow2(thetaWRat) * ((sH - m2Res) * (sH - m2Z)
+ + sH * GamMRat * sH * GamMRatZ) * propZ * propZp;
+ ZpNorm = vapi2 * pow2(thetaWRat) * sH * propZp;
+
+ // Rescale Z0 height normalization to compensate for a width one??
+ //if (doForceWidth) {
+ // intNorm *= forceFactor;
+ // resNorm *= forceFactor;
+ //}
+
+ // Optionally only keep some of gamma*, Z0 and Z' terms.
+ if (gmZmode == 1) {gamZNorm = 0; ZNorm = 0.; gamZpNorm = 0.;
+ ZZpNorm = 0.; ZpNorm = 0.;}
+ if (gmZmode == 2) {gamNorm = 0.; gamZNorm = 0.; gamZpNorm = 0.;
+ ZZpNorm = 0.; ZpNorm = 0.;}
+ if (gmZmode == 3) {gamNorm = 0.; gamZNorm = 0.; ZNorm = 0.;
+ gamZpNorm = 0.; ZZpNorm = 0.;}
+ if (gmZmode == 4) {gamZpNorm = 0.; ZZpNorm = 0.; ZpNorm = 0.;}
+ if (gmZmode == 5) {gamZNorm = 0.; ZNorm = 0.; ZZpNorm = 0.;}
+ if (gmZmode == 6) {gamNorm = 0.; gamZNorm = 0.; gamZpNorm = 0.;}
+ }
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceZprime::calcWidth(bool calledFromInit) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // At initialization only the pure Z'0 should be considered.
+ if (calledFromInit) {
+
+ // Contributions from three fermion generations.
+ if ( id1Abs < 7 || (id1Abs > 10 && id1Abs < 17) ) {
+ double apf = afZp[id1Abs];
+ double vpf = vfZp[id1Abs];
+ widNow = preFac * ps * (vpf*vpf * (1. + 2. * mr1)
+ + apf*apf * ps*ps);
+ if (id1Abs < 7) widNow *= colQ;
+
+ // Contribution from Z'0 -> W^+ W^-.
+ } else if (id1Abs == 24) {
+ widNow = preFac * pow2(coupZpWW * cos2tW) * pow3(ps)
+ * (1. + mr1*mr1 + mr2*mr2 + 10. * (mr1 + mr2 + mr1 * mr2));
+ }
+ }
+
+ // When call for incoming flavour need to consider full mix.
+ else {
+
+ // Contributions from three fermion generations.
+ if ( id1Abs < 7 || (id1Abs > 10 && id1Abs < 17) ) {
+
+ // Couplings of gamma^*/Z^0/Z'^0 to final flavour
+ double ef = CoupEW::ef(id1Abs);
+ double af = CoupEW::af(id1Abs);
+ double vf = CoupEW::vf(id1Abs);
+ double apf = afZp[id1Abs];
+ double vpf = vfZp[id1Abs];
+
+ // Combine couplings with kinematical factors.
+ double kinFacA = pow3(ps);
+ double kinFacV = ps * (1. + 2. * mr1);
+ double ef2 = ef * ef * kinFacV;
+ double efvf = ef * vf * kinFacV;
+ double vaf2 = vf * vf * kinFacV + af * af * kinFacA;
+ double efvpf = ef * vpf * kinFacV;
+ double vafvapf = vf * vpf * kinFacV + af * apf * kinFacA;
+ double vapf2 = vpf * vpf * kinFacV + apf * apf * kinFacA;
+
+ // Relative outwidths: combine instate, propagator and outstate.
+ widNow = gamNorm * ef2 + gamZNorm * efvf + ZNorm * vaf2
+ + gamZpNorm * efvpf + ZZpNorm * vafvapf + ZpNorm * vapf2;
+ if (id1Abs < 7) widNow *= colQ;
+
+ // Contribution from Z'0 -> W^+ W^-.
+ } else if (id1Abs == 24) {
+ widNow = ZpNorm * pow2(coupZpWW * cos2tW) * pow3(ps)
+ * (1. + mr1*mr1 + mr2*mr2 + 10. * (mr1 + mr2 + mr1 * mr2));
+ }
+ }
+
+}
+
+//**************************************************************************
+
+// The ResonanceWprime class.
+// Derived class for W'+- properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceWprime::initConstants() {
+
+ // Locally stored properties and couplings.
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+ cos2tW = CoupEW::cos2thetaW();
+
+ // Axial and vector couplings of fermions.
+ aqWp = Settings::parm("Wprime:aq");
+ vqWp = Settings::parm("Wprime:vq");
+ alWp = Settings::parm("Wprime:al");
+ vlWp = Settings::parm("Wprime:vl");
+
+ // Coupling for W' -> W Z.
+ coupWpWZ = Settings::parm("Wprime:coup2WZ");
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceWprime::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * mHat;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceWprime::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // Decay to quarks involves colour factor and CKM matrix.
+ if (id1Abs > 0 && id1Abs < 7) widNow
+ = preFac * ps * 0.5 * (aqWp*aqWp + vqWp * vqWp)
+ * (1. - 0.5 * (mr1 + mr2) - 0.5 * pow2(mr1 - mr2))
+ * colQ * VCKM::V2id(id1Abs, id2Abs);
+
+ // Decay to leptons simpler.
+ else if (id1Abs > 10 && id1Abs < 17) widNow
+ = preFac * ps * 0.5 * (alWp*aqWp + vlWp * vqWp)
+ * (1. - 0.5 * (mr1 + mr2) - 0.5 * pow2(mr1 - mr2));
+
+ // Decay to W^+- Z^0.
+ else if (id1Abs == 24 && id2Abs == 23) widNow
+ = preFac * 0.25 * pow2(coupWpWZ) * cos2tW * (mr1 / mr2) * pow3(ps)
+ * (1. + mr1*mr1 + mr2*mr2 + 10. * (mr1 + mr2 + mr1 * mr2));
+
+}
+
+//**************************************************************************
+
+// The ResonanceRhorizontal class.
+// Derived class for R^0 (horizontal gauge boson) properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceRhorizontal::initConstants() {
+
+ // Locally stored properties and couplings.
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceRhorizontal::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * mHat;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceRhorizontal::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // R -> f fbar. Colour factor for quarks.
+ widNow = preFac * ps * (2. - mr1 - mr2 - pow2(mr1 - mr2));
+ if (id1Abs < 9) widNow *= colQ;
+
+}
+
+//**************************************************************************
+
+// The ResonanceExcited class.
+// Derived class for excited-fermion properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceExcited::initConstants() {
+
+ // Locally stored properties and couplings.
+ Lambda = Settings::parm("ExcitedFermion:Lambda");
+ coupF = Settings::parm("ExcitedFermion:coupF");
+ coupFprime = Settings::parm("ExcitedFermion:coupFprime");
+ coupFcol = Settings::parm("ExcitedFermion:coupFcol");
+ sin2tW = CoupEW::sin2thetaW();
+ cos2tW = 1. - sin2tW;
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceExcited::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ preFac = pow3(mHat) / pow2(Lambda);
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceExcited::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // f^* -> f g.
+ if (id1Abs == 21) widNow = preFac * alpS * pow2(coupFcol) / 3.;
+
+ // f^* -> f gamma.
+ else if (id1Abs == 22) {
+ double chgI3 = (id2Abs%2 == 0) ? 0.5 : -0.5;
+ double chgY = (id2Abs < 9) ? 1. / 6. : -0.5;
+ double chg = chgI3 * coupF + chgY * coupFprime;
+ widNow = preFac * alpEM * pow2(chg) / 4.;
+ }
+
+ // f^* -> f Z^0.
+ else if (id1Abs == 23) {
+ double chgI3 = (id2Abs%2 == 0) ? 0.5 : -0.5;
+ double chgY = (id2Abs < 9) ? 1. / 6. : -0.5;
+ double chg = chgI3 * cos2tW * coupF - chgY * sin2tW * coupFprime;
+ widNow = preFac * (alpEM * pow2(chg) / (8. * sin2tW * cos2tW))
+ * ps*ps * (2. + mr1);
+ }
+
+ // f^* -> f' W^+-.
+ else if (id1Abs == 24) widNow = preFac * (alpEM * pow2(coupF)
+ / (16. * sin2tW)) * ps*ps * (2. + mr1);
+
+}
+
+//**************************************************************************
+
+// The ResonanceGraviton class.
+// Derived class for excited Graviton properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceGraviton::initConstants() {
+
+ // Locally stored properties and couplings: kappa * m_G*.
+ kappaMG = Settings::parm("ExtraDimensionsG*:kappaMG");
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceGraviton::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = pow2(kappaMG) * mHat / M_PI;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceGraviton::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // Widths to fermion pairs.
+ if (id1Abs < 19) {
+ widNow = preFac * pow3(ps) * (1. + 8. * mr1 / 3.) / 320.;
+ if (id1Abs < 9) widNow *= colQ;
+ }
+
+ // Widths to gluon and photon pair.
+ else if (id1Abs == 21) widNow = preFac / 20.;
+ else if (id1Abs == 22) widNow = preFac / 160.;
+
+ // Widths to Z0 Z0 and W+ W- pair.
+ else if (id1Abs == 23 || id1Abs == 24) {
+ widNow = preFac * ps * (13. / 12. + 14. * mr1 / 3. + 4. * mr1 * mr1)
+ / 80.;
+ if (id1Abs == 23) widNow *= 0.5;
+ }
+
+}
+
+//**************************************************************************
+
+// The ResonanceLeptoquark class.
+// Derived class for leptoquark properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceLeptoquark::initConstants() {
+
+ // Locally stored properties and couplings.
+ kCoup = Settings::parm("LeptoQuark:kCoup");
+
+ // Check that flavour info in decay channel is correctly set.
+ int id1Now = particlePtr->decay[0].product(0);
+ int id2Now = particlePtr->decay[0].product(1);
+ if (id1Now < 1 || id1Now > 5) {
+ infoPtr->errorMsg("Error in ResonanceLeptoquark::init:"
+ " unallowed input quark flavour reset to u");
+ id1Now = 2;
+ particlePtr->decay[0].product(0, id1Now);
+ }
+ if (abs(id2Now) < 11 || abs(id2Now) > 16) {
+ infoPtr->errorMsg("Error in ResonanceLeptoquark::init:"
+ " unallowed input lepton flavour reset to e-");
+ id2Now = 11;
+ particlePtr->decay[0].product(1, id2Now);
+ }
+
+ // Set/overwrite charge and name of particle.
+ bool changed = particlePtr->hasChanged();
+ int chargeLQ = ParticleDataTable::chargeType(id1Now)
+ + ParticleDataTable::chargeType(id2Now);
+ particlePtr->setChargeType(chargeLQ);
+ string nameLQ = "LQ_" + ParticleDataTable::name(id1Now) + ","
+ + ParticleDataTable::name(id2Now);
+ particlePtr->setNames(nameLQ, nameLQ + "bar");
+ if (!changed) particlePtr->setHasChanged(false);
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceLeptoquark::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ preFac = 0.25 * alpEM * kCoup * mHat;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceLeptoquark::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // Width into lepton plus quark.
+ if (id1Abs > 10 && id1Abs < 17 && id2Abs < 7) widNow = preFac * pow3(ps);
+
+}
+
+//**************************************************************************
+
+// The ResonanceNuRight class.
+// Derived class for righthanded Majorana neutrino properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceNuRight::initConstants() {
+
+ // Locally stored properties and couplings: righthanded W mass.
+ thetaWRat = 1. / (768. * M_PI * pow2(CoupEW::sin2thetaW()));
+ mWR = ParticleDataTable::m0(9900024);
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceNuRight::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = pow2(alpEM) * thetaWRat * pow5(mHat) / pow4(max(mHat, mWR));
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceNuRight::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (mHat < mf1 + mf2 + mf3 + MASSMARGIN) return;
+
+ // Coupling part of widths to l- q qbar', l- l'+ nu_lR' and c.c.
+ widNow = (id2Abs < 9 && id3Abs < 9)
+ ? preFac * colQ * VCKM::V2id(id2, id3) : preFac;
+
+ // Phase space corrections in decay. Must have y < 1.
+ double x = (mf1 + mf2 + mf3) / mHat;
+ double x2 = x * x;
+ double fx = 1. - 8. * x2 + 8. * pow3(x2) - pow4(x2)
+ - 24. * pow2(x2) * log(x);
+ double y = min( 0.999, pow2(mHat / mWR) );
+ double fy = ( 12. * (1. - y) * log(1. - y) + 12. * y - 6. * y*y
+ - 2.* pow3(y) ) / pow4(y);
+ widNow *= fx * fy;
+
+}
+
+//**************************************************************************
+
+// The ResonanceZRight class.
+// Derived class for Z_R^0 properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceZRight::initConstants() {
+
+ // Locally stored properties and couplings: righthanded W mass.
+ sin2tW = CoupEW::sin2thetaW();
+ thetaWRat = 1. / (48. * sin2tW * (1. - sin2tW) * (1. - 2. * sin2tW) );
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceZRight::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * mHat;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceZRight::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // Couplings to q qbar and l+ l-.
+ double vf = 0.;
+ double af = 0.;
+ double symMaj = 1.;
+ if (id1Abs < 9 && id1Abs%2 == 1) {
+ af = -1. + 2. * sin2tW;
+ vf = -1. + 4. * sin2tW / 3.;
+ } else if (id1Abs < 9) {
+ af = 1. - 2. * sin2tW;
+ vf = 1. - 8. * sin2tW / 3.;
+ } else if (id1Abs < 19 && id1Abs%2 == 1) {
+ af = -1. + 2. * sin2tW;
+ vf = -1. + 4. * sin2tW;
+
+ // Couplings to nu_L nu_Lbar and nu_R nu_Rbar, both assumed Majoranas.
+ } else if (id1Abs < 19) {
+ af = -2. * sin2tW;
+ vf = 0.;
+ symMaj = 0.5;
+ } else {
+ af = 2. * (1. - sin2tW);
+ vf = 0.;
+ symMaj = 0.5;
+ }
+
+ // Width expression, including phase space and colour factor.
+ widNow = preFac * (vf*vf * (1. + 2. * mr1) + af*af * ps*ps) * ps
+ * symMaj;
+ if (id1Abs < 9) widNow *= colQ;
+
+}
+
+//**************************************************************************
+
+// The ResonanceWRight class.
+// Derived class for W_R+- properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceWRight::initConstants() {
+
+ // Locally stored properties and couplings.
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceWRight::calcPreFac(bool) {
+
+ // Common coupling factors.
+ alpEM = alphaEM.alphaEM(mHat * mHat);
+ alpS = alphaS.alphaS(mHat * mHat);
+ colQ = 3. * (1. + alpS / M_PI);
+ preFac = alpEM * thetaWRat * mHat;
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceWRight::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // Combine kinematics with colour factor and CKM couplings.
+ widNow = preFac * (1. - 0.5 * (mr1 + mr2) - 0.5 * pow2(mr1 - mr2))
+ * ps;
+ if (id1Abs < 9) widNow *= colQ * VCKM::V2id(id1Abs, id2Abs);
+
+}
+
+//**************************************************************************
+
+// The ResonanceHchgchgLeft class.
+// Derived class for H++/H-- (left) properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceHchgchgLeft::initConstants() {
+
+ // Read in Yukawa matrix for couplings to a lepton pair.
+ yukawa[1][1] = Settings::parm("LeftRightSymmmetry:coupHee");
+ yukawa[2][1] = Settings::parm("LeftRightSymmmetry:coupHmue");
+ yukawa[2][2] = Settings::parm("LeftRightSymmmetry:coupHmumu");
+ yukawa[3][1] = Settings::parm("LeftRightSymmmetry:coupHtaue");
+ yukawa[3][2] = Settings::parm("LeftRightSymmmetry:coupHtaumu");
+ yukawa[3][3] = Settings::parm("LeftRightSymmmetry:coupHtautau");
+
+ // Locally stored properties and couplings.
+ gL = Settings::parm("LeftRightSymmmetry:gL");
+ vL = Settings::parm("LeftRightSymmmetry:vL");
+ mW = ParticleDataTable::m0(24);
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceHchgchgLeft::calcPreFac(bool) {
+
+ // Common coupling factors.
+ preFac = mHat / (8. * M_PI);
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceHchgchgLeft::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // H++-- width to a pair of leptons. Combinatorial factor of 2.
+ if (id1Abs < 17 && id2Abs < 17) {
+ widNow = preFac * pow2(yukawa[(id1Abs-9)/2][(id2Abs-9)/2]) * ps;
+ if (id2Abs != id1Abs) widNow *= 2.;
+ }
+
+ // H++-- width to a pair of lefthanded W's.
+ else if (id1Abs == 24 && id2Abs == 24)
+ widNow = preFac * 0.5 * pow2(gL*gL * vL / mW)
+ * (3. * mr1 + 0.25 / mr1 - 1.) * ps;
+
+}
+
+//**************************************************************************
+
+// The ResonanceHchgchgRight class.
+// Derived class for H++/H-- (right) properties.
+
+//*********
+
+// Initialize constants.
+
+void ResonanceHchgchgRight::initConstants() {
+
+ // Read in Yukawa matrix for couplings to a lepton pair.
+ yukawa[1][1] = Settings::parm("LeftRightSymmmetry:coupHee");
+ yukawa[2][1] = Settings::parm("LeftRightSymmmetry:coupHmue");
+ yukawa[2][2] = Settings::parm("LeftRightSymmmetry:coupHmumu");
+ yukawa[3][1] = Settings::parm("LeftRightSymmmetry:coupHtaue");
+ yukawa[3][2] = Settings::parm("LeftRightSymmmetry:coupHtaumu");
+ yukawa[3][3] = Settings::parm("LeftRightSymmmetry:coupHtautau");
+
+ // Locally stored properties and couplings.
+ idWR = 9000024;
+ gR = Settings::parm("LeftRightSymmmetry:gR");
+
+}
+
+//*********
+
+// Calculate various common prefactors for the current mass.
+
+void ResonanceHchgchgRight::calcPreFac(bool) {
+
+ // Common coupling factors.
+ preFac = mHat / (8. * M_PI);
+
+}
+
+//*********
+
+// Calculate width for currently considered channel.
+
+void ResonanceHchgchgRight::calcWidth(bool) {
+
+ // Check that above threshold.
+ if (ps == 0.) return;
+
+ // H++-- width to a pair of leptons. Combinatorial factor of 2.
+ if (id1Abs < 17 && id2Abs < 17) {
+ widNow = preFac * pow2(yukawa[(id1Abs-9)/2][(id2Abs-9)/2]) * ps;
+ if (id2Abs != id1Abs) widNow *= 2.;
+ }
+
+ // H++-- width to a pair of lefthanded W's.
+ else if (id1Abs == idWR && id2Abs == idWR)
+ widNow = preFac * pow2(yukawa[(id1Abs-9)/2][(id2Abs-9)/2]) * ps;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// Settings.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the Settings class.
+
+#include "Settings.h"
+
+// Allow string and character manipulation.
+#include <cctype>
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Settings class.
+// This class contains flags, modes, parms and words used in generation.
+
+//*********
+
+// Definitions of static variables.
+map<string, Flag> Settings::flags;
+map<string, Mode> Settings::modes;
+map<string, Parm> Settings::parms;
+map<string, Word> Settings::words;
+bool Settings::isInit = false;
+
+// Static copy of Info - not optimal solution??
+Info* Settings::infoPtr = 0;
+
+//*********
+
+// Read in database from specific file.
+
+bool Settings::init(string startFile, bool append, ostream& os) {
+
+ // Don't initialize if it has already been done and not in append mode.
+ if (isInit && !append) return true;
+ int nError = 0;
+
+ // List of files to be checked. Start with input file.
+ vector<string> files;
+ files.push_back(startFile);
+
+ // If nontrivial startfile path, then use that for other files as well.
+ string pathName = "";
+ if (startFile.rfind("/") != string::npos)
+ pathName = startFile.substr(0, startFile.rfind("/") + 1);
+
+ // Loop over files. Open them for read.
+ for (int i = 0; i < int(files.size()); ++i) {
+ const char* cstring = files[i].c_str();
+ ifstream is(cstring);
+
+ // Check that instream is OK.
+ if (!is) {
+ os << "\n PYTHIA Error: settings file " << files[i]
+ << " not found" << endl;
+ return false;
+ }
+
+ // Read in one line at a time.
+ string line;
+ while ( getline(is, line) ) {
+
+ // Get first word of a line, to interpret it as tag.
+ istringstream getfirst(line);
+ string tag;
+ getfirst >> tag;
+
+ // Skip ahead if not interesting. Only look for new files in startfile.
+ if (tag != "<flag" && tag != "<flagfix" && tag != "<mode"
+ && tag != "<modeopen" && tag != "<modepick" && tag != "<modefix"
+ && tag != "<parm" && tag != "<parmfix" && tag != "<word"
+ && tag != "<wordfix" && tag != "<aidx") continue;
+
+ // Read and append continuation line(s) if line does not contain >.
+ while (line.find(">") == string::npos) {
+ string addLine;
+ getline(is, addLine);
+ line += " " + addLine;
+ }
+
+ // Remove extra blanks before an = sign.
+ while (line.find(" =") != string::npos) line.erase( line.find(" ="), 1);
+
+ // Add file also to be read.
+ if (tag == "<aidx") {
+ string name = attributeValue( line, "href");
+ if (name == "") {
+ os << " PYTHIA Error: failed to find name attribute in line "
+ << line << endl;
+ ++nError;
+ continue;
+ }
+ files.push_back(pathName + name + ".xml");
+ continue;
+ }
+
+ // Find name attribute.
+ string name = attributeValue( line, "name=");
+ if (name == "") {
+ os << " PYTHIA Error: failed to find name attribute in line "
+ << line << endl;
+ ++nError;
+ continue;
+ }
+
+ // Check that default value attribute present, and whether max and min.
+ if (line.find("default=") == string::npos) {
+ os << " PYTHIA Error: failed to find default value token in line "
+ << line << endl;
+ ++nError;
+ continue;
+ }
+ bool hasMin = (line.find("min=") != string::npos);
+ bool hasMax = (line.find("max=") != string::npos);
+
+ // Check for occurence of a bool and add to flag map.
+ if (tag == "<flag" || tag == "<flagfix") {
+ bool value = boolAttributeValue( line, "default=");
+ addFlag( name, value);
+
+ // Check for occurence of an int and add to mode map.
+ } else if (tag == "<mode" || tag == "<modeopen"
+ || tag == "<modepick" || tag == "<modefix") {
+ int value = intAttributeValue( line, "default=");
+ int minVal = intAttributeValue( line, "min=");
+ int maxVal = intAttributeValue( line, "max=");
+ addMode( name, value, hasMin, hasMax, minVal, maxVal);
+
+ // Check for occurence of a double and add to parm map.
+ } else if (tag == "<parm" || tag == "<parmfix") {
+ double value = doubleAttributeValue( line, "default=");
+ double minVal = doubleAttributeValue( line, "min=");
+ double maxVal = doubleAttributeValue( line, "max=");
+ addParm( name, value, hasMin, hasMax, minVal, maxVal);
+
+ // Check for occurence of a string and add to word map.
+ } else if (tag == "<word" || tag == "<wordfix") {
+ string value = attributeValue( line, "default=");
+ addWord( name, value);
+ }
+
+ // End of loop over lines in input file and loop over files.
+ };
+ };
+
+ // Done.
+ if (nError > 0) return false;
+ isInit = true;
+ return true;
+
+}
+
+//*********
+
+// Overwrite existing database by reading from specific file.
+
+bool Settings::reInit(string startFile) {
+
+ // Reset maps to empty.
+ flags.clear();
+ modes.clear();
+ parms.clear();
+ words.clear();
+
+ // Then let normal init do the rest.
+ isInit = false;
+ return init(startFile);
+
+}
+
+//*********
+
+// Read in updates from a character string, like a line of a file.
+// Is used by readString (and readFile) in Pythia.
+
+bool Settings::readString(string line, bool warn, ostream& os) {
+
+ // If empty line then done.
+ if (line.find_first_not_of(" ") == string::npos) return true;
+
+ // If first character is not a letter, then taken to be a comment line.
+ string lineNow = line;
+ int firstChar = lineNow.find_first_not_of(" ");
+ if (!isalpha(lineNow[firstChar])) return true;
+
+ // Replace an equal sign by a blank to make parsing simpler.
+ while (lineNow.find("=") != string::npos) {
+ int firstEqual = lineNow.find_first_of("=");
+ lineNow.replace(firstEqual, 1, " ");
+ }
+
+ // Get first word of a line.
+ istringstream splitLine(lineNow);
+ string name;
+ splitLine >> name;
+
+ // Replace two colons by one (:: -> :) to allow for such mistakes.
+ while (name.find("::") != string::npos) {
+ int firstColonColon = name.find_first_of("::");
+ name.replace(firstColonColon, 2, ":");
+ }
+
+ // Check whether this is in the database. Done if not.
+ int inDataBase = 0;
+ if (isFlag(name)) inDataBase = 1;
+ else if (isMode(name)) inDataBase = 2;
+ else if (isParm(name)) inDataBase = 3;
+ else if (isWord(name)) inDataBase = 4;
+ if (inDataBase == 0) {
+ if (warn) os << "\n PYTHIA Warning: input string not found in settings"
+ << " databases; skip:\n " << line << endl;
+ return false;
+ }
+
+ // Find value. Warn if none found.
+ string valueString;
+ splitLine >> valueString;
+ if (!splitLine) {
+ if (warn) os << "\n PYTHIA Warning: variable recognized, but its value"
+ << " not meaningful; skip:\n " << line << endl;
+ return false;
+ }
+
+ // Update flag map; allow many ways to say yes.
+ if (inDataBase == 1) {
+ bool value = boolString(valueString);
+ flag(name, value);
+
+ // Update mode map.
+ } else if (inDataBase == 2) {
+ istringstream modeData(valueString);
+ int value;
+ modeData >> value;
+ if (!modeData) {
+ if (warn) os << "\n PYTHIA Warning: variable recognized, but its value"
+ << " not meaningful; skip:\n " << line << endl;
+ return false;
+ }
+ mode(name, value);
+
+ // Update parm map.
+ } else if (inDataBase == 3) {
+ istringstream parmData(valueString);
+ double value;
+ parmData >> value;
+ if (!parmData) {
+ if (warn) os << "\n PYTHIA Warning: variable recognized, but its value"
+ << " not meaningful; skip:\n " << line << endl;
+ return false;
+ }
+ parm(name, value);
+
+ // Update word map.
+ } else {
+ word(name, valueString);
+ }
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Write updates or everything to user-defined file.
+
+bool Settings::writeFile(string toFile, bool writeAll) {
+
+ // Open file for writing.
+ const char* cstring = toFile.c_str();
+ ofstream os(cstring);
+ if (!os) {
+ infoPtr->errorMsg("Error in Settings::writeFile:"
+ " could not open file", toFile);
+ return false;
+ }
+ return writeFile( os, writeAll);
+
+}
+
+//*********
+
+// Write updates or everything to user-defined file.
+
+bool Settings::writeFile(ostream& os, bool writeAll) {
+
+ // Write simple header as comment.
+ if (writeAll) os << "! List of all current PYTHIA ";
+ else os << "! List of all modified PYTHIA ";
+ os << fixed << setprecision(3) << parm("Pythia:versionNumber")
+ << " settings.\n";
+
+ // Iterators for the flag, mode and parm tables.
+ map<string, Flag>::iterator flagEntry = flags.begin();
+ map<string, Mode>::iterator modeEntry = modes.begin();
+ map<string, Parm>::iterator parmEntry = parms.begin();
+ map<string, Word>::iterator wordEntry = words.begin();
+
+ // Loop while there is something left to do.
+ while (flagEntry != flags.end() || modeEntry != modes.end()
+ || parmEntry != parms.end() || wordEntry != words.end()) {
+
+ // Check if a flag is next in lexigraphical order; if so print it.
+ if ( flagEntry != flags.end()
+ && ( modeEntry == modes.end() || flagEntry->first < modeEntry->first )
+ && ( parmEntry == parms.end() || flagEntry->first < parmEntry->first )
+ && ( wordEntry == words.end() || flagEntry->first < wordEntry->first )
+ ) {
+ string state[2] = {"off", "on"};
+ bool valNow = flagEntry->second.valNow;
+ bool valDefault = flagEntry->second.valDefault;
+ if ( writeAll || valNow != valDefault )
+ os << flagEntry->second.name << " = " << state[valNow] << "\n";
+ ++flagEntry;
+
+ // Else check if mode is next, and if so print it.
+ } else if ( modeEntry != modes.end()
+ && ( parmEntry == parms.end() || modeEntry->first < parmEntry->first )
+ && ( wordEntry == words.end() || modeEntry->first < wordEntry->first )
+ ) {
+ int valNow = modeEntry->second.valNow;
+ int valDefault = modeEntry->second.valDefault;
+ if ( writeAll || valNow != valDefault )
+ os << modeEntry->second.name << " = " << valNow << "\n";
+ ++modeEntry;
+
+ // Else check if parm is next, and if so print it;
+ // fixed or scientific depending on value.
+ } else if ( parmEntry != parms.end()
+ && ( wordEntry == words.end() || parmEntry->first < wordEntry->first )
+ ) {
+ double valNow = parmEntry->second.valNow;
+ double valDefault = parmEntry->second.valDefault;
+ if ( writeAll || valNow != valDefault ) {
+ os << parmEntry->second.name << " = ";
+ if ( valNow == 0. ) os << fixed << setprecision(1);
+ else if ( abs(valNow) < 0.001 ) os << scientific << setprecision(4);
+ else if ( abs(valNow) < 0.1 ) os << fixed << setprecision(7);
+ else if ( abs(valNow) < 1000. ) os << fixed << setprecision(5);
+ else if ( abs(valNow) < 1000000. ) os << fixed << setprecision(3);
+ else os << scientific << setprecision(4);
+ os << valNow << "\n";
+ }
+ ++parmEntry;
+
+ // Else print word.
+ } else {
+ string valNow = wordEntry->second.valNow;
+ string valDefault = wordEntry->second.valDefault;
+ if ( writeAll || valNow != valDefault )
+ os << wordEntry->second.name << " = " << valNow << "\n";
+ ++wordEntry;
+ }
+ } ;
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Print out table of database in lexigraphical order.
+
+void Settings::list(bool listAll, bool listString, string match,
+ ostream& os) {
+
+ // Table header; output for bool as off/on.
+ if (listAll)
+ os << "\n *------- PYTHIA Flag + Mode + Parm + Word Settings (all) "
+ << " -------------------------------------------------------* \n";
+ else if (!listString)
+ os << "\n *------- PYTHIA Flag + Mode + Parm + Word Settings (chang"
+ << "es only) ----------------------------------------------* \n" ;
+ else
+ os << "\n *------- PYTHIA Flag + Mode + Parm + Word Settings (with "
+ << "requested string) -------------------------------------* \n" ;
+ os << " | "
+ << " | \n"
+ << " | Name | "
+ << " Now | Default Min Max | \n"
+ << " | | "
+ << " | | \n";
+
+ // Convert input string to lowercase for match.
+ match = toLower(match);
+ if (match == "") match = " ";
+
+ // Iterators for the flag, mode and parm tables.
+ map<string, Flag>::iterator flagEntry = flags.begin();
+ map<string, Mode>::iterator modeEntry = modes.begin();
+ map<string, Parm>::iterator parmEntry = parms.begin();
+ map<string, Word>::iterator wordEntry = words.begin();
+
+ // Loop while there is something left to do.
+ while (flagEntry != flags.end() || modeEntry != modes.end()
+ || parmEntry != parms.end() || wordEntry != words.end()) {
+
+ // Check if a flag is next in lexigraphical order; if so print it.
+ if ( flagEntry != flags.end()
+ && ( modeEntry == modes.end() || flagEntry->first < modeEntry->first )
+ && ( parmEntry == parms.end() || flagEntry->first < parmEntry->first )
+ && ( wordEntry == words.end() || flagEntry->first < wordEntry->first )
+ ) {
+ string state[2] = {"off", "on"};
+ bool valNow = flagEntry->second.valNow;
+ bool valDefault = flagEntry->second.valDefault;
+ if ( listAll || (!listString && valNow != valDefault)
+ || (listString && flagEntry->first.find(match) != string::npos) )
+ os << " | " << setw(45) << left
+ << flagEntry->second.name << " | " << setw(24) << right
+ << state[valNow] << " | " << setw(12) << state[valDefault]
+ << " | \n";
+ ++flagEntry;
+
+ // Else check if mode is next, and if so print it.
+ } else if ( modeEntry != modes.end()
+ && ( parmEntry == parms.end() || modeEntry->first < parmEntry->first )
+ && ( wordEntry == words.end() || modeEntry->first < wordEntry->first )
+ ) {
+ int valNow = modeEntry->second.valNow;
+ int valDefault = modeEntry->second.valDefault;
+ if ( listAll || (!listString && valNow != valDefault)
+ || (listString && modeEntry->first.find(match) != string::npos) ) {
+ os << " | " << setw(45) << left
+ << modeEntry->second.name << " | " << setw(24) << right
+ << valNow << " | " << setw(12) << valDefault;
+ if (modeEntry->second.hasMin)
+ os << setw(12) << modeEntry->second.valMin;
+ else os << " ";
+ if (modeEntry->second.hasMax)
+ os << setw(12) << modeEntry->second.valMax;
+ else os << " ";
+ os << " | \n";
+ }
+ ++modeEntry;
+
+ // Else check if parm is next, and if so print it;
+ // fixed or scientific depending on value.
+ } else if ( parmEntry != parms.end()
+ && ( wordEntry == words.end() || parmEntry->first < wordEntry->first )
+ ) {
+ double valNow = parmEntry->second.valNow;
+ double valDefault = parmEntry->second.valDefault;
+ if ( listAll || (!listString && valNow != valDefault )
+ || (listString && parmEntry->first.find(match) != string::npos) ) {
+ os << " | " << setw(45) << left
+ << parmEntry->second.name << right << " | ";
+ for (int i = 0; i < 4; ++i) {
+ if (i == 1) valNow = valDefault;
+ if (i == 2) valNow = parmEntry->second.valMin;
+ if (i == 3) valNow = parmEntry->second.valMax;
+ if ( (i == 2 && !parmEntry->second.hasMin)
+ || (i == 3 && !parmEntry->second.hasMax) )
+ os << " ";
+ else if ( valNow == 0. )
+ os << fixed << setprecision(1) << setw(12) << valNow;
+ else if ( abs(valNow) < 0.001 )
+ os << scientific << setprecision(4) << setw(12) << valNow;
+ else if ( abs(valNow) < 0.1 )
+ os << fixed << setprecision(7) << setw(12) << valNow;
+ else if ( abs(valNow) < 1000. )
+ os << fixed << setprecision(5) << setw(12) << valNow;
+ else if ( abs(valNow) < 1000000. )
+ os << fixed << setprecision(3) << setw(12) << valNow;
+ else
+ os << scientific << setprecision(4) << setw(12) << valNow;
+ if (i == 0) os << " | ";
+ }
+ os << " | \n";
+ }
+ ++parmEntry;
+
+ // Else print word.
+ } else {
+ string valNow = wordEntry->second.valNow;
+ string valDefault = wordEntry->second.valDefault;
+ int blankLeft = max(0, 60 - max(24, int(valNow.length()) )
+ - max(12, int(valDefault.length()) ) );
+ string blankPad( blankLeft, ' ');
+ if ( listAll || (!listString && valNow != valDefault)
+ || (listString && wordEntry->first.find(match) != string::npos) )
+ os << " | " << setw(45) << left
+ << wordEntry->second.name << " | " << setw(24) << right
+ << valNow << " | " << setw(12) << valDefault << blankPad
+ << " | \n";
+ ++wordEntry;
+ }
+ } ;
+
+ // End of loop over database contents.
+ os << " | "
+ << " | \n"
+ << " *------- End PYTHIA Flag + Mode + Parm + Word Settings ---"
+ << "------------------------------------------------------* " << endl;
+
+}
+
+//*********
+
+// Reset all values to their defaults.
+
+void Settings::resetAll() {
+
+ // Loop through the flags table, resetting all entries.
+ for (map<string, Flag>::iterator flagEntry = flags.begin();
+ flagEntry != flags.end(); ++flagEntry) {
+ string name = flagEntry->first;
+ resetFlag(name);
+ }
+
+ // Loop through the modes table, resetting all entries.
+ for (map<string, Mode>::iterator modeEntry = modes.begin();
+ modeEntry != modes.end(); ++modeEntry) {
+ string name = modeEntry->first;
+ resetMode(name);
+ }
+
+ // Loop through the parms table, resetting all entries.
+ for (map<string, Parm>::iterator parmEntry = parms.begin();
+ parmEntry != parms.end(); ++parmEntry) {
+ string name = parmEntry->first;
+ resetParm(name);
+ }
+
+ // Loop through the words table, resetting all entries.
+ for (map<string, Word>::iterator wordEntry = words.begin();
+ wordEntry != words.end(); ++wordEntry) {
+ string name = wordEntry->first;
+ resetWord(name);
+ }
+
+}
+
+//*********
+
+// Give back current value, with check that key exists.
+
+bool Settings::flag(string keyIn) {
+ if (isFlag(keyIn)) return flags[toLower(keyIn)].valNow;
+ infoPtr->errorMsg("Error in Settings::flag: unknown key", keyIn);
+ return false;
+}
+
+int Settings::mode(string keyIn) {
+ if (isMode(keyIn)) return modes[toLower(keyIn)].valNow;
+ infoPtr->errorMsg("Error in Settings::mode: unknown key", keyIn);
+ return 0;
+}
+
+double Settings::parm(string keyIn) {
+ if (isParm(keyIn)) return parms[toLower(keyIn)].valNow;
+ infoPtr->errorMsg("Error in Settings::parm: unknown key", keyIn);
+ return 0.;
+}
+
+string Settings::word(string keyIn) {
+ if (isWord(keyIn)) return words[toLower(keyIn)].valNow;
+ infoPtr->errorMsg("Error in Settings::word: unknown key", keyIn);
+ return " ";
+}
+
+//*********
+
+// Change current value, respecting limits.
+
+void Settings::flag(string keyIn, bool nowIn) {
+ if (isFlag(keyIn)) flags[toLower(keyIn)].valNow = nowIn;
+}
+
+void Settings:: mode(string keyIn, int nowIn) {
+ if (isMode(keyIn)) {
+ Mode& modeNow = modes[toLower(keyIn)];
+ if (modeNow.hasMin && nowIn < modeNow.valMin)
+ modeNow.valNow = modeNow.valMin;
+ else if (modeNow.hasMax && nowIn > modeNow.valMax)
+ modeNow.valNow = modeNow.valMax;
+ else modeNow.valNow = nowIn;
+ }
+}
+
+void Settings::parm(string keyIn, double nowIn) {
+ if (isParm(keyIn)) {
+ Parm& parmNow = parms[toLower(keyIn)];
+ if (parmNow.hasMin && nowIn < parmNow.valMin)
+ parmNow.valNow = parmNow.valMin;
+ else if (parmNow.hasMax && nowIn > parmNow.valMax)
+ parmNow.valNow = parmNow.valMax;
+ else parmNow.valNow = nowIn;
+ }
+}
+
+void Settings::word(string keyIn, string nowIn) {
+ if (isWord(keyIn)) words[toLower(keyIn)].valNow = nowIn;
+}
+
+//*********
+
+// Convert string to lowercase for case-insensitive comparisons.
+// Also remove initial and trailing blanks, if any.
+
+string Settings::toLower(const string& name) {
+
+ // Copy string without initial and trailing blanks.
+ if (name.find_first_not_of(" ") == string::npos) return "";
+ int firstChar = name.find_first_not_of(" ");
+ int lastChar = name.find_last_not_of(" ");
+ string temp = name.substr( firstChar, lastChar + 1 - firstChar);
+
+ // Convert to lowercase letter by letter.
+ for (int i = 0; i < int(temp.length()); ++i)
+ temp[i] = std::tolower(temp[i]);
+ return temp;
+
+}
+
+//*********
+
+// Allow several alternative inputs for true/false.
+
+bool Settings::boolString(string tag) {
+
+ string tagLow = toLower(tag);
+ return ( tagLow == "true" || tagLow == "1" || tagLow == "on"
+ || tagLow == "yes" || tagLow == "ok" );
+
+}
+
+//*********
+
+// Extract XML value string following XML attribute.
+
+string Settings::attributeValue(string line, string attribute) {
+
+ if (line.find(attribute) == string::npos) return "";
+ int iBegAttri = line.find(attribute);
+ int iBegQuote = line.find("\"", iBegAttri + 1);
+ int iEndQuote = line.find("\"", iBegQuote + 1);
+ return line.substr(iBegQuote + 1, iEndQuote - iBegQuote - 1);
+
+}
+
+//*********
+
+// Extract XML bool value following XML attribute.
+
+bool Settings::boolAttributeValue(string line, string attribute) {
+
+ string valString = attributeValue(line, attribute);
+ if (valString == "") return false;
+ return boolString(valString);
+
+}
+
+//*********
+
+// Extract XML int value following XML attribute.
+
+int Settings::intAttributeValue(string line, string attribute) {
+ string valString = attributeValue(line, attribute);
+ if (valString == "") return 0;
+ istringstream valStream(valString);
+ int intVal;
+ valStream >> intVal;
+ return intVal;
+
+}
+
+//*********
+
+// Extract XML double value following XML attribute.
+
+double Settings::doubleAttributeValue(string line, string attribute) {
+ string valString = attributeValue(line, attribute);
+ if (valString == "") return 0.;
+ istringstream valStream(valString);
+ double doubleVal;
+ valStream >> doubleVal;
+ return doubleVal;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaCompositeness.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// compositeness simulation classes.
+
+#include "SigmaCompositeness.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma1qg2qStar class.
+// Cross section for q g -> q^* (excited quark state).
+// Note: for simplicity decay is assumed isotropic.
+
+//*********
+
+// Initialize process.
+
+void Sigma1qg2qStar::initProc() {
+
+ // Set up process properties from the chosen quark flavour.
+ idRes = 4000000 + idq;
+ codeSave = 4000 + idq;
+ if (idq == 1) nameSave = "d g -> d^*";
+ else if (idq == 2) nameSave = "u g -> u^*";
+ else if (idq == 3) nameSave = "s g -> s^*";
+ else if (idq == 4) nameSave = "c g -> c^*";
+ else nameSave = "b g -> b^*";
+
+ // Store q* mass and width for propagator.
+ mRes = ParticleDataTable::m0(idRes);
+ GammaRes = ParticleDataTable::mWidth(idRes);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Locally stored properties and couplings.
+ Lambda = Settings::parm("ExcitedFermion:Lambda");
+ coupFcol = Settings::parm("ExcitedFermion:coupFcol");
+
+ // Set pointer to particle properties and decay table.
+ qStarPtr = ParticleDataTable::particleDataPtr(idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1qg2qStar::sigmaKin() {
+
+ // Incoming width for correct quark.
+ widthIn = pow3(mH) * alpS * pow2(coupFcol) / (3. * pow2(Lambda));
+
+ // Set up Breit-Wigner.
+ sigBW = M_PI/ ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat) for specific incoming flavours.
+
+double Sigma1qg2qStar::sigmaHat() {
+
+ // Identify whether correct incoming flavours.
+ int idqNow = (id2 == 21) ? id1 : id2;
+ if (abs(idqNow) != idq) return 0.;
+
+ // Outgoing width and total sigma. Done.
+ return widthIn * sigBW * qStarPtr->resWidthOpen(idqNow, mH);
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1qg2qStar::setIdColAcol() {
+
+ // Flavours.
+ int idqNow = (id2 == 21) ? id1 : id2;
+ int idqStar = (idqNow > 0) ? idRes : -idRes;
+ setId( id1, id2, idqStar);
+
+ // Colour flow topology.
+ if (id1 == idqNow) setColAcol( 1, 0, 2, 1, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 2, 0);
+ if (idqNow < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for q* decay angle.
+
+double Sigma1qg2qStar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // q* should sit in entry 5. Sequential Z/W decay assumed isotropic.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Sign of asymmetry.
+ int sideIn = (process[3].idAbs() < 20) ? 1 : 2;
+ int sideOut = (process[6].idAbs() < 20) ? 1 : 2;
+ double eps = (sideIn == sideOut) ? 1. : -1.;
+
+ // Phase space factors.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+
+ // Reconstruct decay angle. Default isotropic decay.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+ double wt = 1.;
+ double wtMax = 1.;
+
+ // Decay q* -> q (g/gamma) or q (Z^0/W^+-).
+ int idBoson = (sideOut == 1) ? process[7].idAbs() : process[6].idAbs();
+ if (idBoson == 21 || idBoson == 22) {
+ wt = 1. + eps * cosThe;
+ wtMax = 2.;
+ } else if (idBoson == 23 || idBoson == 24) {
+ double mrB = (sideOut == 1) ? mr2 : mr1;
+ double ratB = (1. - 0.5 * mrB) / (1 + 0.5 * mrB);
+ wt = 1. + eps * cosThe * ratB;
+ wtMax = 1. + ratB;
+ }
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma1lgm2lStar class.
+// Cross section for l gamma -> l^* (excited lepton state).
+// Note: for simplicity decay is assumed isotropic.
+
+//*********
+
+// Initialize process.
+
+void Sigma1lgm2lStar::initProc() {
+
+ // Set up process properties from the chosen lepton flavour.
+ idRes = 4000000 + idl;
+ codeSave = 4000 + idl;
+ if (idl == 11) nameSave = "e gamma -> e^*";
+ else if (idl == 13) nameSave = "mu gamma -> mu^*";
+ else nameSave = "tau gamma -> tau^*";
+
+ // Store l* mass and width for propagator.
+ mRes = ParticleDataTable::m0(idRes);
+ GammaRes = ParticleDataTable::mWidth(idRes);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Locally stored properties and couplings.
+ Lambda = Settings::parm("ExcitedFermion:Lambda");
+ double coupF = Settings::parm("ExcitedFermion:coupF");
+ double coupFp = Settings::parm("ExcitedFermion:coupFprime");
+ coupChg = -0.5 * coupF - 0.5 * coupFp;
+
+ // Set pointer to particle properties and decay table.
+ qStarPtr = ParticleDataTable::particleDataPtr(idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1lgm2lStar::sigmaKin() {
+
+ // Incoming width for correct lepton.
+ widthIn = pow3(mH) * alpEM * pow2(coupChg) / pow2(Lambda);
+
+ // Set up Breit-Wigner.
+ sigBW = M_PI/ ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat) for specific incoming flavours.
+
+double Sigma1lgm2lStar::sigmaHat() {
+
+ // Identify whether correct incoming flavours.
+ int idlNow = (id2 == 22) ? id1 : id2;
+ if (abs(idlNow) != idl) return 0.;
+
+ // Outgoing width and total sigma. Done.
+ return widthIn * sigBW * qStarPtr->resWidthOpen(idlNow, mH);
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1lgm2lStar::setIdColAcol() {
+
+ // Flavours.
+ int idlNow = (id2 == 22) ? id1 : id2;
+ int idlStar = (idlNow > 0) ? idRes : -idRes;
+ setId( id1, id2, idlStar);
+
+ // No colour flow.
+ setColAcol( 0, 0, 0, 0, 0, 0);
+
+}
+
+//*********
+
+// Evaluate weight for l* decay angle.
+
+double Sigma1lgm2lStar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // l* should sit in entry 5. Sequential Z/W decay assumed isotropic.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Sign of asymmetry.
+ int sideIn = (process[3].idAbs() < 20) ? 1 : 2;
+ int sideOut = (process[6].idAbs() < 20) ? 1 : 2;
+ double eps = (sideIn == sideOut) ? 1. : -1.;
+
+ // Phase space factors.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+
+ // Reconstruct decay angle. Default isotropic decay.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+ double wt = 1.;
+ double wtMax = 1.;
+
+ // Decay l* -> l gamma or l (Z^0/W^+-).
+ int idBoson = (sideOut == 1) ? process[7].idAbs() : process[6].idAbs();
+ if (idBoson == 22) {
+ wt = 1. + eps * cosThe;
+ wtMax = 2.;
+ } else if (idBoson == 23 || idBoson == 24) {
+ double mrB = (sideOut == 1) ? mr2 : mr1;
+ double ratB = (1. - 0.5 * mrB) / (1 + 0.5 * mrB);
+ wt = 1. + eps * cosThe * ratB;
+ wtMax = 1. + ratB;
+ }
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma2qq2qStarq class.
+// Cross section for q q' -> q^* q' (excited quark state).
+// Note: for simplicity decay is assumed isotropic.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qq2qStarq::initProc() {
+
+ // Set up process properties from the chosen quark flavour.
+ idRes = 4000000 + idq;
+ codeSave = 4020 + idq;
+ if (idq == 1) nameSave = "q q -> d^* q";
+ else if (idq == 2) nameSave = "q q -> u^* q";
+ else if (idq == 3) nameSave = "q q -> s^* q";
+ else if (idq == 4) nameSave = "q q -> c^* q";
+ else nameSave = "q q -> b^* q";
+
+ // Locally stored properties and couplings.
+ Lambda = Settings::parm("ExcitedFermion:Lambda");
+ preFac = M_PI / pow4(Lambda);
+
+ // Secondary open width fractions.
+ openFracPos = ParticleDataTable::resOpenFrac( idRes);
+ openFracNeg = ParticleDataTable::resOpenFrac(-idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qq2qStarq::sigmaKin() {
+
+ // Two possible expressions, for like or unlike sign.
+ sigmaA = preFac * (1. - s3 / sH);
+ sigmaB = preFac * (-uH) * (sH + tH) / sH2;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat) for specific incoming flavours.
+
+double Sigma2qq2qStarq::sigmaHat() {
+
+ // Identify different allowed incoming flavour combinations.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ double open1 = (id1 > 0) ? openFracPos : openFracNeg;
+ double open2 = (id2 > 0) ? openFracPos : openFracNeg;
+ double sigma = 0.;
+ if (id1 * id2 > 0) {
+ if (id1Abs == idq) sigma += (4./3.) * sigmaA * open1;
+ if (id2Abs == idq) sigma += (4./3.) * sigmaA * open2;
+ } else if (id1Abs == idq && id2 == -id1)
+ sigma = (8./3.) * sigmaB * (open1 + open2);
+ else if (id2 == -id1) sigma = sigmaB * (open1 + open2);
+ else if (id1Abs == idq) sigma = sigmaB * open1;
+ else if (id2Abs == idq) sigma = sigmaB * open2;
+
+ // Done.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qq2qStarq::setIdColAcol() {
+
+ // Flavours: either side may have been excited.
+ double open1 = 0.;
+ double open2 = 0.;
+ if (abs(id1) == idq) open1 = (id1 > 0) ? openFracPos : openFracNeg;
+ if (abs(id2) == idq) open2 = (id2 > 0) ? openFracPos : openFracNeg;
+ if (open1 == 0. && open2 == 0.) {
+ open1 = (id1 > 0) ? openFracPos : openFracNeg;
+ open2 = (id2 > 0) ? openFracPos : openFracNeg;
+ }
+ bool excite1 = (open1 > 0.);
+ if (open1 > 0. && open2 > 0.) excite1
+ = (Rndm::flat() * (open1 + open2) < open1);
+
+ // Always excited quark in slot 3 so colour flow flipped or not.
+ if (excite1) {
+ id3 = (id1 > 0) ? idq : -idq;
+ id4 = id2;
+ if (id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
+ else setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
+ if (id1 < 0) swapColAcol();
+ } else {
+ id3 = (id2 > 0) ? idq : -idq;
+ id4 = id1;
+ swapTU = true;
+ if (id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 2, 0, 1, 0);
+ else setColAcol( 1, 0, 0, 2, 0, 2, 1, 0);
+ if (id1 < 0) swapColAcol();
+ }
+ setId( id1, id2, id3, id4);
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2lStarlbar class.
+// Cross section for q qbar -> l^* lbar (excited lepton state).
+// Note: for simplicity decay is assumed isotropic.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2lStarlbar::initProc() {
+
+ // Set up process properties from the chosen lepton flavour.
+ idRes = 4000000 + idl;
+ codeSave = 4020 + idl;
+ if (idl == 11) nameSave = "q qbar -> e^*+- e^-+";
+ else if (idl == 12) nameSave = "q qbar -> nu_e^* nu_ebar";
+ else if (idl == 13) nameSave = "q qbar -> mu^*+- mu^-+";
+ else if (idl == 14) nameSave = "q qbar -> nu_mu^* nu_mubar";
+ else if (idl == 15) nameSave = "q qbar -> tau^*+- tau^-+";
+ else nameSave = "q qbar -> nu_tau^* nu_taubar";
+
+ // Secondary open width fractions.
+ openFracPos = ParticleDataTable::resOpenFrac( idRes);
+ openFracNeg = ParticleDataTable::resOpenFrac(-idRes);
+
+ // Locally stored properties and couplings.
+ Lambda = Settings::parm("ExcitedFermion:Lambda");
+ preFac = (M_PI / pow4(Lambda)) * (openFracPos + openFracNeg) / 3.;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qqbar2lStarlbar::sigmaKin() {
+
+ // Only one possible expressions
+ sigma = preFac * (-uH) * (sH + tH) / sH2;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2lStarlbar::setIdColAcol() {
+
+ // Flavours: either lepton or antilepton may be excited.
+ if (Rndm::flat() * (openFracPos + openFracNeg) < openFracPos) {
+ setId( id1, id2, idRes, -idl);
+ if (id1 < 0) swapTU = true;
+ } else {
+ setId( id1, id2, -idRes, idl);
+ if (id1 > 0) swapTU = true;
+ }
+
+ // Colour flow trivial.
+ if (id1 > 0) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 1, 1, 0, 0, 0, 0, 0);
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaEW.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// electroweak simulation classes (including photon processes).
+
+#include "SigmaEW.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma2qg2qgamma class.
+// Cross section for q g -> q gamma.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qg2qgamma::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ sigUS = (1./3.) * (sH2 + uH2) / (-sH * uH);
+
+ // Answer.
+ sigma0 = (M_PI/sH2) * alpS * alpEM * sigUS;
+
+ }
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qg2qgamma::sigmaHat() {
+
+ // Incoming flavour gives charge factor.
+ int idNow = (id2 == 21) ? id1 : id2;
+ double eNow = CoupEW::ef( abs(idNow) );
+ return sigma0 * pow2(eNow);
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2qgamma::setIdColAcol() {
+
+ // Construct outgoing flavours.
+ id3 = (id1 == 21) ? 22 : id1;
+ id4 = (id2 == 21) ? 22 : id2;
+ setId( id1, id2, id3, id4);
+
+ // Colour flow topology. Swap if first is gluon, or when antiquark.
+ setColAcol( 1, 0, 2, 1, 2, 0, 0, 0);
+ if (id1 == 21) swapCol1234();
+ if (id1 < 0 || id2 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2ggamma class.
+// Cross section for q qbar -> g gamma.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qqbar2ggamma::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ double sigTU = (8./9.) * (tH2 + uH2) / (tH * uH);
+
+ // Answer.
+ sigma0 = (M_PI/sH2) * alpS * alpEM * sigTU;
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qqbar2ggamma::sigmaHat() {
+
+ // Incoming flavour gives charge factor.
+ double eNow = CoupEW::ef( abs(id1) );
+ return sigma0 * pow2(eNow);
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2ggamma::setIdColAcol() {
+
+ // Outgoing flavours trivial.
+ setId( id1, id2, 21, 22);
+
+ // One colour flow topology. Swap if first is antiquark.
+ setColAcol( 1, 0, 0, 2, 1, 2, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2ggamma class.
+// Cross section for g g -> g gamma.
+// Proceeds through a quark box, by default using 5 massless quarks.
+
+//*********
+
+// Initialize process, especially parton-flux object.
+
+void Sigma2gg2ggamma::initProc() {
+
+ // Maximum quark flavour in loop.
+ int nQuarkLoop = Settings::mode("PromptPhoton:nQuarkLoop");
+
+ // Calculate charge factor from the allowed quarks in the box.
+ chargeSum = - 1./3. + 2./3. - 1./3.;
+ if (nQuarkLoop >= 4) chargeSum += 2./3.;
+ if (nQuarkLoop >= 5) chargeSum -= 1./3.;
+ if (nQuarkLoop >= 6) chargeSum += 2./3.;
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat).
+
+void Sigma2gg2ggamma::sigmaKin() {
+
+ // Logarithms of Mandelstam variable ratios.
+ double logST = log( -sH / tH );
+ double logSU = log( -sH / uH );
+ double logTU = log( tH / uH );
+
+ // Real and imaginary parts of separate amplitudes.
+ double b0stuRe = 1. + (tH - uH) / sH * logTU
+ + 0.5 * (tH2 + uH2) / sH2 * (pow2(logTU) + pow2(M_PI));
+ double b0stuIm = 0.;
+ double b0tsuRe = 1. + (sH - uH) / tH * logSU
+ + 0.5 * (sH2 + uH2) / tH2 * pow2(logSU);
+ double b0tsuIm = -M_PI * ( (sH - uH) / tH + (sH2 + uH2) / tH2 * logSU);
+ double b0utsRe = 1. + (sH - tH) / uH * logST
+ + 0.5 * (sH2 + tH2) / uH2 * pow2(logST);
+ double b0utsIm = -M_PI * ( (sH - tH) / uH + (sH2 + tH2) / uH2 * logST);
+ double b1stuRe = -1.;
+ double b1stuIm = 0.;
+ double b2stuRe = -1.;
+ double b2stuIm = 0.;
+
+ // Calculate kinematics dependence.
+ double sigBox = pow2(b0stuRe) + pow2(b0stuIm) + pow2(b0tsuRe)
+ + pow2(b0tsuIm) + pow2(b0utsRe) + pow2(b0utsIm) + 4. * pow2(b1stuRe)
+ + 4. * pow2(b1stuIm) + pow2(b2stuRe) + pow2(b2stuIm);
+
+ // Answer.
+ sigma = (5. / (192. * M_PI * sH2)) * pow2(chargeSum)
+ * pow3(alpS) * alpEM * sigBox;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2ggamma::setIdColAcol() {
+
+ // Flavours and colours are trivial.
+ setId( id1, id2, 21, 22);
+ setColAcol( 1, 2, 2, 3, 1, 3, 0, 0);
+ if (Rndm::flat() > 0.5) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2gammagamma class.
+// Cross section for q qbar -> gamma gamma.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2gammagamma::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ sigTU = 2. * (tH2 + uH2) / (tH * uH);
+
+ // Answer contains factor 1/2 from identical photons.
+ sigma0 = (M_PI/sH2) * pow2(alpEM) * 0.5 * sigTU;
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2gammagamma::sigmaHat() {
+
+ // Incoming flavour gives charge and colour factors.
+ double eNow = CoupEW::ef( abs(id1) );
+ double colFac = (abs(id1) < 9) ? 1. / 3. : 1.;
+ return sigma0 * pow4(eNow) * colFac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2gammagamma::setIdColAcol() {
+
+ // Outgoing flavours trivial.
+ setId( id1, id2, 22, 22);
+
+ // No colours at all or one flow topology. Swap if first is antiquark.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2gammagamma class.
+// Cross section for g g -> gamma gamma.
+// Proceeds through a quark box, by default using 5 massless quarks.
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2gammagamma::initProc() {
+
+ // Maximum quark flavour in loop.
+ int nQuarkLoop = Settings::mode("PromptPhoton:nQuarkLoop");
+
+ // Calculate charge factor from the allowed quarks in the box.
+ charge2Sum = 1./9. + 4./9. + 1./9.;
+ if (nQuarkLoop >= 4) charge2Sum += 4./9.;
+ if (nQuarkLoop >= 5) charge2Sum += 1./9.;
+ if (nQuarkLoop >= 6) charge2Sum += 4./9.;
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat).
+
+void Sigma2gg2gammagamma::sigmaKin() {
+
+ // Logarithms of Mandelstam variable ratios.
+ double logST = log( -sH / tH );
+ double logSU = log( -sH / uH );
+ double logTU = log( tH / uH );
+
+ // Real and imaginary parts of separate amplitudes.
+ double b0stuRe = 1. + (tH - uH) / sH * logTU
+ + 0.5 * (tH2 + uH2) / sH2 * (pow2(logTU) + pow2(M_PI));
+ double b0stuIm = 0.;
+ double b0tsuRe = 1. + (sH - uH) / tH * logSU
+ + 0.5 * (sH2 + uH2) / tH2 * pow2(logSU);
+ double b0tsuIm = -M_PI * ( (sH - uH) / tH + (sH2 + uH2) / tH2 * logSU);
+ double b0utsRe = 1. + (sH - tH) / uH * logST
+ + 0.5 * (sH2 + tH2) / uH2 * pow2(logST);
+ double b0utsIm = -M_PI * ( (sH - tH) / uH + (sH2 + tH2) / uH2 * logST);
+ double b1stuRe = -1.;
+ double b1stuIm = 0.;
+ double b2stuRe = -1.;
+ double b2stuIm = 0.;
+
+ // Calculate kinematics dependence.
+ double sigBox = pow2(b0stuRe) + pow2(b0stuIm) + pow2(b0tsuRe)
+ + pow2(b0tsuIm) + pow2(b0utsRe) + pow2(b0utsIm) + 4. * pow2(b1stuRe)
+ + 4. * pow2(b1stuIm) + pow2(b2stuRe) + pow2(b2stuIm);
+
+ // Answer contains factor 1/2 from identical photons.
+ sigma = (0.5 / (16. * M_PI * sH2)) * pow2(charge2Sum)
+ * pow2(alpS) * pow2(alpEM) * sigBox;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2gammagamma::setIdColAcol() {
+
+ // Flavours and colours are trivial.
+ setId( id1, id2, 22, 22);
+ setColAcol( 1, 2, 2, 1, 0, 0, 0, 0);
+
+}
+
+//**************************************************************************
+
+// Sigma2ff2fftgmZ class.
+// Cross section for f f' -> f f' via t-channel gamma*/Z0 exchange
+// (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ff2fftgmZ::initProc() {
+
+ // Store Z0 mass for propagator. Common coupling factor.
+ gmZmode = Settings::mode("WeakZ0:gmZmode");
+ mZ = ParticleDataTable::m0(23);
+ mZS = mZ*mZ;
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ff2fftgmZ::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ double sigma0 = (M_PI / sH2) * pow2(alpEM);
+
+ // Kinematical functions for gamma-gamma, gamma-Z and Z-Z parts.
+ sigmagmgm = sigma0 * 2. * (sH2 + uH2) / tH2;
+ sigmagmZ = sigma0 * 4. * thetaWRat * sH2 / (tH * (tH - mZS));
+ sigmaZZ = sigma0 * 2. * pow2(thetaWRat) * sH2 / pow2(tH - mZS);
+ if (gmZmode == 1) {sigmagmZ = 0.; sigmaZZ = 0.;}
+ if (gmZmode == 2) {sigmagmgm = 0.; sigmagmZ = 0.;}
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ff2fftgmZ::sigmaHat() {
+
+ // Couplings for current flavour combination.
+ int id1Abs = abs(id1);
+ double e1 = CoupEW::ef(id1Abs);
+ double v1 = CoupEW::vf(id1Abs);
+ double a1 = CoupEW::af(id1Abs);
+ int id2Abs = abs(id2);
+ double e2 = CoupEW::ef(id2Abs);
+ double v2 = CoupEW::vf(id2Abs);
+ double a2 = CoupEW::af(id2Abs);
+
+ // Distinguish same-sign and opposite-sign fermions.
+ double epsi = (id1 * id2 > 0) ? 1. : -1.;
+
+ // Flavour-dependent cross section.
+ double sigma = sigmagmgm * pow2(e1 * e2)
+ + sigmagmZ * e1 * e2 * (v1 * v2 * (1. + uH2 / sH2)
+ + a1 * a2 * epsi * (1. - uH2 / sH2))
+ + sigmaZZ * ((v1*v1 + a1*a1) * (v2*v2 + a2*a2) * (1. + uH2 / sH2)
+ + 4. * v1 * a1 * v2 * a2 * epsi * (1. - uH2 / sH2));
+
+ // Spin-state extra factor 2 per incoming neutrino.
+ if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
+ if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ff2fftgmZ::setIdColAcol() {
+
+ // Trivial flavours: out = in.
+ setId( id1, id2, id1, id2);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9 && abs(id2) < 9 && id1*id2 > 0)
+ setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
+ else if (abs(id1) < 9 && abs(id2) < 9)
+ setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
+ else if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 1, 0, 0, 0);
+ else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if ( (abs(id1) < 9 && id1 < 0) || (abs(id1) > 10 && id2 < 0) )
+ swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2ff2fftW class.
+// Cross section for f_1 f_2 -> f_3 f_4 via t-channel W+- exchange
+// (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ff2fftW::initProc() {
+
+ // Store W+- mass for propagator. Common coupling factor.
+ mW = ParticleDataTable::m0(24);
+ mWS = mW*mW;
+ thetaWRat = 1. / (4. * CoupEW::sin2thetaW());
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ff2fftW::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * pow2(alpEM * thetaWRat)
+ * 4. * sH2 / pow2(tH - mWS);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ff2fftW::sigmaHat() {
+
+ // Some flavour combinations not possible.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ if ( (id1Abs%2 == id2Abs%2 && id1 * id2 > 0)
+ || (id1Abs%2 != id2Abs%2 && id1 * id2 < 0) ) return 0.;
+
+ // Basic cross section.
+ double sigma = sigma0;
+ if (id1 * id2 < 0) sigma *= uH2 / sH2;
+
+ // CKM factors for final states.
+ sigma *= VCKM::V2sum(id1Abs) * VCKM::V2sum(id2Abs);
+
+ // Spin-state extra factor 2 per incoming neutrino.
+ if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
+ if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ff2fftW::setIdColAcol() {
+
+ // Pick out-flavours by relative CKM weights.
+ id3 = VCKM::V2pick(id1);
+ id4 = VCKM::V2pick(id2);
+ setId( id1, id2, id3, id4);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9 && abs(id2) < 9 && id1*id2 > 0)
+ setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
+ else if (abs(id1) < 9 && abs(id2) < 9)
+ setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
+ else if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 1, 0, 0, 0);
+ else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if ( (abs(id1) < 9 && id1 < 0) || (abs(id1) > 10 && id2 < 0) )
+ swapColAcol();
+
+}
+
+
+//**************************************************************************
+
+// Sigma2qq2QqtW class.
+// Cross section for q q' -> Q q" via t-channel W+- exchange.
+// Related to Sigma2ff2ffViaW class, but with massive matrix elements.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qq2QqtW::initProc() {
+
+ // Process name.
+ nameSave = "q q -> Q q (t-channel W+-)";
+ if (idNew == 4) nameSave = "q q -> c q (t-channel W+-)";
+ if (idNew == 5) nameSave = "q q -> b q (t-channel W+-)";
+ if (idNew == 6) nameSave = "q q -> t q (t-channel W+-)";
+ if (idNew == 7) nameSave = "q q -> b' q (t-channel W+-)";
+ if (idNew == 8) nameSave = "q q -> t' q (t-channel W+-)";
+
+ // Store W+- mass for propagator. Common coupling factor.
+ mW = ParticleDataTable::m0(24);
+ mWS = mW*mW;
+ thetaWRat = 1. / (4. * CoupEW::sin2thetaW());
+
+ // Secondary open width fractions, relevant for top (or heavier).
+ openFracPos = ParticleDataTable::resOpenFrac(idNew);
+ openFracNeg = ParticleDataTable::resOpenFrac(-idNew);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qq2QqtW::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * pow2(alpEM * thetaWRat) * 4. / pow2(tH - mWS);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qq2QqtW::sigmaHat() {
+
+ // Some flavour combinations not possible.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ bool diff12 = (id1Abs%2 != id2Abs%2);
+ if ( (!diff12 && id1 * id2 > 0)
+ || ( diff12 && id1 * id2 < 0) ) return 0.;
+
+ // Basic cross section.
+ double sigma = sigma0;
+ sigma *= (id1 * id2 > 0) ? sH * (sH - s3) : uH * (uH - s3);
+
+ // Secondary width if t or tbar produced on either side.
+ double openFrac1 = (id1 > 0) ? openFracPos : openFracNeg;
+ double openFrac2 = (id2 > 0) ? openFracPos : openFracNeg;
+
+ // CKM factors for final states; further impossible case.
+ bool diff1N = (id1Abs%2 != idNew%2);
+ bool diff2N = (id2Abs%2 != idNew%2);
+ if (diff1N && diff2N)
+ sigma *= ( VCKM::V2id(id1Abs, idNew) * openFrac1 * VCKM::V2sum(id2Abs)
+ + VCKM::V2sum(id1Abs) * VCKM::V2id(id2Abs, idNew) * openFrac2 );
+ else if (diff1N)
+ sigma *= VCKM::V2id(id1Abs, idNew) * openFrac1 * VCKM::V2sum(id2Abs);
+ else if (diff2N)
+ sigma *= VCKM::V2sum(id1Abs) * VCKM::V2id(id2Abs, idNew) * openFrac2;
+ else sigma = 0.;
+
+ // Spin-state extra factor 2 per incoming neutrino.
+ if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
+ if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qq2QqtW::setIdColAcol() {
+
+ // For topologies like d dbar -> (t/c/u) (t/c/u)bar pick side.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ int side = 1;
+ if ( (id1Abs + idNew)%2 == 1 && (id2Abs + idNew)%2 == 1 ) {
+ double prob1 = VCKM::V2id(id1Abs, idNew) * VCKM::V2sum(id2Abs);
+ prob1 *= (id1 > 0) ? openFracPos : openFracNeg;
+ double prob2 = VCKM::V2id(id2Abs, idNew) * VCKM::V2sum(id1Abs);
+ prob2 *= (id2 > 0) ? openFracPos : openFracNeg;
+ if (prob2 > Rndm::flat() * (prob1 + prob2)) side = 2;
+ }
+ else if ((id2Abs + idNew)%2 == 1) side = 2;
+
+ // Pick out-flavours by relative CKM weights.
+ if (side == 1) {
+ // q q' -> t q" : correct order from start.
+ id3 = (id1 > 0) ? idNew : -idNew;
+ id4 = VCKM::V2pick(id2);
+ setId( id1, id2, id3, id4);
+ } else {
+ // q q' -> q" t : stored as t q" so swap tHat <-> uHat.
+ swapTU = true;
+ id3 = VCKM::V2pick(id1);
+ id4 = (id2 > 0) ? idNew : -idNew;
+ setId( id1, id2, id4, id3);
+ }
+
+ // Colour flow topologies. Swap when antiquarks on side 1.
+ if (side == 1 && id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
+ else if (id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 2, 0, 1, 0);
+ else if (side == 1) setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
+ else setColAcol( 1, 0, 0, 2, 0, 2, 1, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles of W in top decay.
+
+double Sigma2qq2QqtW::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // For top decay hand over to standard routine, else done.
+ if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+ else return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma1ffbar2gmZ class.
+// Cross section for f fbar -> gamma*/Z0 (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2gmZ::initProc() {
+
+ // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
+ gmZmode = Settings::mode("WeakZ0:gmZmode");
+
+ // Store Z0 mass and width for propagator.
+ mRes = ParticleDataTable::m0(23);
+ GammaRes = ParticleDataTable::mWidth(23);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(23);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2gmZ::sigmaKin() {
+
+ // Common coupling factors.
+ double colQ = 3. * (1. + alpS / M_PI);
+
+ // Reset quantities to sum. Declare variables in loop.
+ gamSum = 0.;
+ intSum = 0.;
+ resSum = 0.;
+ int idAbs, onMode;
+ double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
+
+ // Loop over all Z0 decay channels.
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ idAbs = abs( particlePtr->decay[i].product(0) );
+
+ // Only contributions from three fermion generations, except top.
+ if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
+ mf = ParticleDataTable::m0(idAbs);
+
+ // Check that above threshold. Phase space.
+ if (mH > 2. * mf + MASSMARGIN) {
+ mr = pow2(mf / mH);
+ betaf = sqrtpos(1. - 4. * mr);
+ psvec = betaf * (1. + 2. * mr);
+ psaxi = pow3(betaf);
+
+ // Combine phase space with couplings.
+ ef2 = CoupEW::ef2(idAbs) * psvec;
+ efvf = CoupEW::efvf(idAbs) * psvec;
+ vf2af2 = CoupEW::vf2(idAbs) * psvec + CoupEW::af2(idAbs) * psaxi;
+ colf = (idAbs < 6) ? colQ : 1.;
+
+ // Store sum of combinations. For outstate only open channels.
+ onMode = particlePtr->decay[i].onMode();
+ if (onMode == 1 || onMode == 2) {
+ gamSum += colf * ef2;
+ intSum += colf * efvf;
+ resSum += colf * vf2af2;
+ }
+
+ // End loop over fermions.
+ }
+ }
+ }
+
+ // Calculate prefactors for gamma/interference/Z0 cross section terms.
+ gamProp = 4. * M_PI * pow2(alpEM) / (3. * sH);
+ intProp = gamProp * 2. * thetaWRat * sH * (sH - m2Res)
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ resProp = gamProp * pow2(thetaWRat * sH)
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+
+ // Optionally only keep gamma* or Z0 term.
+ if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
+ if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2gmZ::sigmaHat() {
+
+ // Combine gamma, interference and Z0 parts.
+ int idAbs = abs(id1);
+ double sigma = CoupEW::ef2(idAbs) * gamProp * gamSum
+ + CoupEW::efvf(idAbs) * intProp * intSum
+ + CoupEW::vf2af2(idAbs) * resProp * resSum;
+
+ // Colour factor. Answer.
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2gmZ::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, 23);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for gamma*/Z0 decay angle.
+
+double Sigma1ffbar2gmZ::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Z should sit in entry 5.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Couplings for in- and out-flavours.
+ int idInAbs = process[3].idAbs();
+ double ei = CoupEW::ef(idInAbs);
+ double vi = CoupEW::vf(idInAbs);
+ double ai = CoupEW::af(idInAbs);
+ int idOutAbs = process[6].idAbs();
+ double ef = CoupEW::ef(idOutAbs);
+ double vf = CoupEW::vf(idOutAbs);
+ double af = CoupEW::af(idOutAbs);
+
+ // Phase space factors. (One power of beta left out in formulae.)
+ double mf = process[6].m();
+ double mr = mf*mf / sH;
+ double betaf = sqrtpos(1. - 4. * mr);
+
+ // Coefficients of angular expression.
+ double coefTran = ei*ei * gamProp * ef*ef + ei * vi * intProp * ef * vf
+ + (vi*vi + ai*ai) * resProp * (vf*vf + pow2(betaf) * af*af);
+ double coefLong = 4. * mr * ( ei*ei * gamProp * ef*ef
+ + ei * vi * intProp * ef * vf + (vi*vi + ai*ai) * resProp * vf*vf );
+ double coefAsym = betaf * ( ei * ai * intProp * ef * af
+ + 4. * vi * ai * resProp * vf * af );
+
+ // Flip asymmetry for in-fermion + out-antifermion.
+ if (process[3].id() * process[6].id() < 0) coefAsym = -coefAsym;
+
+ // Reconstruct decay angle and weight for it.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+ double wtMax = 2. * (coefTran + abs(coefAsym));
+ double wt = coefTran * (1. + pow2(cosThe))
+ + coefLong * (1. - pow2(cosThe)) + 2. * coefAsym * cosThe;
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma1ffbar2W class.
+// Cross section for f fbar' -> W+- (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2W::initProc() {
+
+ // Store W+- mass and width for propagator.
+ mRes = ParticleDataTable::m0(24);
+ GammaRes = ParticleDataTable::mWidth(24);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(24);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2W::sigmaKin() {
+
+ // Set up Breit-Wigner. Cross section for W+ and W- separately.
+ double sigBW = 12. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double preFac = alpEM * thetaWRat * mH;
+ sigma0Pos = preFac * sigBW * particlePtr->resWidthOpen(34, mH);
+ sigma0Neg = preFac * sigBW * particlePtr->resWidthOpen(-34, mH);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2W::sigmaHat() {
+
+ // Secondary width for W+ or W-. CKM and colour factors.
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ double sigma = (idUp > 0) ? sigma0Pos : sigma0Neg;
+ if (abs(id1) < 9) sigma *= VCKM::V2id(abs(id1), abs(id2)) / 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2W::setIdColAcol() {
+
+ // Sign of outgoing W.
+ int sign = 1 - 2 * (abs(id1)%2);
+ if (id1 < 0) sign = -sign;
+ setId( id1, id2, 24 * sign);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for W decay angle.
+
+double Sigma1ffbar2W::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // W should sit in entry 5.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Phase space factors.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+
+ // Sign of asymmetry.
+ double eps = (process[3].id() * process[6].id() > 0) ? 1. : -1.;
+
+ // Reconstruct decay angle and weight for it.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+ double wtMax = 4.;
+ double wt = pow2(1. + betaf * eps * cosThe) - pow2(mr1 - mr2);
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2ffbarsgm class.
+// Cross section f fbar -> gamma* -> f' fbar', for multiple interactions.
+
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2ffbarsgm::sigmaKin() {
+
+ // Pick new flavour. Allow three leptons and five quarks.
+ double colQ = 1. + (alpS / M_PI);
+ double flavWt = 3. + colQ * 11. / 3.;
+ double flavRndm = Rndm::flat() * flavWt;
+ if (flavRndm < 3.) {
+ if (flavRndm < 1.) idNew = 11;
+ else if (flavRndm < 2.) idNew = 13;
+ else idNew = 15;
+ } else {
+ flavRndm = 3. * (flavWt - 3.) / colQ;
+ if (flavRndm < 4.) idNew = 2;
+ else if (flavRndm < 8.) idNew = 4;
+ else if (flavRndm < 9.) idNew = 1;
+ else if (flavRndm < 10.) idNew = 3;
+ else idNew = 5;
+ }
+ double mNew = ParticleDataTable::m0(idNew);
+ double m2New = mNew*mNew;
+
+ // Calculate kinematics dependence. Give correct mass factors for
+ // tHat, uHat defined as if massless kinematics, d(sigma)/d(Omega)
+ // = beta (1 + cos^2(theta) + (1 - beta^2) sin^2(theta)).
+ // Special case related to phase space form in multiple interactions.
+ double sigS = 0.;
+ if (sH > 4. * m2New) {
+ double beta = sqrt(1. - 4. * m2New / sH);
+ sigS = beta * (2.* (tH2 + uH2) + 4. * (1. - beta * beta) * tH * uH)
+ / sH2;
+ }
+
+ // Answer is proportional to number of outgoing flavours.
+ sigma0 = (M_PI/sH2) * pow2(alpEM) * sigS * flavWt;
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2ffbarsgm::sigmaHat() {
+
+ // Charge and colour factors.
+ double eNow = CoupEW::ef( abs(id1) );
+ double sigma = sigma0 * pow2(eNow);
+ if (abs(id1) < 9) sigma /= 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2ffbarsgm::setIdColAcol() {
+
+ // Set outgoing flavours.
+ id3 = (id1 > 0) ? idNew : -idNew;
+ setId( id1, id2, id3, -id3);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
+ else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2FFbarsgmZ class.
+// Cross section f fbar -> gamma*/Z0 -> F Fbar.
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2FFbarsgmZ::initProc() {
+
+ // Process name.
+ nameSave = "f fbar -> F Fbar (s-channel gamma*/Z0)";
+ if (idNew == 4) nameSave = "f fbar -> c cbar (s-channel gamma*/Z0)";
+ if (idNew == 5) nameSave = "f fbar -> b bbar (s-channel gamma*/Z0)";
+ if (idNew == 6) nameSave = "f fbar -> t tbar (s-channel gamma*/Z0)";
+ if (idNew == 7) nameSave = "f fbar -> b' b'bar (s-channel gamma*/Z0)";
+ if (idNew == 8) nameSave = "f fbar -> t' t'bar (s-channel gamma*/Z0)";
+ if (idNew == 15) nameSave = "f fbar -> tau+ tau- (s-channel gamma*/Z0)";
+ if (idNew == 17) nameSave = "f fbar -> tau'+ tau'- (s-channel gamma*/Z0)";
+ if (idNew == 18)
+ nameSave = "f fbar -> nu'_tau nu'bar_tau (s-channel gamma*/Z0)";
+
+ // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
+ gmZmode = Settings::mode("WeakZ0:gmZmode");
+
+ // Store Z0 mass and width for propagator.
+ mRes = ParticleDataTable::m0(23);
+ GammaRes = ParticleDataTable::mWidth(23);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+ // Store couplings of F.
+ ef = CoupEW::ef(idNew);
+ vf = CoupEW::vf(idNew);
+ af = CoupEW::af(idNew);
+
+ // Secondary open width fraction, relevant for top (or heavier).
+ openFracPair = ParticleDataTable::resOpenFrac(idNew, -idNew);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2FFbarsgmZ::sigmaKin() {
+
+ // Check that above threshold.
+ isPhysical = true;
+ if (mH < m3 + m4 + MASSMARGIN) {
+ isPhysical = false;
+ return;
+ }
+
+ // Define average F, Fbar mass so same beta. Phase space.
+ double s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH;
+ mr = s34Avg / sH;
+ betaf = sqrtpos(1. - 4. * mr);
+
+ // Final-state colour factor.
+ double colF = (idNew < 9) ? 3. * (1. + alpS / M_PI) : 1.;
+
+ // Reconstruct decay angle so can reuse 2 -> 1 cross section.
+ cosThe = (tH - uH) / (betaf * sH);
+
+ // Calculate prefactors for gamma/interference/Z0 cross section terms.
+ gamProp = colF * M_PI * pow2(alpEM) / sH2;
+ intProp = gamProp * 2. * thetaWRat * sH * (sH - m2Res)
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ resProp = gamProp * pow2(thetaWRat * sH)
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+
+ // Optionally only keep gamma* or Z0 term.
+ if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
+ if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2FFbarsgmZ::sigmaHat() {
+
+ // Fail if below threshold.
+ if (!isPhysical) return 0.;
+
+ // Couplings for in-flavours.
+ int idAbs = abs(id1);
+ double ei = CoupEW::ef(idAbs);
+ double vi = CoupEW::vf(idAbs);
+ double ai = CoupEW::af(idAbs);
+
+ // Coefficients of angular expression.
+ double coefTran = ei*ei * gamProp * ef*ef + ei * vi * intProp * ef * vf
+ + (vi*vi + ai*ai) * resProp * (vf*vf + pow2(betaf) * af*af);
+ double coefLong = 4. * mr * ( ei*ei * gamProp * ef*ef
+ + ei * vi * intProp * ef * vf + (vi*vi + ai*ai) * resProp * vf*vf );
+ double coefAsym = betaf * ( ei * ai * intProp * ef * af
+ + 4. * vi * ai * resProp * vf * af );
+
+ // Combine gamma, interference and Z0 parts.
+ double sigma = coefTran * (1. + pow2(cosThe))
+ + coefLong * (1. - pow2(cosThe)) + 2. * coefAsym * cosThe;
+
+ // Top: corrections for closed decay channels.
+ sigma *= openFracPair;
+
+ // Initial-state colour factor. Answer.
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2FFbarsgmZ::setIdColAcol() {
+
+ // Set outgoing flavours.
+ id3 = (id1 > 0) ? idNew : -idNew;
+ setId( id1, id2, id3, -id3);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
+ else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles of W in top decay.
+
+double Sigma2ffbar2FFbarsgmZ::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // For top decay hand over to standard routine, else done.
+ if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+ else return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2FfbarsW class.
+// Cross section f fbar' -> W+- -> F fbar".
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2FfbarsW::initProc() {
+
+ // Process name.
+ nameSave = "f fbar -> F fbar (s-channel W+-)";
+ if (idNew == 4) nameSave = "f fbar -> c qbar (s-channel W+-)";
+ if (idNew == 5) nameSave = "f fbar -> b qbar (s-channel W+-)";
+ if (idNew == 6) nameSave = "f fbar -> t qbar (s-channel W+-)";
+ if (idNew == 7) nameSave = "f fbar -> b' qbar (s-channel W+-)";
+ if (idNew == 8) nameSave = "f fbar -> t' qbar (s-channel W+-)";
+ if (idNew == 7 && idNew2 == 6)
+ nameSave = "f fbar -> b' tbar (s-channel W+-)";
+ if (idNew == 8 && idNew2 == 7)
+ nameSave = "f fbar -> t' b'bar (s-channel W+-)";
+ if (idNew == 15 || idNew == 16)
+ nameSave = "f fbar -> tau nu_taubar (s-channel W+-)";
+ if (idNew == 17 || idNew == 18)
+ nameSave = "f fbar -> tau' nu'_taubar (s-channel W+-)";
+
+ // Store W+- mass and width for propagator.
+ mRes = ParticleDataTable::m0(24);
+ GammaRes = ParticleDataTable::mWidth(24);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+ // For t/t' want to use at least b mass.
+ idPartner = idNew2;
+ if ( (idNew == 6 || idNew == 8) && idNew2 == 0 ) idPartner = 5;
+
+ // Sum of CKM weights for quarks.
+ V2New = (idNew < 9) ? VCKM::V2sum(idNew) : 1.;
+ if (idNew2 != 0) V2New = VCKM::V2id(idNew, idNew2);
+
+ // Secondary open width fractions, relevant for top or heavier.
+ openFracPos = ParticleDataTable::resOpenFrac( idNew, -idNew2);
+ openFracNeg = ParticleDataTable::resOpenFrac(-idNew, idNew2);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2FfbarsW::sigmaKin() {
+
+ // Check that above threshold.
+ isPhysical = true;
+ if (mH < m3 + m4 + MASSMARGIN) {
+ isPhysical = false;
+ return;
+ }
+
+ // Phase space factors.
+ double mr1 = s3 / sH;
+ double mr2 = s4 / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+
+ // Reconstruct decay angle so can reuse 2 -> 1 cross section.
+ double cosThe = (tH - uH) / (betaf * sH);
+
+ // Set up Breit-Wigner and in- and out-widths.
+ double sigBW = 9. * M_PI * pow2(alpEM * thetaWRat)
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+
+ // Initial-state colour factor.
+ double colF = (idNew < 9) ? 3. * (1. + alpS / M_PI) * V2New : 1.;
+
+ // Angular dependence.
+ double wt = pow2(1. + betaf * cosThe) - pow2(mr1 - mr2);
+
+ // Temporary answer.
+ sigma0 = sigBW * colF * wt;
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2FfbarsW::sigmaHat() {
+
+ // Fail if below threshold.
+ if (!isPhysical) return 0.;
+
+ // CKM and colour factors.
+ double sigma = sigma0;
+ if (abs(id1) < 9) sigma *= VCKM::V2id(abs(id1), abs(id2)) / 3.;
+
+ // Correction for secondary width in top (or heavier) decay.
+ int idSame = ((abs(id1) + idNew)%2 == 0) ? id1 : id2;
+ sigma *= (idSame > 0) ? openFracPos : openFracNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2FfbarsW::setIdColAcol() {
+
+ // Set outgoing flavours.
+ id3 = idNew;
+ id4 = (idNew2 != 0) ? idNew2 : VCKM::V2pick(idNew);
+ if (idNew%2 == 0) {
+ int idInUp = (abs(id1)%2 == 0) ? id1 : id2;
+ if (idInUp > 0) id4 = -id4;
+ else id3 = -id3;
+ } else {
+ int idInDn = (abs(id1)%2 == 1) ? id1 : id2;
+ if (idInDn > 0) id4 = -id4;
+ else id3 = -id3;
+ }
+ setId( id1, id2, id3, id4);
+
+ // Swap tHat and uHat for fbar' f -> F f".
+ if (id1 * id3 < 0) swapTU = true;
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9 && idNew < 9) setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
+ else if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else if (idNew < 9) setColAcol( 0, 0, 0, 0, 1, 0, 0, 1);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapCol12();
+ if (id3 < 0) swapCol34();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles of W in top decay.
+
+double Sigma2ffbar2FfbarsW::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // For top decay hand over to standard routine, else done.
+ if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+ else return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbargmZWgmZW class.
+// Collects common methods for f fbar -> gamma*/Z0/W+- gamma*/Z0/W-+.
+
+//*********
+
+// Calculate and store internal products.
+
+void Sigma2ffbargmZWgmZW::setupProd( Event& process, int i1, int i2,
+ int i3, int i4, int i5, int i6) {
+
+ // Store incoming and outgoing momenta,
+ pRot[1] = process[i1].p();
+ pRot[2] = process[i2].p();
+ pRot[3] = process[i3].p();
+ pRot[4] = process[i4].p();
+ pRot[5] = process[i5].p();
+ pRot[6] = process[i6].p();
+
+ // Do random rotation to avoid accidental zeroes in HA expressions.
+ bool smallPT = false;
+ do {
+ smallPT = false;
+ double thetaNow = acos(2. * Rndm::flat() - 1.);
+ double phiNow = 2. * M_PI * Rndm::flat();
+ for (int i = 1; i <= 6; ++i) {
+ pRot[i].rot( thetaNow, phiNow);
+ if (pRot[i].pT2() < 1e-4 * pRot[i].pAbs2()) smallPT = true;
+ }
+ } while (smallPT);
+
+ // Calculate internal products.
+ for (int i = 1; i < 6; ++i) {
+ for (int j = i + 1; j <= 6; ++j) {
+ hA[i][j] =
+ sqrt( (pRot[i].e() - pRot[i].pz()) * (pRot[j].e() + pRot[j].pz())
+ / pRot[i].pT2() ) * complex( pRot[i].px(), pRot[i].py() )
+ - sqrt( (pRot[i].e() + pRot[i].pz()) * (pRot[j].e() - pRot[j].pz())
+ / pRot[j].pT2() ) * complex( pRot[j].px(), pRot[j].py() );
+ hC[i][j] = conj( hA[i][j] );
+ if (i <= 2) {
+ hA[i][j] *= complex( 0., 1.);
+ hC[i][j] *= complex( 0., 1.);
+ }
+ hA[j][i] = - hA[i][j];
+ hC[j][i] = - hC[i][j];
+ }
+ }
+
+}
+
+//*********
+
+// Evaluate the F function of Gunion and Kunszt.
+
+complex Sigma2ffbargmZWgmZW::fGK(int j1, int j2, int j3, int j4, int j5,
+ int j6) {
+
+ return 4. * hA[j1][j3] * hC[j2][j6]
+ * ( hA[j1][j5] * hC[j1][j4] + hA[j3][j5] * hC[j3][j4] );
+
+}
+
+//*********
+
+// Evaluate the Xi function of Gunion and Kunszt.
+
+double Sigma2ffbargmZWgmZW::xiGK( double tHnow, double uHnow) {
+
+ return - 4. * s3 * s4 + tHnow * (3. * tHnow + 4. * uHnow)
+ + tHnow * tHnow * ( tHnow * uHnow / (s3 * s4)
+ - 2. * (1. / s3 + 1./s4) * (tHnow + uHnow)
+ + 2. * (s3 / s4 + s4 / s3) );
+
+}
+
+//*********
+
+// Evaluate the Xj function of Gunion and Kunszt.
+
+double Sigma2ffbargmZWgmZW::xjGK( double tHnow, double uHnow) {
+
+ return 8. * pow2(s3 + s4) - 8. * (s3 + s4) * (tHnow + uHnow)
+ - 6. * tHnow * uHnow - 2. * tHnow * uHnow * ( tHnow * uHnow
+ / (s3 * s4) - 2. * (1. / s3 + 1. / s4) * (tHnow + uHnow)
+ + 2. * (s3 / s4 + s4 / s3) );
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2gmZgmZ class.
+// Cross section for f fbar -> gamma*/Z0 gamma*/Z0 (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2gmZgmZ::initProc() {
+
+ // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
+ gmZmode = Settings::mode("WeakZ0:gmZmode");
+
+ // Store Z0 mass and width for propagator.
+ mRes = ParticleDataTable::m0(23);
+ GammaRes = ParticleDataTable::mWidth(23);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(23);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2gmZgmZ::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * pow2(alpEM) * 0.5
+ * ( (tH2 + uH2 + 2. * (s3 + s4) * sH) / (tH * uH)
+ - s3 * s4 * (1./tH2 + 1./uH2) );
+
+ // Common coupling factors at the resonance masses
+ double alpEM3 = alphaEMPtr->alphaEM(s3);
+ double alpS3 = alphaSPtr->alphaS(s3);
+ double colQ3 = 3. * (1. + alpS3 / M_PI);
+ double alpEM4 = alphaEMPtr->alphaEM(s4);
+ double alpS4 = alphaSPtr->alphaS(s4);
+ double colQ4 = 3. * (1. + alpS4 / M_PI);
+
+ // Reset quantities to sum. Declare variables in loop.
+ gamSum3 = 0.;
+ intSum3 = 0.;
+ resSum3 = 0.;
+ gamSum4 = 0.;
+ intSum4 = 0.;
+ resSum4 = 0.;
+ int onMode;
+ double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
+
+ // Loop over all Z0 decay channels.
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ int idAbs = abs( particlePtr->decay[i].product(0) );
+
+ // Only contributions from three fermion generations, except top.
+ if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
+ mf = ParticleDataTable::m0(idAbs);
+ onMode = particlePtr->decay[i].onMode();
+
+ // First Z0: check that above threshold. Phase space.
+ if (m3 > 2. * mf + MASSMARGIN) {
+ mr = pow2(mf / m3);
+ betaf = sqrtpos(1. - 4. * mr);
+ psvec = betaf * (1. + 2. * mr);
+ psaxi = pow3(betaf);
+
+ // First Z0: combine phase space with couplings.
+ ef2 = CoupEW::ef2(idAbs) * psvec;
+ efvf = CoupEW::efvf(idAbs) * psvec;
+ vf2af2 = CoupEW::vf2(idAbs) * psvec + CoupEW::af2(idAbs) * psaxi;
+ colf = (idAbs < 6) ? colQ3 : 1.;
+
+ // First Z0: store sum of combinations for open outstate channels.
+ if (onMode == 1 || onMode == 2) {
+ gamSum3 += colf * ef2;
+ intSum3 += colf * efvf;
+ resSum3 += colf * vf2af2;
+ }
+ }
+
+ // Second Z0: check that above threshold. Phase space.
+ if (m4 > 2. * mf + MASSMARGIN) {
+ mr = pow2(mf / m4);
+ betaf = sqrtpos(1. - 4. * mr);
+ psvec = betaf * (1. + 2. * mr);
+ psaxi = pow3(betaf);
+
+ // Second Z0: combine phase space with couplings.
+ ef2 = CoupEW::ef2(idAbs) * psvec;
+ efvf = CoupEW::efvf(idAbs) * psvec;
+ vf2af2 = CoupEW::vf2(idAbs) * psvec + CoupEW::af2(idAbs) * psaxi;
+ colf = (idAbs < 6) ? colQ4 : 1.;
+
+ // Second Z0: store sum of combinations for open outstate channels.
+ if (onMode == 1 || onMode == 2) {
+ gamSum4 += colf * ef2;
+ intSum4 += colf * efvf;
+ resSum4 += colf * vf2af2;
+ }
+ }
+
+ // End loop over fermions.
+ }
+ }
+
+ // First Z0: calculate prefactors for gamma/interference/Z0 terms.
+ gamProp3 = 4. * alpEM3 / (3. * M_PI * s3);
+ intProp3 = gamProp3 * 2. * thetaWRat * s3 * (s3 - m2Res)
+ / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
+ resProp3 = gamProp3 * pow2(thetaWRat * s3)
+ / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
+
+ // First Z0: optionally only keep gamma* or Z0 term.
+ if (gmZmode == 1) {intProp3 = 0.; resProp3 = 0.;}
+ if (gmZmode == 2) {gamProp3 = 0.; intProp3 = 0.;}
+
+ // Second Z0: calculate prefactors for gamma/interference/Z0 terms.
+ gamProp4 = 4. * alpEM4 / (3. * M_PI * s4);
+ intProp4 = gamProp4 * 2. * thetaWRat * s4 * (s4 - m2Res)
+ / ( pow2(s4 - m2Res) + pow2(s4 * GamMRat) );
+ resProp4 = gamProp4 * pow2(thetaWRat * s4)
+ / ( pow2(s4 - m2Res) + pow2(s4 * GamMRat) );
+
+ // Second Z0: optionally only keep gamma* or Z0 term.
+ if (gmZmode == 1) {intProp4 = 0.; resProp4 = 0.;}
+ if (gmZmode == 2) {gamProp4 = 0.; intProp4 = 0.;}
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2gmZgmZ::sigmaHat() {
+
+ // Charge/2, left- and righthanded couplings for in-fermion.
+ int idAbs = abs(id1);
+ double ei = 0.5 * CoupEW::ef(idAbs);
+ double li = CoupEW::lf(idAbs);
+ double ri = CoupEW::rf(idAbs);
+
+ // Combine left/right gamma, interference and Z0 parts for each Z0.
+ double left3 = ei * ei * gamProp3 * gamSum3
+ + ei * li * intProp3 * intSum3
+ + li * li * resProp3 * resSum3;
+ double right3 = ei * ei * gamProp3 * gamSum3
+ + ei * ri * intProp3 * intSum3
+ + ri * ri * resProp3 * resSum3;
+ double left4 = ei * ei * gamProp4 * gamSum4
+ + ei * li * intProp4 * intSum4
+ + li * li * resProp4 * resSum4;
+ double right4 = ei * ei * gamProp4 * gamSum4
+ + ei * ri * intProp4 * intSum4
+ + ri * ri * resProp4 * resSum4;
+
+ // Combine left- and right-handed couplings for the two Z0's.
+ double sigma = sigma0 * (left3 * left4 + right3 * right4);
+
+ // Correct for the running-width Z0 propagators weight in PhaseSpace.
+ sigma /= (runBW3 * runBW4);
+
+ // Initial-state colour factor. Answer.
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2gmZgmZ::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, 23, 23);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate correlated decay flavours of the two gamma*/Z0.
+// Unique complication, caused by gamma*/Z0 mix different left/right.
+
+double Sigma2ffbar2gmZgmZ::weightDecayFlav( Event& process) {
+
+ // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
+ i1 = (process[3].id() < 0) ? 3 : 4;
+ i2 = 7 - i1;
+ i3 = (process[7].id() > 0) ? 7 : 8;
+ i4 = 15 - i3;
+ i5 = (process[9].id() > 0) ? 9 : 10;
+ i6 = 19 - i5;
+
+ // Charge/2, left- and righthanded couplings for in- and out-fermions.
+ int idAbs = process[i1].idAbs();
+ double ei = 0.5 * CoupEW::ef(idAbs);
+ double li = CoupEW::lf(idAbs);
+ double ri = CoupEW::rf(idAbs);
+ idAbs = process[i3].idAbs();
+ double e3 = 0.5 * CoupEW::ef(idAbs);
+ double l3 = CoupEW::lf(idAbs);
+ double r3 = CoupEW::rf(idAbs);
+ idAbs = process[i5].idAbs();
+ double e4 = 0.5 * CoupEW::ef(idAbs);
+ double l4 = CoupEW::lf(idAbs);
+ double r4 = CoupEW::rf(idAbs);
+
+ // Left- and righthanded couplings combined with propagators.
+ c3LL = ei * ei * gamProp3 * e3 * e3
+ + ei * li * intProp3 * e3 * l3
+ + li * li * resProp3 * l3 * l3;
+ c3LR = ei * ei * gamProp3 * e3 * e3
+ + ei * li * intProp3 * e3 * r3
+ + li * li * resProp3 * r3 * r3;
+ c3RL = ei * ei * gamProp3 * e3 * e3
+ + ei * ri * intProp3 * e3 * l3
+ + ri * ri * resProp3 * l3 * l3;
+ c3RR = ei * ei * gamProp3 * e3 * e3
+ + ei * ri * intProp3 * e3 * r3
+ + ri * ri * resProp3 * r3 * r3;
+ c4LL = ei * ei * gamProp4 * e4 * e4
+ + ei * li * intProp4 * e4 * l4
+ + li * li * resProp4 * l4 * l4;
+ c4LR = ei * ei * gamProp4 * e4 * e4
+ + ei * li * intProp4 * e4 * r4
+ + li * li * resProp4 * r4 * r4;
+ c4RL = ei * ei * gamProp4 * e4 * e4
+ + ei * ri * intProp4 * e4 * l4
+ + ri * ri * resProp4 * l4 * l4;
+ c4RR = ei * ei * gamProp4 * e4 * e4
+ + ei * ri * intProp4 * e4 * r4
+ + ri * ri * resProp4 * r4 * r4;
+
+ // Flavour weight and maximum.
+ flavWt = (c3LL + c3LR) * (c4LL + c4LR) + (c3RL + c3RR) * (c4RL + c4RR);
+ double flavWtMax = (c3LL + c3LR + c3RL + c3RR) * (c4LL + c4LR + c4RL + c4RR);
+
+ // Done.
+ return flavWt / flavWtMax;
+
+}
+
+//*********
+
+// Evaluate weight for decay angles of the two gamma*/Z0.
+
+double Sigma2ffbar2gmZgmZ::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Two resonance decays, but with common weight.
+ if (iResBeg != 5 || iResEnd != 6) return 1.;
+
+ // Set up four-products and internal products.
+ setupProd( process, i1, i2, i3, i4, i5, i6);
+
+ // Flip tHat and uHat if first incoming is fermion.
+ double tHres = tH;
+ double uHres = uH;
+ if (process[3].id() > 0) swap( tHres, uHres);
+
+ // Kinematics factors (norm(x) = |x|^2).
+ double fGK135 = norm( fGK( 1, 2, 3, 4, 5, 6) / tHres
+ + fGK( 1, 2, 5, 6, 3, 4) / uHres );
+ double fGK145 = norm( fGK( 1, 2, 4, 3, 5, 6) / tHres
+ + fGK( 1, 2, 5, 6, 4, 3) / uHres );
+ double fGK136 = norm( fGK( 1, 2, 3, 4, 6, 5) / tHres
+ + fGK( 1, 2, 6, 5, 3, 4) / uHres );
+ double fGK146 = norm( fGK( 1, 2, 4, 3, 6, 5) / tHres
+ + fGK( 1, 2, 6, 5, 4, 3) / uHres );
+ double fGK253 = norm( fGK( 2, 1, 5, 6, 3, 4) / tHres
+ + fGK( 2, 1, 3, 4, 5, 6) / uHres );
+ double fGK263 = norm( fGK( 2, 1, 6, 5, 3, 4) / tHres
+ + fGK( 2, 1, 3, 4, 6, 5) / uHres );
+ double fGK254 = norm( fGK( 2, 1, 5, 6, 4, 3) / tHres
+ + fGK( 2, 1, 4, 3, 5, 6) / uHres );
+ double fGK264 = norm( fGK( 2, 1, 6, 5, 4, 3) / tHres
+ + fGK( 2, 1, 4, 3, 6, 5) / uHres );
+
+ // Weight and maximum.
+ double wt = c3LL * c4LL * fGK135 + c3LR * c4LL * fGK145
+ + c3LL * c4LR * fGK136 + c3LR * c4LR * fGK146
+ + c3RL * c4RL * fGK253 + c3RR * c4RL * fGK263
+ + c3RL * c4RR * fGK254 + c3RR * c4RR * fGK264;
+ double wtMax = 16. * s3 * s4 * flavWt
+ * ( (tHres*tHres + uHres*uHres + 2. * sH * (s3 + s4)) / (tHres * uHres)
+ - s3 * s4 * (1. / (tHres*tHres) + 1. / (uHres*uHres)) );
+
+ // Done.
+ return wt / wtMax;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2ZW class.
+// Cross section for f fbar' -> W+ W- (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2ZW::initProc() {
+
+ // Store W+- mass and width for propagator.
+ mW = ParticleDataTable::m0(24);
+ widW = ParticleDataTable::mWidth(24);
+ mWS = mW*mW;
+ mwWS = pow2(mW * widW);
+
+ // Left-handed couplings for up/nu- and down/e-type quarks.
+ lun = (hasLeptonBeams) ? CoupEW::lf(12) : CoupEW::lf(2);
+ lde = (hasLeptonBeams) ? CoupEW::lf(11) : CoupEW::lf(1);
+
+ // Common weak coupling factor.
+ sin2thetaW = CoupEW::sin2thetaW();
+ cos2thetaW = CoupEW::cos2thetaW();
+ thetaWRat = 1. / (4. * cos2thetaW);
+ thetaWpt = (9. - 8. * sin2thetaW) / 4.;
+ thetaWmm = (8. * sin2thetaW - 6.) / 4.;
+
+ // Secondary open width fractions.
+ openFracPos = ParticleDataTable::resOpenFrac(23, 24);
+ openFracNeg = ParticleDataTable::resOpenFrac(23, -24);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2ffbar2ZW::sigmaKin() {
+
+ // Evaluate cross section.
+ double resBW = 1. / (pow2(sH - mWS) + mwWS);
+ sigma0 = (M_PI / sH2) * 0.5 * pow2(alpEM / sin2thetaW);
+ sigma0 *= sH * resBW * (thetaWpt * pT2 + thetaWmm * (s3 + s4))
+ + (sH - mWS) * resBW * sH * (pT2 - s3 - s4) * (lun / tH - lde / uH)
+ + thetaWRat * sH * pT2 * ( lun*lun / tH2 + lde*lde / uH2 )
+ + 2. * thetaWRat * sH * (s3 + s4) * lun * lde / (tH * uH);
+
+ // Protect against slightly negative cross sections,
+ // probably caused by addition of width to the W propagator.
+ sigma0 = max(0., sigma0);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2ZW::sigmaHat() {
+
+ // CKM and colour factors.
+ double sigma = sigma0;
+ if (abs(id1) < 9) sigma *= VCKM::V2id(abs(id1), abs(id2)) / 3.;
+
+ // Corrections for secondary widths in Z0 and W+- decays.
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ sigma *= (idUp > 0) ? openFracPos : openFracNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2ZW::setIdColAcol() {
+
+ // Sign of outgoing W.
+ int sign = 1 - 2 * (abs(id1)%2);
+ if (id1 < 0) sign = -sign;
+ setId( id1, id2, 23, 24 * sign);
+
+ // tHat is defined between (f, W-) or (fbar, W+),
+ // so OK for u/ubar on side 1, but must swap tHat <-> uHat if d/dbar.
+ if (abs(id1)%2 == 1) swapTU = true;
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for Z0 and W+- decay angles.
+
+double Sigma2ffbar2ZW::weightDecay( Event& process, int iResBeg, int iResEnd) {
+
+ // Two resonance decays, but with common weight.
+ if (iResBeg != 5 || iResEnd != 6) return 1.;
+
+ // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6)
+ // with f' fbar' from W+- and f" fbar" from Z0 (note flip Z0 <-> W+-).
+ int i1 = (process[3].id() < 0) ? 3 : 4;
+ int i2 = 7 - i1;
+ int i3 = (process[9].id() > 0) ? 9 : 10;
+ int i4 = 19 - i3;
+ int i5 = (process[7].id() > 0) ? 7 : 8;
+ int i6 = 15 - i5;
+
+ // Set up four-products and internal products.
+ setupProd( process, i1, i2, i3, i4, i5, i6);
+
+ // Swap tHat and uHat if incoming fermion is downtype.
+ double tHres = tH;
+ double uHres = uH;
+ if (process[i2].id()%2 == 1) swap( tHres, uHres);
+
+ // Couplings of incoming (anti)fermions and outgoing from Z0.
+ int idAbs = process[i1].idAbs();
+ double ai = CoupEW::af(idAbs);
+ double li1 = CoupEW::lf(idAbs);
+ idAbs = process[i2].idAbs();
+ double li2 = CoupEW::lf(idAbs);
+ idAbs = process[i5].idAbs();
+ double l4 = CoupEW::lf(idAbs);
+ double r4 = CoupEW::rf(idAbs);
+
+ // W propagator/interference factor.
+ double Wint = cos2thetaW * (sH - mWS) / (pow2(sH - mWS) + mwWS);
+
+ // Combinations of couplings and kinematics (norm(x) = |x|^2).
+ double aWZ = li2 / tHres - 2. * Wint * ai;
+ double bWZ = li1 / uHres + 2. * Wint * ai;
+ double fGK135 = norm( aWZ * fGK( 1, 2, 3, 4, 5, 6)
+ + bWZ * fGK( 1, 2, 5, 6, 3, 4) );
+ double fGK136 = norm( aWZ * fGK( 1, 2, 3, 4, 6, 5)
+ + bWZ * fGK( 1, 2, 6, 5, 3, 4) );
+ double xiT = xiGK( tHres, uHres);
+ double xiU = xiGK( uHres, tHres);
+ double xjTU = xjGK( tHres, uHres);
+
+ // Weight and maximum weight.
+ double wt = l4*l4 * fGK135 + r4*r4 * fGK136;
+ double wtMax = 4. * s3 * s4 * (l4*l4 + r4*r4)
+ * (aWZ * aWZ * xiT + bWZ * bWZ * xiU + aWZ * bWZ * xjTU);
+
+ // Done.
+ return wt / wtMax;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2WW class.
+// Cross section for f fbar -> W- W+ (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2WW::initProc() {
+
+ // Store Z0 mass and width for propagator. Common coupling factor.
+ mZ = ParticleDataTable::m0(23);
+ widZ = ParticleDataTable::mWidth(23);
+ mZS = mZ*mZ;
+ mwZS = pow2(mZ * widZ);
+ thetaWRat = 1. / (4. * CoupEW::sin2thetaW());
+
+ // Secondary open width fraction.
+ openFracPair = ParticleDataTable::resOpenFrac(24, -24);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2ffbar2WW::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * pow2(alpEM);
+
+ // Z0 propagator and gamma*/Z0 interference.
+ double Zprop = sH2 / (pow2(sH - mZS) + mwZS);
+ double Zint = Zprop * (1. - mZS / sH);
+
+ // Common coupling factors (g = gamma*, Z = Z0, f = t-channel fermion).
+ cgg = 0.5;
+ cgZ = thetaWRat * Zint;
+ cZZ = 0.5 * pow2(thetaWRat) * Zprop;
+ cfg = thetaWRat;
+ cfZ = pow2(thetaWRat) * Zint;
+ cff = pow2(thetaWRat);
+
+ // Kinematical functions.
+ double rat34 = sH * (2. * (s3 + s4) + pT2) / (s3 * s4);
+ double lambdaS = pow2(sH - s3 - s4) - 4. * s3 * s4;
+ double intA = (sH - s3 - s4) * rat34 / sH;
+ double intB = 4. * (s3 + s4 - pT2);
+ gSS = (lambdaS * rat34 + 12. * sH * pT2) / sH2;
+ gTT = rat34 + 4. * sH * pT2 / tH2;
+ gST = intA + intB / tH;
+ gUU = rat34 + 4. * sH * pT2 / uH2;
+ gSU = intA + intB / uH;
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2WW::sigmaHat() {
+
+ // Flavour-specific couplings.
+ int idAbs = abs(id1);
+ double ei = CoupEW::ef(idAbs);
+ double vi = CoupEW::vf(idAbs);
+ double ai = CoupEW::af(idAbs);
+
+ // Combine, with different cases for up- and down-type in-flavours.
+ double sigma = sigma0;
+ sigma *= (idAbs%2 == 1)
+ ? (cgg * ei*ei + cgZ * ei * vi + cZZ * (vi*vi + ai*ai)) * gSS
+ + (cfg * ei + cfZ * (vi + ai)) * gST + cff * gTT
+ : (cgg * ei*ei + cgZ * ei * vi + cZZ * (vi*vi + ai*ai)) * gSS
+ - (cfg * ei + cfZ * (vi + ai)) * gSU + cff * gUU;
+
+ // Initial-state colour factor. Correction for secondary widths. Answer.
+ if (idAbs < 9) sigma /= 3.;
+ sigma *= openFracPair;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2WW::setIdColAcol() {
+
+ // Always order W- W+, i.e. W- first.
+ setId( id1, id2, -24, 24);
+
+ // tHat is defined between (f, W-) or (fbar, W+),
+ if (id1 < 0) swapTU = true;
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for W+ and W- decay angles.
+
+double Sigma2ffbar2WW::weightDecay( Event& process, int iResBeg, int iResEnd) {
+
+ // Two resonance decays, but with common weight.
+ if (iResBeg != 5 || iResEnd != 6) return 1.;
+
+ // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
+ // with f' fbar' from W- and f" fbar" from W+.
+ int i1 = (process[3].id() < 0) ? 3 : 4;
+ int i2 = 7 - i1;
+ int i3 = (process[7].id() > 0) ? 7 : 8;
+ int i4 = 15 - i3;
+ int i5 = (process[9].id() > 0) ? 9 : 10;
+ int i6 = 19 - i5;
+
+ // Set up four-products and internal products.
+ setupProd( process, i1, i2, i3, i4, i5, i6);
+
+ // tHat and uHat of fbar f -> W- W+ opposite to previous convention.
+ double tHres = uH;
+ double uHres = tH;
+
+ // Couplings of incoming (anti)fermion.
+ int idAbs = process[i1].idAbs();
+ double ai = CoupEW::af(idAbs);
+ double li = CoupEW::lf(idAbs);
+ double ri = CoupEW::rf(idAbs);
+
+ // gamma*/Z0 propagator/interference factor.
+ double Zint = mZS * (sH - mZS) / (pow2(sH - mZS) + mwZS);
+
+ // Combinations of couplings and kinematics (norm(x) = |x|^2).
+ double dWW = (li * Zint + ai) / sH;
+ double aWW = dWW + 0.5 * (ai + 1.) / tHres;
+ double bWW = dWW + 0.5 * (ai - 1.) / uHres;
+ double cWW = ri * Zint / sH;
+ double fGK135 = norm( aWW * fGK( 1, 2, 3, 4, 5, 6)
+ - bWW * fGK( 1, 2, 5, 6, 3, 4) );
+ double fGK253 = norm( cWW * ( fGK( 2, 1, 5, 6, 3, 4)
+ - fGK( 2, 1, 3, 4, 5, 6) ) );
+ double xiT = xiGK( tHres, uHres);
+ double xiU = xiGK( uHres, tHres);
+ double xjTU = xjGK( tHres, uHres);
+
+ // Weight and maximum weight.
+ double wt = fGK135 + fGK253;
+ double wtMax = 4. * s3 * s4
+ * ( aWW * aWW * xiT + bWW * bWW * xiU - aWW * bWW * xjTU
+ + cWW * cWW * (xiT + xiU - xjTU) );
+
+ // Done.
+ return wt / wtMax;
+}
+
+//**************************************************************************
+
+// Sigma2ffbargmZggm class.
+// Collects common methods for f fbar -> gamma*/Z0 g/gamma and permutations.
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbargmZggm::initProc() {
+
+ // Allow to pick only gamma* or Z0 part of full gamma*/Z0 expression.
+ gmZmode = Settings::mode("WeakZ0:gmZmode");
+
+ // Store Z0 mass and width for propagator.
+ mRes = ParticleDataTable::m0(23);
+ GammaRes = ParticleDataTable::mWidth(23);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(23);
+
+}
+
+//*********
+
+// Evaluate sum of flavour couplings times phase space.
+
+void Sigma2ffbargmZggm::flavSum() {
+
+ // Coupling factors for Z0 subsystem.
+ double alpSZ = alphaSPtr->alphaS(s3);
+ double colQZ = 3. * (1. + alpSZ / M_PI);
+
+ // Reset quantities to sum. Declare variables in loop.
+ gamSum = 0.;
+ intSum = 0.;
+ resSum = 0.;
+ int onMode;
+ double mf, mr, psvec, psaxi, betaf, ef2, efvf, vf2af2, colf;
+
+ // Loop over all Z0 decay channels.
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ int idAbs = abs( particlePtr->decay[i].product(0) );
+
+ // Only contributions from three fermion generations, except top.
+ if ( (idAbs > 0 && idAbs < 6) || ( idAbs > 10 && idAbs < 17)) {
+ mf = ParticleDataTable::m0(idAbs);
+
+ // Check that above threshold. Phase space.
+ if (m3 > 2. * mf + MASSMARGIN) {
+ mr = pow2(mf / m3);
+ betaf = sqrtpos(1. - 4. * mr);
+ psvec = betaf * (1. + 2. * mr);
+ psaxi = pow3(betaf);
+
+ // Combine phase space with couplings.
+ ef2 = CoupEW::ef2(idAbs) * psvec;
+ efvf = CoupEW::efvf(idAbs) * psvec;
+ vf2af2 = CoupEW::vf2(idAbs) * psvec + CoupEW::af2(idAbs) * psaxi;
+ colf = (idAbs < 6) ? colQZ : 1.;
+
+ // Store sum of combinations. For outstate only open channels.
+ onMode = particlePtr->decay[i].onMode();
+ if (onMode == 1 || onMode == 2) {
+ gamSum += colf * ef2;
+ intSum += colf * efvf;
+ resSum += colf * vf2af2;
+ }
+
+ // End loop over fermions.
+ }
+ }
+ }
+
+ // Done. Return values in gamSum, intSum and resSum.
+
+}
+
+//*********
+
+// Calculate common parts of gamma/interference/Z0 propagator terms.
+
+void Sigma2ffbargmZggm::propTerm() {
+
+ // Calculate prefactors for gamma/interference/Z0 cross section terms.
+ gamProp = 4. * alpEM / (3. * M_PI * s3);
+ intProp = gamProp * 2. * thetaWRat * s3 * (s3 - m2Res)
+ / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
+ resProp = gamProp * pow2(thetaWRat * s3)
+ / ( pow2(s3 - m2Res) + pow2(s3 * GamMRat) );
+
+ // Optionally only keep gamma* or Z0 term.
+ if (gmZmode == 1) {intProp = 0.; resProp = 0.;}
+ if (gmZmode == 2) {gamProp = 0.; intProp = 0.;}
+
+}
+
+//*********
+
+// Evaluate weight for gamma*/Z0 decay angle.
+
+double Sigma2ffbargmZggm::weightDecay( Event& process, int iResBeg, int iResEnd) {
+
+ // Z should sit in entry 5 and one more parton in entry 6.
+ if (iResBeg != 5 || iResEnd != 6) return 1.;
+
+ // In an outgoing sense fermions are labelled f(1) fbar(2) f'(3) fbar'(4)
+ // where f' fbar' come from gamma*/Z0 decay.
+ int i1, i2;
+ int i3 = (process[7].id() > 0) ? 7 : 8;
+ int i4 = 15 - i3;
+
+ // Order so that fbar(1) f(2) -> gamma*/Z0 g/gamma.
+ if (process[3].idAbs() < 20 && process[4].idAbs() < 20) {
+ i1 = (process[3].id() < 0) ? 3 : 4;
+ i2 = 7 - i1;
+
+ // Order so that f(2)/fbar(1) g/gamma -> f(1)/fbar(2) f'(3) gamma*/Z0.
+ } else if (process[3].idAbs() < 20) {
+ i1 = (process[3].id() < 0) ? 3 : 6;
+ i2 = 9 - i1;
+ } else {
+ i1 = (process[4].id() < 0) ? 4 : 6;
+ i2 = 10 - i1;
+ }
+
+ // Charge/2, left- and righthanded couplings for in- and out-fermion.
+ int id1Abs = process[i1].idAbs();
+ double ei = 0.5 * CoupEW::ef(id1Abs);
+ double li = CoupEW::lf(id1Abs);
+ double ri = CoupEW::rf(id1Abs);
+ int id3Abs = process[i3].idAbs();
+ double ef = 0.5 * CoupEW::ef(id3Abs);
+ double lf = CoupEW::lf(id3Abs);
+ double rf = CoupEW::rf(id3Abs);
+
+ // Combinations of left/right for in/out, gamma*/interference/Z0.
+ double clilf = ei*ei * gamProp * ef*ef + ei*li * intProp * ef*lf
+ + li*li * resProp * lf*lf;
+ double clirf = ei*ei * gamProp * ef*ef + ei*li * intProp * ef*rf
+ + li*li * resProp * rf*rf;
+ double crilf = ei*ei * gamProp * ef*ef + ei*ri * intProp * ef*lf
+ + ri*ri * resProp * lf*lf;
+ double crirf = ei*ei * gamProp * ef*ef + ei*ri * intProp * ef*rf
+ + ri*ri * resProp * rf*rf;
+
+ // Evaluate four-vector products.
+ double p13 = process[i1].p() * process[i3].p();
+ double p14 = process[i1].p() * process[i4].p();
+ double p23 = process[i2].p() * process[i3].p();
+ double p24 = process[i2].p() * process[i4].p();
+
+ // Calculate weight and its maximum.
+ double wt = (clilf + crirf) * (p13*p13 + p24*p24)
+ + (clirf + crilf) * (p14*p14 + p23*p23) ;
+ double wtMax = (clilf + clirf + crilf + crirf)
+ * (pow2(p13 + p14) + pow2(p23 + p24));
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2gmZg class.
+// Cross section for q qbar -> gamma*/Z0 g.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qqbar2gmZg::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM * alpS)
+ * (2./9.) * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
+
+ // Calculate flavour sums for final state.
+ flavSum();
+
+ // Calculate prefactors for gamma/interference/Z0 cross section terms.
+ propTerm();
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qqbar2gmZg::sigmaHat() {
+
+ // Combine gamma, interference and Z0 parts.
+ int idAbs = abs(id1);
+ double sigma = sigma0
+ * ( CoupEW::ef2(idAbs) * gamProp * gamSum
+ + CoupEW::efvf(idAbs) * intProp * intSum
+ + CoupEW::vf2af2(idAbs) * resProp * resSum);
+
+ // Correct for the running-width Z0 propagater weight in PhaseSpace.
+ sigma /= runBW3;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2gmZg::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, 23, 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2gmZq class.
+// Cross section for q g -> gamma*/Z0 q.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qg2gmZq::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM * alpS)
+ * (1./12.) * (sH2 + uH2 + 2. * tH * s3) / (-sH * uH);
+
+ // Calculate flavour sums for final state.
+ flavSum();
+
+ // Calculate prefactors for gamma/interference/Z0 cross section terms.
+ propTerm();
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qg2gmZq::sigmaHat() {
+
+ // Combine gamma, interference and Z0 parts.
+ int idAbs = (id2 == 21) ? abs(id1) : abs(id2);
+ double sigma = sigma0
+ * ( CoupEW::ef2(idAbs) * gamProp * gamSum
+ + CoupEW::efvf(idAbs) * intProp * intSum
+ + CoupEW::vf2af2(idAbs) * resProp * resSum);
+
+ // Correct for the running-width Z0 propagater weight in PhaseSpace.
+ sigma /= runBW3;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2gmZq::setIdColAcol() {
+
+ // Flavour set up for q g -> gamma*/Z0 q.
+ int idq = (id2 == 21) ? id1 : id2;
+ setId( id1, id2, 23, idq);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2gmZgm class.
+// Cross section for f fbar -> gamma*/Z0 gamma.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2gmZgm::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM*alpEM)
+ * 0.5 * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
+
+ // Calculate flavour sums for final state.
+ flavSum();
+
+ // Calculate prefactors for gamma/interference/Z0 cross section terms.
+ propTerm();
+
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2gmZgm::sigmaHat() {
+
+ // Combine gamma, interference and Z0 parts.
+ int idAbs = abs(id1);
+ double sigma = sigma0 * CoupEW::ef2(idAbs)
+ * ( CoupEW::ef2(idAbs) * gamProp * gamSum
+ + CoupEW::efvf(idAbs) * intProp * intSum
+ + CoupEW::vf2af2(idAbs) * resProp * resSum);
+
+ // Correct for the running-width Z0 propagater weight in PhaseSpace.
+ sigma /= runBW3;
+
+ // Colour factor. Answer.
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2gmZgm::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, 23, 22);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2fgm2gmZf class.
+// Cross section for f gamma -> gamma*/Z0 f'.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2fgm2gmZf::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM*alpEM)
+ * 0.5 * (sH2 + uH2 + 2. * tH * s3) / (- sH * uH);
+
+ // Calculate flavour sums for final state.
+ flavSum();
+
+ // Calculate prefactors for gamma/interference/Z0 cross section terms.
+ propTerm();
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2fgm2gmZf::sigmaHat() {
+
+ // Combine gamma, interference and Z0 parts.
+ int idAbs = (id2 == 22) ? abs(id1) : abs(id2);
+ double sigma = sigma0 * CoupEW::ef2(idAbs)
+ * ( CoupEW::ef2(idAbs) * gamProp * gamSum
+ + CoupEW::efvf(idAbs) * intProp * intSum
+ + CoupEW::vf2af2(idAbs) * resProp * resSum);
+
+ // Correct for the running-width Z0 propagater weight in PhaseSpace.
+ sigma /= runBW3;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2fgm2gmZf::setIdColAcol() {
+
+ // Flavour set up for q gamma -> gamma*/Z0 q.
+ int idq = (id2 == 22) ? id1 : id2;
+ setId( id1, id2, 23, idq);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q gamma in.
+ swapTU = (id2 == 22);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0);
+ else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbarWggm class.
+// Collects common methods for f fbar -> W+- g/gamma and permutations.
+
+//*********
+
+// Evaluate weight for W+- decay angle.
+
+double Sigma2ffbarWggm::weightDecay( Event& process, int iResBeg, int iResEnd) {
+
+ // W should sit in entry 5 and one more parton in entry 6.
+ if (iResBeg != 5 || iResEnd != 6) return 1.;
+
+ // In an outgoing sense fermions are labelled f(1) fbar(2) f'(3) fbar'(4)
+ // where f' fbar' come from W+- decay.
+ int i1, i2;
+ int i3 = (process[7].id() > 0) ? 7 : 8;
+ int i4 = 15 - i3;
+
+ // Order so that fbar(1) f(2) -> W+- g/gamma.
+ if (process[3].idAbs() < 20 && process[4].idAbs() < 20) {
+ i1 = (process[3].id() < 0) ? 3 : 4;
+ i2 = 7 - i1;
+
+ // Order so that f(2)/fbar(1) g/gamma -> f(1)/fbar(2) f'(3) W+-.
+ } else if (process[3].idAbs() < 20) {
+ i1 = (process[3].id() < 0) ? 3 : 6;
+ i2 = 9 - i1;
+ } else {
+ i1 = (process[4].id() < 0) ? 4 : 6;
+ i2 = 10 - i1;
+ }
+
+ // Evaluate four-vector products.
+ double p13 = process[i1].p() * process[i3].p();
+ double p14 = process[i1].p() * process[i4].p();
+ double p23 = process[i2].p() * process[i3].p();
+ double p24 = process[i2].p() * process[i4].p();
+
+ // Calculate weight and its maximum.
+ double wt = pow2(p13) + pow2(p24);
+ double wtMax = pow2(p13 + p14) + pow2(p23 + p24);
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2Wg class.
+// Cross section for q qbar' -> W+- g.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2Wg::initProc() {
+
+ // Secondary open width fractions, relevant for top (or heavier).
+ openFracPos = ParticleDataTable::resOpenFrac(24);
+ openFracNeg = ParticleDataTable::resOpenFrac(-24);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qqbar2Wg::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM * alpS / CoupEW::sin2thetaW())
+ * (2./9.) * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qqbar2Wg::sigmaHat() {
+
+ // CKM factor. Secondary width for W+ or W-.
+ double sigma = sigma0 * VCKM::V2id(abs(id1), abs(id2));
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ sigma *= (idUp > 0) ? openFracPos : openFracNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2Wg::setIdColAcol() {
+
+ // Sign of outgoing W.
+ int sign = 1 - 2 * (abs(id1)%2);
+ if (id1 < 0) sign = -sign;
+ setId( id1, id2, 24 * sign, 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2Wq class.
+// Cross section for q g -> W+- q'.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2Wq::initProc() {
+
+ // Secondary open width fractions, relevant for top (or heavier).
+ openFracPos = ParticleDataTable::resOpenFrac(24);
+ openFracNeg = ParticleDataTable::resOpenFrac(-24);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qg2Wq::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM * alpS / CoupEW::sin2thetaW())
+ * (1./12.) * (sH2 + uH2 + 2. * tH * s3) / (-sH * uH);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qg2Wq::sigmaHat() {
+
+ // CKM factor. Secondary width for W+ or W-.
+ int idAbs = (id2 == 21) ? abs(id1) : abs(id2);
+ double sigma = sigma0 * VCKM::V2sum(idAbs);
+ int idUp = (id2 == 21) ? id1 : id2;
+ if (idAbs%2 == 1) idUp = -idUp;
+ sigma *= (idUp > 0) ? openFracPos : openFracNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2Wq::setIdColAcol() {
+
+ // Sign of outgoing W. Flavour of outgoing quark.
+ int idq = (id2 == 21) ? id1 : id2;
+ int sign = 1 - 2 * (abs(idq)%2);
+ if (idq < 0) sign = -sign;
+ id4 = VCKM::V2pick(idq);
+
+ // Flavour set up for q g -> W q.
+ setId( id1, id2, 24 * sign, id4);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2Wgm class.
+// Cross section for f fbar' -> W+- gamma.
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2Wgm::initProc() {
+
+ // Secondary open width fractions, relevant for top (or heavier).
+ openFracPos = ParticleDataTable::resOpenFrac(24);
+ openFracNeg = ParticleDataTable::resOpenFrac(-24);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2Wgm::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM*alpEM / CoupEW::sin2thetaW())
+ * 0.5 * (tH2 + uH2 + 2. * sH * s3) / (tH * uH);
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2Wgm::sigmaHat() {
+
+ // Extrafactor different for e nu and q qbar' instate.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ double chgUp = (id1Abs > 10) ? 0. : 2./3.;
+ double sigma = sigma0 * pow2( chgUp - tH / (tH + uH) );
+
+ // CKM and colour factors. Secondary width for W+ or W-.
+ if (id1Abs < 9) sigma *= VCKM::V2id(id1Abs, id2Abs) / 3.;
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ sigma *= (idUp > 0) ? openFracPos : openFracNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2Wgm::setIdColAcol() {
+
+ // Sign of outgoing W.
+ int sign = 1 - 2 * (abs(id1)%2);
+ if (id1 < 0) sign = -sign;
+ setId( id1, id2, 24 * sign, 22);
+
+ // tH defined between (f,W-) or (fbar',W+).
+ swapTU = (sign * id1 > 0);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2fgm2Wf class.
+// Cross section for f gamma -> W+- f'.
+
+//*********
+
+// Initialize process.
+
+void Sigma2fgm2Wf::initProc() {
+
+ // Secondary open width fractions, relevant for top (or heavier).
+ openFracPos = ParticleDataTable::resOpenFrac(24);
+ openFracNeg = ParticleDataTable::resOpenFrac(-24);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2fgm2Wf::sigmaKin() {
+
+ // Cross section part common for all incoming flavours.
+ sigma0 = (M_PI / sH2) * (alpEM*alpEM / CoupEW::sin2thetaW())
+ * 0.5 * (sH2 + uH2 + 2. * tH * s3) / (pT2 * s3 - sH * uH);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2fgm2Wf::sigmaHat() {
+
+ // Extrafactor dependent on charge of incoming fermion.
+ int idAbs = (id2 == 22) ? abs(id1) : abs(id2);
+ double charge = (idAbs > 10) ? 1. : ( (idAbs%2 == 1) ? 1./3. : 2./3. );
+ double sigma = sigma0 * pow2( charge - sH / (sH + uH) );
+
+ // CKM factor. Secondary width for W+ or W-.
+ sigma *= VCKM::V2sum(idAbs);
+ int idUp = (id2 == 22) ? id1 : id2;
+ if (idAbs%2 == 1) idUp = -idUp;
+ sigma *= (idUp > 0) ? openFracPos : openFracNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2fgm2Wf::setIdColAcol() {
+
+ // Sign of outgoing W. Flavour of outgoing fermion.
+ int idq = (id2 == 22) ? id1 : id2;
+ int sign = 1 - 2 * (abs(idq)%2);
+ if (idq < 0) sign = -sign;
+ id4 = VCKM::V2pick(idq);
+
+ // Flavour set up for q gamma -> W q.
+ setId( id1, id2, 24 * sign, id4);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q gamma in.
+ swapTU = (id2 == 22);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0);
+ else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaExtraDim.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// extra-dimensional simulation classes.
+
+#include "SigmaExtraDim.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma1gg2GravitonStar class.
+// Cross section for g g -> G* (excited graviton state).
+
+//*********
+
+// Initialize process.
+
+void Sigma1gg2GravitonStar::initProc() {
+
+ // Store G* mass and width for propagator.
+ idGstar = 5000039;
+ mRes = ParticleDataTable::m0(idGstar);
+ GammaRes = ParticleDataTable::mWidth(idGstar);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Overall coupling strength kappa * m_G*.
+ kappaMG = Settings::parm("ExtraDimensionsG*:kappaMG");
+
+ // Set pointer to particle properties and decay table.
+ gStarPtr = ParticleDataTable::particleDataPtr(idGstar);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1gg2GravitonStar::sigmaKin() {
+
+ // Incoming width for gluons.
+ double widthIn = pow2(kappaMG) * mH / (160. * M_PI);
+
+ // Set up Breit-Wigner. Width out only includes open channels.
+ double sigBW = 5. * M_PI/ ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double widthOut = gStarPtr->resWidthOpen(idGstar, mH);
+
+ // Modify cross section in wings of peak. Done.
+ sigma = widthIn * sigBW * widthOut * pow2(sH / m2Res);
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1gg2GravitonStar::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( 21, 21, idGstar);
+
+ // Colour flow topology.
+ setColAcol( 1, 2, 2, 1, 0, 0);
+
+}
+
+//*********
+
+// Evaluate weight for G* decay angle.
+
+double Sigma1gg2GravitonStar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // G* should sit in entry 5.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Phase space factors. Reconstruct decay angle.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+
+ // Default is isotropic decay.
+ double wt = 1.;
+
+ // Angular weight for g + g -> G* -> f + fbar.
+ if (process[6].idAbs() < 19) wt = 1. - pow4(cosThe);
+
+ // Angular weight for g + g -> G* -> g + g or gamma + gamma.
+ else if (process[6].id() == 21 || process[6].id() == 22)
+ wt = (1. + 6. * pow2(cosThe) + pow4(cosThe)) / 8.;
+
+ // Done.
+ return wt;
+
+}
+
+//**************************************************************************
+
+// Sigma1ffbar2GravitonStar class.
+// Cross section for f fbar -> G* (excited graviton state).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2GravitonStar::initProc() {
+
+ // Store G* mass and width for propagator.
+ idGstar = 5000039;
+ mRes = ParticleDataTable::m0(idGstar);
+ GammaRes = ParticleDataTable::mWidth(idGstar);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Overall coupling strength kappa * m_G*.
+ kappaMG = Settings::parm("ExtraDimensionsG*:kappaMG");
+
+ // Set pointer to particle properties and decay table.
+ gStarPtr = ParticleDataTable::particleDataPtr(idGstar);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2GravitonStar::sigmaKin() {
+
+ // Incoming width for fermions, disregarding colour factor.
+ double widthIn = pow2(kappaMG) * mH / (80. * M_PI);
+
+ // Set up Breit-Wigner. Width out only includes open channels.
+ double sigBW = 5. * M_PI/ ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double widthOut = gStarPtr->resWidthOpen(idGstar, mH);
+
+ // Modify cross section in wings of peak. Done.
+ sigma0 = widthIn * sigBW * widthOut * pow2(sH / m2Res);
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2GravitonStar::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, idGstar);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for G* decay angle.
+
+double Sigma1ffbar2GravitonStar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // G* should sit in entry 5.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Phase space factors. Reconstruct decay angle.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+
+ // Default is isotropic decay.
+ double wt = 1.;
+
+ // Angular weight for f + fbar -> G* -> f + fbar.
+ if (process[6].idAbs() < 19)
+ wt = (1. - 3. * pow2(cosThe) + 4. * pow4(cosThe)) / 2.;
+
+ // Angular weight for f + fbar -> G* -> g + g or gamma + gamma.
+ else if (process[6].id() == 21 || process[6].id() == 22)
+ wt = 1. - pow4(cosThe);
+
+ // Done.
+ return wt;
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2GravitonStarg class.
+// Cross section for g g -> G* g (excited graviton state).
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2GravitonStarg::initProc() {
+
+ // Store G* mass and width for propagator.
+ idGstar = 5000039;
+ mRes = ParticleDataTable::m0(idGstar);
+ GammaRes = ParticleDataTable::mWidth(idGstar);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Overall coupling strength kappa * m_G*.
+ kappaMG = Settings::parm("ExtraDimensionsG*:kappaMG");
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idGstar);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2gg2GravitonStarg::sigmaKin() {
+
+ // Evaluate cross section. Secondary width for G*.
+ sigma = (3. * pow2(kappaMG) * alpS) / (32. * sH * s3)
+ * ( pow2(tH2 + tH * uH + uH2) / (sH2 * tH * uH)
+ + 2. * (tH2 / uH + uH2 / tH) / sH + 3. * (tH / uH + uH / tH)
+ + 2. * (sH / uH + sH/tH) + sH2 / (tH * uH) );
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2GravitonStarg::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( 21, 21, idGstar, 21);
+
+ // Colour flow topologies: random choice between two mirrors.
+ if (Rndm::flat() < 0.5) setColAcol( 1, 2, 2, 3, 0, 0, 1, 3);
+ else setColAcol( 1, 2, 3, 1, 0, 0, 3, 2);
+
+}
+
+//*********
+
+// Evaluate weight for decay angles: currently G* assumed isotropic.
+
+double Sigma2gg2GravitonStarg::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // No equations for G* decay so assume isotropic.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2GravitonStarq class.
+// Cross section for q g -> G* q (excited graviton state).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2GravitonStarq::initProc() {
+
+ // Store G* mass and width for propagator.
+ idGstar = 5000039;
+ mRes = ParticleDataTable::m0(idGstar);
+ GammaRes = ParticleDataTable::mWidth(idGstar);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Overall coupling strength kappa * m_G*.
+ kappaMG = Settings::parm("ExtraDimensionsG*:kappaMG");
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idGstar);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qg2GravitonStarq::sigmaKin() {
+
+ // Evaluate cross section. Secondary width for G*.
+ sigma = -(pow2(kappaMG) * alpS) / (192. * sH * s3)
+ * ( 4. * (sH2 + uH2) / (tH * sH) + 9. * (sH + uH) / sH + sH / uH
+ + uH2 / sH2 + 3. * tH * (4. + sH / uH + uH / sH) / sH
+ + 4. * tH2 * (1. / uH + 1. / sH) / sH + 2. * tH2 * tH / (uH * sH2) );
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2GravitonStarq::setIdColAcol() {
+
+ // Flavour set up for q g -> H q.
+ int idq = (id2 == 21) ? id1 : id2;
+ setId( id1, id2, idGstar, idq);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles: currently G* assumed isotropic.
+
+double Sigma2qg2GravitonStarq::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // No equations for G* decay so assume isotropic.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2GravitonStarg class.
+// Cross section for q qbar -> G* g (excited graviton state).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2GravitonStarg::initProc() {
+
+ // Store G* mass and width for propagator.
+ idGstar = 5000039;
+ mRes = ParticleDataTable::m0(idGstar);
+ GammaRes = ParticleDataTable::mWidth(idGstar);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Overall coupling strength kappa * m_G*.
+ kappaMG = Settings::parm("ExtraDimensionsG*:kappaMG");
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idGstar);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qqbar2GravitonStarg::sigmaKin() {
+
+ // Evaluate cross section. Secondary width for G*.
+ sigma = (pow2(kappaMG) * alpS) / (72. * sH * s3)
+ * ( 4. * (tH2 + uH2) / sH2 + 9. * (tH + uH) / sH
+ + (tH2 / uH + uH2 / tH) / sH + 3. * (4. + tH / uH + uH/ tH)
+ + 4. * (sH / uH + sH / tH) + 2. * sH2 / (tH * uH) );
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2GravitonStarg::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, idGstar, 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles: currently G* assumed isotropic.
+
+double Sigma2qqbar2GravitonStarg::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // No equations for G* decay so assume isotropic.
+ return 1.;
+
+}
+
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaHiggs.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// Part of code written by Marc Montull, CERN summer student 2007.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+// Function definitions (not found in the header) for the
+// Higgs simulation classes.
+
+#include "SigmaHiggs.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma1ffbar2H class.
+// Cross section for f fbar -> H0 , H1, H2 or A3.
+// (f is quark or lepton, H0 SM Higgs and H1, H2, A3 BSM Higgses ).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2H::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "f fbar -> H (SM)";
+ codeSave = 901;
+ idRes = 25;
+ }
+ else if (higgsType == 1) {
+ nameSave = "f fbar -> h0(H1)";
+ codeSave = 1001;
+ idRes = 25;
+ }
+ else if (higgsType == 2) {
+ nameSave = "f fbar -> H0(H2)";
+ codeSave = 1021;
+ idRes = 35;
+ }
+ else if (higgsType == 3) {
+ nameSave = "f fbar -> A0(A3)";
+ codeSave = 1041;
+ idRes = 36;
+ }
+
+ // Find pointer to H0, H1, H2 or A3 depending on the value of idRes.
+ HResPtr = ParticleDataTable::particleDataPtr(idRes);
+
+ // Store H0, H1, H2 or A3 mass and width for propagator.
+ mRes = HResPtr->m0();
+ GammaRes = HResPtr->mWidth();
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+}
+
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma1ffbar2H::sigmaKin() {
+
+ // Set up Breit-Wigner.
+ double width = HResPtr->resWidth(idRes, mH);
+ sigBW = 4. * M_PI/ ( pow2(sH - m2Res) + pow2(mH * width) );
+
+ // Width out only includes open channels.
+ widthOut = width * HResPtr->resOpenFrac(idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2H::sigmaHat() {
+
+ // Calculate mass-dependent incoming width, including colour factor.
+ int idAbs = abs(id1);
+ double widthIn = HResPtr->resWidthChan( mH, idAbs, -idAbs);
+ if (idAbs < 9) widthIn /= 9.;
+
+ // Done.
+ return widthIn * sigBW * widthOut;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2H::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, idRes);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma1ffbar2H::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma1gg2H class.
+// Cross section for g g -> H0, H1, H2 or A3 (H0 SM Higgs, H1, H2, A3 BSM).
+
+//*********
+
+// Initialize process.
+
+void Sigma1gg2H::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "g g -> H (SM)";
+ codeSave = 902;
+ idRes = 25;
+ }
+ else if (higgsType == 1) {
+ nameSave = "g g -> h0(H1)";
+ codeSave = 1002;
+ idRes = 25;
+ }
+ else if (higgsType == 2) {
+ nameSave = "g g -> H0(H2)";
+ codeSave = 1022;
+ idRes = 35;
+ }
+ else if (higgsType == 3) {
+ nameSave = "g g -> A0(A3)";
+ codeSave = 1042;
+ idRes = 36;
+ }
+
+ // Find pointer to H0, H1, H2 or A3 depending on idRes.
+ HResPtr = ParticleDataTable::particleDataPtr(idRes);
+
+ // Store H0, H1, H2 or A3 mass and width for propagator.
+ mRes = HResPtr->m0();
+ GammaRes = HResPtr->mWidth();
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1gg2H::sigmaKin() {
+
+ // Incoming width for gluons, gives colour factor of 1/8 * 1/8.
+ double widthIn = HResPtr->resWidthChan( mH, 21, 21) / 64.;
+
+ // Set up Breit-Wigner.
+ double width = HResPtr->resWidth(idRes, mH);
+ double sigBW = 8. * M_PI/ ( pow2(sH - m2Res) + pow2(mH * width) );
+
+ // Width out only includes open channels.
+ double widthOut = width * HResPtr->resOpenFrac(idRes);
+
+ // Done.
+ sigma = widthIn * sigBW * widthOut;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1gg2H::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( 21, 21, idRes);
+
+ // Colour flow topology.
+ setColAcol( 1, 2, 2, 1, 0, 0);
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma1gg2H::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma1gmgm2H class.
+// Cross section for gamma gamma -> H0, H1, H2 or H3.
+// (H0 SM Higgs, H1, H2 and A3 BSM Higgses).
+
+//*********
+
+// Initialize process.
+
+void Sigma1gmgm2H::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "gamma gamma -> H (SM)";
+ codeSave = 903;
+ idRes = 25;
+ }
+ else if (higgsType == 1) {
+ nameSave = "gamma gamma -> h0(H1)";
+ codeSave = 1003;
+ idRes = 25;
+ }
+ else if (higgsType == 2) {
+ nameSave = "gamma gamma -> H0(H2)";
+ codeSave = 1023;
+ idRes = 35;
+ }
+ else if (higgsType == 3) {
+ nameSave = "gamma gamma -> A0(A3)";
+ codeSave = 1043;
+ idRes = 36;
+ }
+
+ // Find pointer to H0, H1, H2 or A3.
+ HResPtr = ParticleDataTable::particleDataPtr(idRes);
+
+ // Store H0, H1, H2 or A3 mass and width for propagator.
+ mRes = HResPtr->m0();
+ GammaRes = HResPtr->mWidth();
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1gmgm2H::sigmaKin() {
+
+ // Incoming width for photons.
+ double widthIn = HResPtr->resWidthChan( mH, 22, 22);
+
+ // Set up Breit-Wigner.
+ double width = HResPtr->resWidth(idRes, mH);
+ double sigBW = 8. * M_PI/ ( pow2(sH - m2Res) + pow2(mH * width) );
+
+ // Width out only includes open channels.
+ double widthOut = width * HResPtr->resOpenFrac(idRes);
+
+ // Done.
+ sigma = widthIn * sigBW * widthOut;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1gmgm2H::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( 22, 22, idRes);
+
+ // Colour flow trivial.
+ setColAcol( 0, 0, 0, 0, 0, 0);
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma1gmgm2H::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2HZ class.
+// Cross section for f fbar -> H0 Z0, H1 Z0, H2 Z0 or A3 Z0.
+// (H0 SM Higgs, H1, H2 and A3 BSM Higgses).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2HZ::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "f fbar -> H0 Z0 (SM)";
+ codeSave = 904;
+ idRes = 25;
+ coup2Z = 1.;
+ }
+ else if (higgsType == 1) {
+ nameSave = "f fbar -> h0(H1) Z0";
+ codeSave = 1004;
+ idRes = 25;
+ coup2Z = Settings::parm("HiggsH1:coup2Z");
+ }
+ else if (higgsType == 2) {
+ nameSave = "f fbar -> H0(H2) Z0";
+ codeSave = 1024;
+ idRes = 35;
+ coup2Z = Settings::parm("HiggsH2:coup2Z");
+ }
+ else if (higgsType == 3) {
+ nameSave = "f fbar -> A0(A3) ZO";
+ codeSave = 1044;
+ idRes = 36;
+ coup2Z = Settings::parm("HiggsA3:coup2Z");
+ }
+
+ // Store Z0 mass and width for propagator. Common coupling factor.
+ mZ = ParticleDataTable::m0(23);
+ widZ = ParticleDataTable::mWidth(23);
+ mZS = mZ*mZ;
+ mwZS = pow2(mZ * widZ);
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+ // Secondary open width fraction.
+ openFracPair = ParticleDataTable::resOpenFrac(idRes, 23);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2HZ::sigmaKin() {
+
+ // Evaluate differential cross section.
+ sigma0 = (M_PI / sH2) * 8. * pow2(alpEM * thetaWRat * coup2Z)
+ * (tH * uH - s3 * s4 + 2. * sH * s4) / (pow2(sH - mZS) + mwZS);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2HZ::sigmaHat() {
+
+ // Coupling a_f^2 + v_f^2 to s-channel Z0 and colour factor.
+ int idAbs = abs(id1);
+ double sigma = sigma0 * CoupEW::vf2af2(idAbs);
+ if (idAbs < 9) sigma /= 3.;
+
+ // Secondary width for H0 and Z0 or H1 and Z0 or H2 and Z0 or A3 and Z0.
+ sigma *= openFracPair;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2HZ::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, idRes, 23);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2ffbar2HZ::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // If not decay of Z0 created along with Higgs then done.
+ if (iResBeg != 5 || iResEnd != 6) return 1.;
+
+ // Order so that fbar(1) f(2) -> H() f'(3) fbar'(4).
+ int i1 = (process[3].id() < 0) ? 3 : 4;
+ int i2 = 7 - i1;
+ int i3 = process[6].daughter1();
+ int i4 = process[6].daughter2();
+ if (process[i3].id() < 0) swap( i3, i4);
+
+ // Find left- and righthanded couplings of fermion pairs.
+ int idAbs = process[i1].idAbs();
+ double liS = pow2( CoupEW::lf(idAbs) );
+ double riS = pow2( CoupEW::rf(idAbs) );
+ idAbs = process[i3].idAbs();
+ double lfS = pow2( CoupEW::lf(idAbs) );
+ double rfS = pow2( CoupEW::rf(idAbs) );
+
+ // Evaluate relevant four-products.
+ double pp13 = process[i1].p() * process[i3].p();
+ double pp14 = process[i1].p() * process[i4].p();
+ double pp23 = process[i2].p() * process[i3].p();
+ double pp24 = process[i2].p() * process[i4].p();
+
+ // Weight and maximum.
+ double wt = (liS * lfS + riS * rfS) * pp13 * pp24
+ + (liS * rfS + riS * lfS) * pp14 * pp23;
+ double wtMax = (liS + riS) * (lfS + rfS) * (pp13 + pp14) * (pp23 + pp24);
+
+ // Done.
+ return wt / wtMax;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2HW class.
+// Cross section for f fbar -> H0 W+-, H1 W+-, H2 W+- or A3 W+-.
+// (H0 SM Higgs, H1, H2 and A3 BSM Higgses).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2HW::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "f fbar -> H0 W+- (SM)";
+ codeSave = 905;
+ idRes = 25;
+ coup2W = 1.;
+ }
+ else if (higgsType == 1) {
+ nameSave = "f fbar -> h0(H1) W+-";
+ codeSave = 1005;
+ idRes = 25;
+ coup2W = Settings::parm("HiggsH1:coup2W");
+ }
+ else if (higgsType == 2) {
+ nameSave = "f fbar -> H0(H2) W+-";
+ codeSave = 1025;
+ idRes = 35;
+ coup2W = Settings::parm("HiggsH2:coup2W");
+ }
+ else if (higgsType == 3) {
+ nameSave = "f fbar -> A0(A3) W+-";
+ codeSave = 1045;
+ idRes = 36;
+ coup2W = Settings::parm("HiggsA3:coup2W");
+ }
+
+ // Store W+- mass and width for propagator. Common coupling factor.
+ mW = ParticleDataTable::m0(24);
+ widW = ParticleDataTable::mWidth(24);
+ mWS = mW*mW;
+ mwWS = pow2(mW * widW);
+ thetaWRat = 1. / (4. * CoupEW::sin2thetaW());
+
+ // Secondary open width fractions.
+ openFracPairPos = ParticleDataTable::resOpenFrac(idRes, 24);
+ openFracPairNeg = ParticleDataTable::resOpenFrac(idRes, -24);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2ffbar2HW::sigmaKin() {
+
+ // Evaluate differential cross section.
+ sigma0 = (M_PI / sH2) * 2. * pow2(alpEM * thetaWRat * coup2W)
+ * (tH * uH - s3 * s4 + 2. * sH * s4) / (pow2(sH - mWS) + mwWS);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2ffbar2HW::sigmaHat() {
+
+ // CKM and colour factors.
+ double sigma = sigma0;
+ if (abs(id1) < 9) sigma *= VCKM::V2id(abs(id1), abs(id2)) / 3.;
+
+ // Secondary width for H0 and W+-.
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ sigma *= (idUp > 0) ? openFracPairPos : openFracPairNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2HW::setIdColAcol() {
+
+ // Sign of outgoing W.
+ int sign = 1 - 2 * (abs(id1)%2);
+ if (id1 < 0) sign = -sign;
+ setId( id1, id2, idRes, 24 * sign);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2ffbar2HW::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // If not decay of W+- created along with Higgs then done.
+ if (iResBeg != 5 || iResEnd != 6) return 1.;
+
+ // Order so that fbar(1) f(2) -> H() f'(3) fbar'(4).
+ int i1 = (process[3].id() < 0) ? 3 : 4;
+ int i2 = 7 - i1;
+ int i3 = process[6].daughter1();
+ int i4 = process[6].daughter2();
+ if (process[i3].id() < 0) swap( i3, i4);
+
+ // Evaluate relevant four-products.
+ double pp13 = process[i1].p() * process[i3].p();
+ double pp14 = process[i1].p() * process[i4].p();
+ double pp23 = process[i2].p() * process[i3].p();
+ double pp24 = process[i2].p() * process[i4].p();
+
+ // Weight and maximum.
+ double wt = pp13 * pp24;
+ double wtMax = (pp13 + pp14) * (pp23 + pp24);
+
+ // Done.
+ return wt / wtMax;
+
+}
+
+//**************************************************************************
+
+// Sigma3ff2HfftZZ class.
+// Cross section for f f' -> H f f' (Z0 Z0 fusion of SM or BSM Higgs).
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+//*********
+
+// Initialize process.
+
+void Sigma3ff2HfftZZ::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "f f' -> H0 f f'(Z0 Z0 fusion) (SM)";
+ codeSave = 906;
+ idRes = 25;
+ coup2Z = 1.;
+ }
+ else if (higgsType == 1) {
+ nameSave = "f f' -> h0(H1) f f' (Z0 Z0 fusion)";
+ codeSave = 1006;
+ idRes = 25;
+ coup2Z = Settings::parm("HiggsH1:coup2Z");
+ }
+ else if (higgsType == 2) {
+ nameSave = "f f' -> H0(H2) f f' (Z0 Z0 fusion)";
+ codeSave = 1026;
+ idRes = 35;
+ coup2Z = Settings::parm("HiggsH2:coup2Z");
+ }
+ else if (higgsType == 3) {
+ nameSave = "f f' -> A0(A3) f f' (Z0 Z0 fusion)";
+ codeSave = 1046;
+ idRes = 36;
+ coup2Z = Settings::parm("HiggsA3:coup2Z");
+ }
+
+ // Common fixed mass and coupling factor.
+ mZS = pow2( ParticleDataTable::m0(23) );
+ prefac = 0.25 * mZS
+ * pow3( 4. * M_PI / (CoupEW::sin2thetaW() * CoupEW::cos2thetaW()) );
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma3ff2HfftZZ::sigmaKin() {
+
+ // Required four-vector products.
+ double pp12 = 0.5 * sH;
+ double pp14 = 0.5 * mH * p4cm.pMinus();
+ double pp15 = 0.5 * mH * p5cm.pMinus();
+ double pp24 = 0.5 * mH * p4cm.pPlus();
+ double pp25 = 0.5 * mH * p5cm.pPlus();
+ double pp45 = p4cm * p5cm;
+
+ // Propagator factors and two possible numerators.
+ double prop = pow2( (2. * pp14 + mZS) * (2. * pp25 + mZS) );
+ sigma1 = prefac * pp12 * pp45 / prop;
+ sigma2 = prefac * pp15 * pp24 / prop;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma3ff2HfftZZ::sigmaHat() {
+
+ // Flavour-dependent coupling factors for two incoming flavours.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ double lf1S = pow2( CoupEW::lf(id1Abs) );
+ double rf1S = pow2( CoupEW::rf(id1Abs) );
+ double lf2S = pow2( CoupEW::lf(id2Abs) );
+ double rf2S = pow2( CoupEW::rf(id2Abs) );
+ double c1 = lf1S * lf2S + rf1S * rf2S;
+ double c2 = lf1S * rf2S + rf1S * lf2S;
+
+ // Combine couplings and kinematics factors.
+ double sigma = pow3(alpEM) * (c1 * sigma1 + c2 * sigma2) * pow2(coup2Z);
+
+ // Secondary width for H0, H1, H2 or A3.
+ sigma *= openFrac;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma3ff2HfftZZ::setIdColAcol() {
+
+ // Trivial flavours: out = in.
+ setId( id1, id2, idRes, id1, id2);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9 && abs(id2) < 9 && id1*id2 > 0)
+ setColAcol( 1, 0, 2, 0, 0, 0, 1, 0, 2, 0);
+ else if (abs(id1) < 9 && abs(id2) < 9)
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 0, 0, 2);
+ else if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0, 0, 0);
+ else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ if ( (abs(id1) < 9 && id1 < 0) || (abs(id1) > 10 && id2 < 0) )
+ swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma3ff2HfftZZ::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma3ff2HfftWW class.
+// Cross section for f_1 f_2 -> H0 f_3 f_4 (W+ W- fusion of SM or BSM Higgs).
+
+//*********
+
+// Initialize process.
+
+void Sigma3ff2HfftWW::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "f_1 f_2 -> H0 f_3 f_4 (W+ W- fusion) (SM)";
+ codeSave = 907;
+ idRes = 25;
+ coup2W = 1.;
+ }
+ else if (higgsType == 1) {
+ nameSave = "f_1 f_2 -> h0(H1) f_3 f_4 (W+ W- fusion)";
+ codeSave = 1007;
+ idRes = 25;
+ coup2W = Settings::parm("HiggsH1:coup2W");
+ }
+ else if (higgsType == 2) {
+ nameSave = "f_1 f_2 -> H0(H2) f_3 f_4 (W+ W- fusion)";
+ codeSave = 1027;
+ idRes = 35;
+ coup2W = Settings::parm("HiggsH2:coup2W");
+ }
+ else if (higgsType == 3) {
+ nameSave = "f_1 f_2 -> A0(A3) f_3 f_4 (W+ W- fusion)";
+ codeSave = 1047;
+ idRes = 36;
+ coup2W = Settings::parm("HiggsA3:coup2W");
+ }
+
+ // Common fixed mass and coupling factor.
+ mWS = pow2( ParticleDataTable::m0(24) );
+ prefac = mWS * pow3( 4. * M_PI / CoupEW::sin2thetaW() );
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma3ff2HfftWW::sigmaKin() {
+
+ // Required four-vector products.
+ double pp12 = 0.5 * sH;
+ double pp14 = 0.5 * mH * p4cm.pMinus();
+ double pp25 = 0.5 * mH * p5cm.pPlus();
+ double pp45 = p4cm * p5cm;
+
+ // Cross section: kinematics part. Combine with couplings.
+ double prop = pow2( (2. * pp14 + mWS) * (2. * pp25 + mWS) );
+ sigma0 = prefac * pp12 * pp45 * pow2(coup2W) / prop;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma3ff2HfftWW::sigmaHat() {
+
+ // Some flavour combinations not possible.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ if ( (id1Abs%2 == id2Abs%2 && id1 * id2 > 0)
+ || (id1Abs%2 != id2Abs%2 && id1 * id2 < 0) ) return 0.;
+
+ // Basic cross section. CKM factors for final states.
+ double sigma = sigma0 * pow3(alpEM) * VCKM::V2sum(id1Abs)
+ * VCKM::V2sum(id2Abs);
+
+ // Secondary width for H0, H1, H2 or A3.
+ sigma *= openFrac;
+
+ // Spin-state extra factor 2 per incoming neutrino.
+ if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
+ if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma3ff2HfftWW::setIdColAcol() {
+
+ // Pick out-flavours by relative CKM weights.
+ id4 = VCKM::V2pick(id1);
+ id5 = VCKM::V2pick(id2);
+ setId( id1, id2, idRes, id4, id5);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9 && abs(id2) < 9 && id1*id2 > 0)
+ setColAcol( 1, 0, 2, 0, 0, 0, 1, 0, 2, 0);
+ else if (abs(id1) < 9 && abs(id2) < 9)
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 0, 0, 2);
+ else if (abs(id1) < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0, 0, 0);
+ else if (abs(id2) < 9) setColAcol( 0, 0, 1, 0, 0, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ if ( (abs(id1) < 9 && id1 < 0) || (abs(id1) > 10 && id2 < 0) )
+ swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma3ff2HfftWW::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma3gg2HQQbar class.
+// Cross section for g g -> H0 Q Qbar (Q Qbar fusion of SM or BSM Higgs).
+
+//*********
+
+// Initialize process.
+
+void Sigma3gg2HQQbar::initProc() {
+
+ // Properties specific to Higgs state for the "g g -> H ttbar" process.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ if (higgsType == 0 && idNew == 6) {
+ nameSave = "g g -> H t tbar (SM)";
+ codeSave = 908;
+ idRes = 25;
+ coup2Q = 1.;
+ }
+ else if (higgsType == 1 && idNew == 6) {
+ nameSave = "g g -> h0(H1) t tbar";
+ codeSave = 1008;
+ idRes = 25;
+ coup2Q = Settings::parm("HiggsH1:coup2u");
+ }
+ else if (higgsType == 2 && idNew == 6) {
+ nameSave = "g g -> H0(H2) t tbar";
+ codeSave = 1028;
+ idRes = 35;
+ coup2Q = Settings::parm("HiggsH2:coup2u");
+ }
+ else if (higgsType == 3 && idNew == 6) {
+ nameSave = "g g -> A0(A3) t tbar";
+ codeSave = 1048;
+ idRes = 36;
+ coup2Q = Settings::parm("HiggsA3:coup2u");
+ }
+
+ // Properties specific to Higgs state for the "g g -> H b bbar" process.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ if (higgsType == 0 && idNew == 5) {
+ nameSave = "g g -> H b bbar (SM)";
+ codeSave = 912;
+ idRes = 25;
+ coup2Q = 1.;
+ }
+ else if (higgsType == 1 && idNew == 5) {
+ nameSave = "g g -> h0(H1) b bbar";
+ codeSave = 1012;
+ idRes = 25;
+ coup2Q = Settings::parm("HiggsH1:coup2d");
+ }
+ else if (higgsType == 2 && idNew == 5) {
+ nameSave = "g g -> H0(H2) b bbar";
+ codeSave = 1032;
+ idRes = 35;
+ coup2Q = Settings::parm("HiggsH2:coup2d");
+ }
+ else if (higgsType == 3 && idNew == 5) {
+ nameSave = "g g -> A0(A3) b bbar";
+ codeSave = 1052;
+ idRes = 36;
+ coup2Q = Settings::parm("HiggsA3:coup2d");
+ }
+
+ // Common mass and coupling factors.
+ double mWS = pow2(ParticleDataTable::m0(24));
+ prefac = (4. * M_PI / CoupEW::sin2thetaW()) * pow2(4. * M_PI)
+ * 0.25 / mWS;
+
+ // Secondary open width fraction.
+ openFracTriplet = ParticleDataTable::resOpenFrac(idRes, idNew, -idNew);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma3gg2HQQbar::sigmaKin() {
+
+ // Running mass of heavy quark.
+ double mQ2run = pow2( ParticleDataTable::mRun(idNew, mH) );
+
+ // Linear combination of p_Q and p_Qbar to ensure common mass.
+ double mQ2 = m4 * m5;
+ double epsi = 0.;
+ if (m4 != m5) {
+ double s45 = (p4cm + p5cm).m2Calc();
+ mQ2 = 0.5 * (s4 + s5) - 0.25 * pow2(s4 - s5) / s45;
+ epsi = 0.5 * (s5 - s4) / s45;
+ }
+
+ // Set up kinematics: g(4) g(5) -> H(3) Q(1) Qbar(2) in outgoing sense.
+ Vec4 pTemp[6];
+ pTemp[4] = Vec4( 0., 0., -0.5* mH, -0.5* mH);
+ pTemp[5] = Vec4( 0., 0., 0.5* mH, -0.5* mH);
+ pTemp[1] = p4cm + epsi * (p4cm + p5cm);
+ pTemp[2] = p5cm - epsi * (p4cm + p5cm);
+ pTemp[3] = p3cm;
+
+ // Four-product combinations.
+ double z1 = pTemp[1] * pTemp[2];
+ double z2 = pTemp[1] * pTemp[3];
+ double z3 = pTemp[1] * pTemp[4];
+ double z4 = pTemp[1] * pTemp[5];
+ double z5 = pTemp[2] * pTemp[3];
+ double z6 = pTemp[2] * pTemp[4];
+ double z7 = pTemp[2] * pTemp[5];
+ double z8 = pTemp[3] * pTemp[4];
+ double z9 = pTemp[3] * pTemp[5];
+ double z10 = pTemp[4] * pTemp[5];
+
+ // Powers required as shorthand in matriz elements.
+ double mQ4 = mQ2 * mQ2;
+ double mQ6 = mQ2 * mQ4;
+ double z1S = z1 * z1;
+ double z2S = z2 * z2;
+ double z3S = z3 * z3;
+ double z4S = z4 * z4;
+ double z5S = z5 * z5;
+ double z6S = z6 * z6;
+ double z7S = z7 * z7;
+ double z8S = z8 * z8;
+ double z9S = z9 * z9;
+ double z10S = z10 * z10;
+
+ // Evaluate matriz elements for g + g -> Q + Qbar + H.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ double fm[9][9];
+ fm[1][1] = 64*mQ6+16*mQ4*s3+32*mQ4*(z1+2*z2+z4+z9+2*
+ z7+z5)+8*mQ2*s3*(-z1-z4+2*z7)+16*mQ2*(z2*z9+4*z2*
+ z7+z2*z5-2*z4*z7-2*z9*z7)+8*s3*z4*z7-16*z2*z9*z7;
+ fm[1][2] = 16*mQ6+8*mQ4*(-2*z1+z2-2*z3-2*z4-4*z10+z9-z8+2
+ *z7-4*z6+z5)+8*mQ2*(-2*z1*z2-2*z2*z4-2*z2*z10+z2*z7-2*
+ z2*z6-2*z3*z7+2*z4*z7+4*z10*z7-z9*z7-z8*z7)+16*z2*z7*(z4+
+ z10);
+ fm[1][3] = 16*mQ6-4*mQ4*s3+8*mQ4*(-2*z1+2*z2-2*z3-4*
+ z4-8*z10+z9+z8-2*z7-4*z6+2*z5)-(4*mQ2*s3)*(z1+z4+z10
+ +z6)+8*mQ2*(-2*z1*z2-2*z1*z10+z1*z9+z1*z8-2*z1*z5+z2S
+ -4*z2*z4-5*z2*z10+z2*z8-z2*z7-3*z2*z6+z2*z5+z3*z9+2*z3*z7
+ -z3*z5+z4*z8+2*z4*z6-3*z4*z5-5*z10*z5+z9*z8+z9*z6+z9*z5+
+ z8*z7-4*z6*z5+z5S)-(16*z2*z5)*(z1+z4+z10+z6);
+ fm[1][4] = 16*mQ6+4*mQ4*s3+16*mQ4*(-z1+z2-z3-z4+z10-
+ z9-z8+2*z7+2*z6-z5)+4*mQ2*s3*(z1+z3+z4+z10+2*z7+2*z6
+ )+8*mQ2*(4*z1*z10+4*z1*z7+4*z1*z6+2*z2*z10-z2*z9-z2*z8+
+ 4*z2*z7+4*z2*z6-z2*z5+4*z10*z5+4*z7*z5+4*z6*z5)-(8*s3*
+ z1)*(z10+z7+z6)+16*z2*z5*(z10+z7+z6);
+ fm[1][5] = 8*mQ4*(-2*z1-2*z4+z10-z9)+4*mQ2*(4*z1S-2*z1*
+ z2+8*z1*z3+6*z1*z10-2*z1*z9+4*z1*z8+4*z1*z7+4*z1*z6+2*z1*
+ z5+z2*z10+4*z3*z4-z3*z9+2*z3*z7+3*z4*z8-2*z4*z6+2*z4*z5-4
+ *z10*z7+3*z10*z5-3*z9*z6+3*z8*z7-4*z7S+4*z7*z5)+8*(z1S
+ *z9-z1S*z8-z1*z2*z7+z1*z2*z6+z1*z3*z9+z1*z3*z5-z1*z4*
+ z8-z1*z4*z5+z1*z10*z9+z1*z9*z7+z1*z9*z6-z1*z8*z7-z2*z3*z7
+ +z2*z4*z6-z2*z10*z7-z2*z7S+z3*z7*z5-z4*z10*z5-z4*z7*z5-
+ z4*z6*z5);
+ fm[1][6] = 16*mQ4*(-4*z1-z4+z9-z7)+4*mQ2*s3*(-2*z1-z4-
+ z7)+16*mQ2*(-2*z1S-3*z1*z2-2*z1*z4-3*z1*z9-2*z1*z7-3*
+ z1*z5-2*z2*z4-2*z7*z5)-8*s3*z4*z7+8*(-z1*z2*z9-2*z1*z2
+ *z5-z1*z9S-z1*z9*z5+z2S*z7-z2*z4*z5+z2*z9*z7-z2*z7*z5
+ +z4*z9*z5+z4*z5S);
+ fm[1][7] = 8*mQ4*(2*z3+z4+3*z10+z9+2*z8+3*z7+6*z6)+2*mQ2*
+ s3*(-2*z3-z4+3*z10+3*z7+6*z6)+4*mQ2*(4*z1*z10+4*z1*
+ z7+8*z1*z6+6*z2*z10+z2*z9+2*z2*z8+6*z2*z7+12*z2*z6-8*z3*
+ z7+4*z4*z7+4*z4*z6+4*z10*z5+4*z9*z7+4*z9*z6-8*z8*z7+4*z7*
+ z5+8*z6*z5)+4*s3*(-z1*z10-z1*z7-2*z1*z6+2*z3*z7-z4*z7-
+ z4*z6)+8*z2*(z10*z5+z9*z7+z9*z6-2*z8*z7+z7*z5+2*z6*z5);
+ fm[1][8] = 8*mQ4*(2*z3+z4+3*z10+2*z9+z8+3*z7+6*z6)+2*mQ2*
+ s3*(-2*z3-z4+2*z10+z7+2*z6)+4*mQ2*(4*z1*z10-2*z1*z9+
+ 2*z1*z8+4*z1*z7+8*z1*z6+5*z2*z10+2*z2*z9+z2*z8+4*z2*z7+8*
+ z2*z6-z3*z9-8*z3*z7+2*z3*z5+2*z4*z9-z4*z8+4*z4*z7+4*z4*z6
+ +4*z4*z5+5*z10*z5+z9S-z9*z8+2*z9*z7+5*z9*z6+z9*z5-7*z8*
+ z7+2*z8*z5+2*z7*z5+10*z6*z5)+2*s3*(-z1*z10+z3*z7-2*z4*
+ z7+z4*z6)+4*(-z1*z9S+z1*z9*z8-2*z1*z9*z5-z1*z8*z5+2*z2*
+ z10*z5+z2*z9*z7+z2*z9*z6-2*z2*z8*z7+3*z2*z6*z5+z3*z9*z5+
+ z3*z5S+z4*z9*z5-2*z4*z8*z5+2*z4*z5S);
+ fm[2][2] = 16*mQ6+16*mQ4*(-z1+z3-z4-z10+z7-z6)+16*mQ2*(
+ z3*z10+z3*z7+z3*z6+z4*z7+z10*z7)-16*z3*z10*z7;
+ fm[2][3] = 16*mQ6+8*mQ4*(-2*z1+z2+2*z3-4*z4-4*z10-z9+z8-2
+ *z7-2*z6+z5)+8*mQ2*(-2*z1*z5+4*z3*z10-z3*z9-z3*z8-2*z3*
+ z7+2*z3*z6+z3*z5-2*z4*z5-2*z10*z5-2*z6*z5)+16*z3*z5*(z10+
+ z6);
+ fm[2][4] = 8*mQ4*(-2*z1-2*z3+z10-z8)+4*mQ2*(4*z1S-2*z1*
+ z2+8*z1*z4+6*z1*z10+4*z1*z9-2*z1*z8+4*z1*z7+4*z1*z6+2*z1*
+ z5+z2*z10+4*z3*z4+3*z3*z9-2*z3*z7+2*z3*z5-z4*z8+2*z4*z6-4
+ *z10*z6+3*z10*z5+3*z9*z6-3*z8*z7-4*z6S+4*z6*z5)+8*(-z1S
+ *z9+z1S*z8+z1*z2*z7-z1*z2*z6-z1*z3*z9-z1*z3*z5+z1*z4
+ *z8+z1*z4*z5+z1*z10*z8-z1*z9*z6+z1*z8*z7+z1*z8*z6+z2*z3*
+ z7-z2*z4*z6-z2*z10*z6-z2*z6S-z3*z10*z5-z3*z7*z5-z3*z6*
+ z5+z4*z6*z5);
+ fm[2][5] = 16*mQ4*z10+8*mQ2*(2*z1S+2*z1*z3+2*z1*z4+2*z1
+ *z10+2*z1*z7+2*z1*z6+z3*z7+z4*z6)+8*(-2*pow3(z1)-2*z1S*z3-
+ 2*z1S*z4-2*z1S*z10-2*z1S*z7-2*z1S*z6-2*z1*z3*z4-
+ z1*z3*z10-2*z1*z3*z6-z1*z4*z10-2*z1*z4*z7-z1*z10S-z1*
+ z10*z7-z1*z10*z6-2*z1*z7*z6+z3S*z7-z3*z4*z7-z3*z4*z6+z3
+ *z10*z7+z3*z7S-z3*z7*z6+z4S*z6+z4*z10*z6-z4*z7*z6+z4*
+ z6S);
+ fm[2][6] = 8*mQ4*(-2*z1+z10-z9-2*z7)+4*mQ2*(4*z1S+2*z1*
+ z2+4*z1*z3+4*z1*z4+6*z1*z10-2*z1*z9+4*z1*z8+8*z1*z6-2*z1*
+ z5+4*z2*z4+3*z2*z10+2*z2*z7-3*z3*z9-2*z3*z7-4*z4S-4*z4*
+ z10+3*z4*z8+2*z4*z6+z10*z5-z9*z6+3*z8*z7+4*z7*z6)+8*(z1S
+ *z9-z1S*z8-z1*z2*z7+z1*z2*z6+z1*z3*z9+z1*z3*z5+z1*z4*
+ z9-z1*z4*z8-z1*z4*z5+z1*z10*z9+z1*z9*z6-z1*z8*z7-z2*z3*z7
+ -z2*z4*z7+z2*z4*z6-z2*z10*z7+z3*z7*z5-z4S*z5-z4*z10*z5-
+ z4*z6*z5);
+ fm[2][7] = 8*mQ4*(z3+2*z4+3*z10+z7+2*z6)+4*mQ2*(-4*z1*z3-
+ 2*z1*z4-2*z1*z10+z1*z9-z1*z8-4*z1*z7-2*z1*z6+z2*z3+2*z2*
+ z4+3*z2*z10+z2*z7+2*z2*z6-6*z3*z4-6*z3*z10-2*z3*z9-2*z3*
+ z7-4*z3*z6-z3*z5-6*z4S-6*z4*z10-3*z4*z9-z4*z8-4*z4*z7-2
+ *z4*z6-2*z4*z5-3*z10*z9-3*z10*z8-6*z10*z7-6*z10*z6+z10*z5
+ +z9*z7-2*z8*z7-2*z8*z6-6*z7*z6+z7*z5-6*z6S+2*z6*z5)+4*(
+ -z1S*z9+z1S*z8-2*z1*z2*z10-3*z1*z2*z7-3*z1*z2*z6+z1*
+ z3*z9-z1*z3*z5+z1*z4*z9+z1*z4*z8+z1*z4*z5+z1*z10*z9+z1*
+ z10*z8-z1*z9*z6+z1*z8*z6+z2*z3*z7-3*z2*z4*z7-z2*z4*z6-3*
+ z2*z10*z7-3*z2*z10*z6-3*z2*z7*z6-3*z2*z6S-2*z3*z4*z5-z3
+ *z10*z5-z3*z6*z5-z4S*z5-z4*z10*z5+z4*z6*z5);
+ fm[2][8] = 8*mQ4*(z3+2*z4+3*z10+z7+2*z6)+4*mQ2*(-4*z1*z3-
+ 2*z1*z4-2*z1*z10-z1*z9+z1*z8-4*z1*z7-2*z1*z6+z2*z3+2*z2*
+ z4+z2*z10-z2*z7-2*z2*z6-6*z3*z4-6*z3*z10-2*z3*z9+z3*z8-2*
+ z3*z7-4*z3*z6+z3*z5-6*z4S-6*z4*z10-2*z4*z9-4*z4*z7-2*z4
+ *z6+2*z4*z5-3*z10*z9-3*z10*z8-6*z10*z7-6*z10*z6+3*z10*z5-
+ z9*z6-2*z8*z7-3*z8*z6-6*z7*z6+z7*z5-6*z6S+2*z6*z5)+4*(
+ z1S*z9-z1S*z8-z1*z2*z7+z1*z2*z6-3*z1*z3*z5+z1*z4*z9-
+ z1*z4*z8-3*z1*z4*z5+z1*z10*z9+z1*z10*z8-2*z1*z10*z5+z1*z9
+ *z6+z1*z8*z7+z1*z8*z6-z2*z4*z7+z2*z4*z6-z2*z10*z7-z2*z10*
+ z6-2*z2*z7*z6-z2*z6S-3*z3*z4*z5-3*z3*z10*z5+z3*z7*z5-3*
+ z3*z6*z5-3*z4S*z5-3*z4*z10*z5-z4*z6*z5);
+ fm[3][3] = 64*mQ6+16*mQ4*s3+32*mQ4*(z1+z2+2*z3+z8+z6
+ +2*z5)+8*mQ2*s3*(-z1+2*z3-z6)+16*mQ2*(z2*z5-2*z3*
+ z8-2*z3*z6+4*z3*z5+z8*z5)+8*s3*z3*z6-16*z3*z8*z5;
+ fm[3][4] = 16*mQ4*(-4*z1-z3+z8-z6)+4*mQ2*s3*(-2*z1-z3-
+ z6)+16*mQ2*(-2*z1S-3*z1*z2-2*z1*z3-3*z1*z8-2*z1*z6-3*
+ z1*z5-2*z2*z3-2*z6*z5)-8*s3*z3*z6+8*(-z1*z2*z8-2*z1*z2
+ *z5-z1*z8S-z1*z8*z5+z2S*z6-z2*z3*z5+z2*z8*z6-z2*z6*z5
+ +z3*z8*z5+z3*z5S);
+ fm[3][5] = 8*mQ4*(-2*z1+z10-z8-2*z6)+4*mQ2*(4*z1S+2*z1*
+ z2+4*z1*z3+4*z1*z4+6*z1*z10+4*z1*z9-2*z1*z8+8*z1*z7-2*z1*
+ z5+4*z2*z3+3*z2*z10+2*z2*z6-4*z3S-4*z3*z10+3*z3*z9+2*z3
+ *z7-3*z4*z8-2*z4*z6+z10*z5+3*z9*z6-z8*z7+4*z7*z6)+8*(-z1S
+ *z9+z1S*z8+z1*z2*z7-z1*z2*z6-z1*z3*z9+z1*z3*z8-z1*z3
+ *z5+z1*z4*z8+z1*z4*z5+z1*z10*z8-z1*z9*z6+z1*z8*z7+z2*z3*
+ z7-z2*z3*z6-z2*z4*z6-z2*z10*z6-z3S*z5-z3*z10*z5-z3*z7*
+ z5+z4*z6*z5);
+ fm[3][6] = 16*mQ6+4*mQ4*s3+16*mQ4*(-z1-z2+2*z3+2*z4+
+ z10-z9-z8-z7-z6+z5)+4*mQ2*s3*(z1+2*z3+2*z4+z10+z7+z6
+ )+8*mQ2*(4*z1*z3+4*z1*z4+4*z1*z10+4*z2*z3+4*z2*z4+4*z2*
+ z10-z2*z5+4*z3*z5+4*z4*z5+2*z10*z5-z9*z5-z8*z5)-(8*s3*
+ z1)*(z3+z4+z10)+16*z2*z5*(z3+z4+z10);
+ fm[3][7] = 8*mQ4*(3*z3+6*z4+3*z10+z9+2*z8+2*z7+z6)+2*mQ2*
+ s3*(z3+2*z4+2*z10-2*z7-z6)+4*mQ2*(4*z1*z3+8*z1*z4+4*
+ z1*z10+2*z1*z9-2*z1*z8+2*z2*z3+10*z2*z4+5*z2*z10+2*z2*z9+
+ z2*z8+2*z2*z7+4*z2*z6-7*z3*z9+2*z3*z8-8*z3*z7+4*z3*z6+4*
+ z3*z5+5*z4*z8+4*z4*z6+8*z4*z5+5*z10*z5-z9*z8-z9*z6+z9*z5+
+ z8S-z8*z7+2*z8*z6+2*z8*z5)+2*s3*(-z1*z10+z3*z7-2*z3*
+ z6+z4*z6)+4*(-z1*z2*z9-2*z1*z2*z8+z1*z9*z8-z1*z8S+z2S
+ *z7+2*z2S*z6+3*z2*z4*z5+2*z2*z10*z5-2*z2*z9*z6+z2*z8*z7
+ +z2*z8*z6-2*z3*z9*z5+z3*z8*z5+z4*z8*z5);
+ fm[3][8] = 8*mQ4*(3*z3+6*z4+3*z10+2*z9+z8+2*z7+z6)+2*mQ2*
+ s3*(3*z3+6*z4+3*z10-2*z7-z6)+4*mQ2*(4*z1*z3+8*z1*z4+
+ 4*z1*z10+4*z2*z3+8*z2*z4+4*z2*z10-8*z3*z9+4*z3*z8-8*z3*z7
+ +4*z3*z6+6*z3*z5+4*z4*z8+4*z4*z6+12*z4*z5+6*z10*z5+2*z9*
+ z5+z8*z5)+4*s3*(-z1*z3-2*z1*z4-z1*z10+2*z3*z7-z3*z6-z4
+ *z6)+8*z5*(z2*z3+2*z2*z4+z2*z10-2*z3*z9+z3*z8+z4*z8);
+ fm[4][4] = 64*mQ6+16*mQ4*s3+32*mQ4*(z1+2*z2+z3+z8+2*
+ z6+z5)+8*mQ2*s3*(-z1-z3+2*z6)+16*mQ2*(z2*z8+4*z2*
+ z6+z2*z5-2*z3*z6-2*z8*z6)+8*s3*z3*z6-16*z2*z8*z6;
+ fm[4][5] = 16*mQ6+8*mQ4*(-2*z1+z2-2*z3-2*z4-4*z10-z9+z8-4
+ *z7+2*z6+z5)+8*mQ2*(-2*z1*z2-2*z2*z3-2*z2*z10-2*z2*z7+
+ z2*z6+2*z3*z6-2*z4*z6+4*z10*z6-z9*z6-z8*z6)+16*z2*z6*(z3+
+ z10);
+ fm[4][6] = 16*mQ6-4*mQ4*s3+8*mQ4*(-2*z1+2*z2-4*z3-2*
+ z4-8*z10+z9+z8-4*z7-2*z6+2*z5)-(4*mQ2*s3)*(z1+z3+z10
+ +z7)+8*mQ2*(-2*z1*z2-2*z1*z10+z1*z9+z1*z8-2*z1*z5+z2S
+ -4*z2*z3-5*z2*z10+z2*z9-3*z2*z7-z2*z6+z2*z5+z3*z9+2*z3*z7
+ -3*z3*z5+z4*z8+2*z4*z6-z4*z5-5*z10*z5+z9*z8+z9*z6+z8*z7+
+ z8*z5-4*z7*z5+z5S)-(16*z2*z5)*(z1+z3+z10+z7);
+ fm[4][7] = 8*mQ4*(-z3-2*z4-3*z10-2*z9-z8-6*z7-3*z6)+2*mQ2
+ *s3*(z3+2*z4-3*z10-6*z7-3*z6)+4*mQ2*(-4*z1*z10-8*z1*
+ z7-4*z1*z6-6*z2*z10-2*z2*z9-z2*z8-12*z2*z7-6*z2*z6-4*z3*
+ z7-4*z3*z6+8*z4*z6-4*z10*z5+8*z9*z6-4*z8*z7-4*z8*z6-8*z7*
+ z5-4*z6*z5)+4*s3*(z1*z10+2*z1*z7+z1*z6+z3*z7+z3*z6-2*
+ z4*z6)+8*z2*(-z10*z5+2*z9*z6-z8*z7-z8*z6-2*z7*z5-z6*z5);
+ fm[4][8] = 8*mQ4*(-z3-2*z4-3*z10-z9-2*z8-6*z7-3*z6)+2*mQ2
+ *s3*(z3+2*z4-2*z10-2*z7-z6)+4*mQ2*(-4*z1*z10-2*z1*z9
+ +2*z1*z8-8*z1*z7-4*z1*z6-5*z2*z10-z2*z9-2*z2*z8-8*z2*z7-4
+ *z2*z6+z3*z9-2*z3*z8-4*z3*z7-4*z3*z6-4*z3*z5+z4*z8+8*z4*
+ z6-2*z4*z5-5*z10*z5+z9*z8+7*z9*z6-2*z9*z5-z8S-5*z8*z7-2
+ *z8*z6-z8*z5-10*z7*z5-2*z6*z5)+2*s3*(z1*z10-z3*z7+2*z3
+ *z6-z4*z6)+4*(-z1*z9*z8+z1*z9*z5+z1*z8S+2*z1*z8*z5-2*z2
+ *z10*z5+2*z2*z9*z6-z2*z8*z7-z2*z8*z6-3*z2*z7*z5+2*z3*z9*
+ z5-z3*z8*z5-2*z3*z5S-z4*z8*z5-z4*z5S);
+ fm[5][5] = 16*mQ6+16*mQ4*(-z1-z3+z4-z10-z7+z6)+16*mQ2*(
+ z3*z6+z4*z10+z4*z7+z4*z6+z10*z6)-16*z4*z10*z6;
+ fm[5][6] = 16*mQ6+8*mQ4*(-2*z1+z2-4*z3+2*z4-4*z10+z9-z8-2
+ *z7-2*z6+z5)+8*mQ2*(-2*z1*z5-2*z3*z5+4*z4*z10-z4*z9-z4*
+ z8+2*z4*z7-2*z4*z6+z4*z5-2*z10*z5-2*z7*z5)+16*z4*z5*(z10+
+ z7);
+ fm[5][7] = 8*mQ4*(-2*z3-z4-3*z10-2*z7-z6)+4*mQ2*(2*z1*z3+
+ 4*z1*z4+2*z1*z10+z1*z9-z1*z8+2*z1*z7+4*z1*z6-2*z2*z3-z2*
+ z4-3*z2*z10-2*z2*z7-z2*z6+6*z3S+6*z3*z4+6*z3*z10+z3*z9+
+ 3*z3*z8+2*z3*z7+4*z3*z6+2*z3*z5+6*z4*z10+2*z4*z8+4*z4*z7+
+ 2*z4*z6+z4*z5+3*z10*z9+3*z10*z8+6*z10*z7+6*z10*z6-z10*z5+
+ 2*z9*z7+2*z9*z6-z8*z6+6*z7S+6*z7*z6-2*z7*z5-z6*z5)+4*(-
+ z1S*z9+z1S*z8+2*z1*z2*z10+3*z1*z2*z7+3*z1*z2*z6-z1*z3
+ *z9-z1*z3*z8-z1*z3*z5-z1*z4*z8+z1*z4*z5-z1*z10*z9-z1*z10*
+ z8-z1*z9*z7+z1*z8*z7+z2*z3*z7+3*z2*z3*z6-z2*z4*z6+3*z2*
+ z10*z7+3*z2*z10*z6+3*z2*z7S+3*z2*z7*z6+z3S*z5+2*z3*z4
+ *z5+z3*z10*z5-z3*z7*z5+z4*z10*z5+z4*z7*z5);
+ fm[5][8] = 8*mQ4*(-2*z3-z4-3*z10-2*z7-z6)+4*mQ2*(2*z1*z3+
+ 4*z1*z4+2*z1*z10-z1*z9+z1*z8+2*z1*z7+4*z1*z6-2*z2*z3-z2*
+ z4-z2*z10+2*z2*z7+z2*z6+6*z3S+6*z3*z4+6*z3*z10+2*z3*z8+
+ 2*z3*z7+4*z3*z6-2*z3*z5+6*z4*z10-z4*z9+2*z4*z8+4*z4*z7+2*
+ z4*z6-z4*z5+3*z10*z9+3*z10*z8+6*z10*z7+6*z10*z6-3*z10*z5+
+ 3*z9*z7+2*z9*z6+z8*z7+6*z7S+6*z7*z6-2*z7*z5-z6*z5)+4*(
+ z1S*z9-z1S*z8-z1*z2*z7+z1*z2*z6+z1*z3*z9-z1*z3*z8+3*
+ z1*z3*z5+3*z1*z4*z5-z1*z10*z9-z1*z10*z8+2*z1*z10*z5-z1*z9
+ *z7-z1*z9*z6-z1*z8*z7-z2*z3*z7+z2*z3*z6+z2*z10*z7+z2*z10*
+ z6+z2*z7S+2*z2*z7*z6+3*z3S*z5+3*z3*z4*z5+3*z3*z10*z5+
+ z3*z7*z5+3*z4*z10*z5+3*z4*z7*z5-z4*z6*z5);
+ fm[6][6] = 64*mQ6+16*mQ4*s3+32*mQ4*(z1+z2+2*z4+z9+z7
+ +2*z5)+8*mQ2*s3*(-z1+2*z4-z7)+16*mQ2*(z2*z5-2*z4*
+ z9-2*z4*z7+4*z4*z5+z9*z5)+8*s3*z4*z7-16*z4*z9*z5;
+ fm[6][7] = 8*mQ4*(-6*z3-3*z4-3*z10-2*z9-z8-z7-2*z6)+2*mQ2
+ *s3*(-2*z3-z4-2*z10+z7+2*z6)+4*mQ2*(-8*z1*z3-4*z1*z4
+ -4*z1*z10+2*z1*z9-2*z1*z8-10*z2*z3-2*z2*z4-5*z2*z10-z2*z9
+ -2*z2*z8-4*z2*z7-2*z2*z6-5*z3*z9-4*z3*z7-8*z3*z5-2*z4*z9+
+ 7*z4*z8-4*z4*z7+8*z4*z6-4*z4*z5-5*z10*z5-z9S+z9*z8-2*z9
+ *z7+z9*z6-2*z9*z5+z8*z7-z8*z5)+2*s3*(z1*z10-z3*z7+2*z4
+ *z7-z4*z6)+4*(2*z1*z2*z9+z1*z2*z8+z1*z9S-z1*z9*z8-2*
+ z2S*z7-z2S*z6-3*z2*z3*z5-2*z2*z10*z5-z2*z9*z7-z2*z9*z6+
+ 2*z2*z8*z7-z3*z9*z5-z4*z9*z5+2*z4*z8*z5);
+ fm[6][8] = 8*mQ4*(-6*z3-3*z4-3*z10-z9-2*z8-z7-2*z6)+2*mQ2
+ *s3*(-6*z3-3*z4-3*z10+z7+2*z6)+4*mQ2*(-8*z1*z3-4*z1*
+ z4-4*z1*z10-8*z2*z3-4*z2*z4-4*z2*z10-4*z3*z9-4*z3*z7-12*
+ z3*z5-4*z4*z9+8*z4*z8-4*z4*z7+8*z4*z6-6*z4*z5-6*z10*z5-z9
+ *z5-2*z8*z5)+4*s3*(2*z1*z3+z1*z4+z1*z10+z3*z7+z4*z7-2*
+ z4*z6)+8*z5*(-2*z2*z3-z2*z4-z2*z10-z3*z9-z4*z9+2*z4*z8);
+ fm[7][7] = 72*mQ4*z10+18*mQ2*s3*z10+8*mQ2*(z1*z10+9*
+ z2*z10+7*z3*z7+2*z3*z6+2*z4*z7+7*z4*z6+z10*z5+2*z9*z7+7*
+ z9*z6+7*z8*z7+2*z8*z6)+2*s3*(-z1*z10-7*z3*z7-2*z3*z6-2
+ *z4*z7-7*z4*z6)+4*z2*(z10*z5+2*z9*z7+7*z9*z6+7*z8*z7+2*z8
+ *z6);
+ fm[7][8] = 72*mQ4*z10+2*mQ2*s3*z10+4*mQ2*(2*z1*z10+
+ 10*z2*z10+7*z3*z9+2*z3*z8+14*z3*z7+4*z3*z6+2*z4*z9+7*z4*
+ z8+4*z4*z7+14*z4*z6+10*z10*z5+z9S+7*z9*z8+2*z9*z7+7*z9*
+ z6+z8S+7*z8*z7+2*z8*z6)+2*s3*(7*z1*z10-7*z3*z7-2*z3*
+ z6-2*z4*z7-7*z4*z6)+2*(-2*z1*z9S-14*z1*z9*z8-2*z1*z8S
+ +2*z2*z10*z5+2*z2*z9*z7+7*z2*z9*z6+7*z2*z8*z7+2*z2*z8*z6+
+ 7*z3*z9*z5+2*z3*z8*z5+2*z4*z9*z5+7*z4*z8*z5);
+ fm[8][8] = 72*mQ4*z10+18*mQ2*s3*z10+8*mQ2*(z1*z10+z2
+ *z10+7*z3*z9+2*z3*z8+7*z3*z7+2*z3*z6+2*z4*z9+7*z4*z8+2*z4
+ *z7+7*z4*z6+9*z10*z5)+2*s3*(-z1*z10-7*z3*z7-2*z3*z6-2*
+ z4*z7-7*z4*z6)+4*z5*(z2*z10+7*z3*z9+2*z3*z8+2*z4*z9+7*z4*
+ z8);
+ double fm99 = -4*mQ4*z10-mQ2*s3*z10+4*mQ2*(-z1*z10-z2*z10+
+ z3*z7+z4*z6-z10*z5+z9*z6+z8*z7)+s3*(z1*z10-z3*z7-z4*z6
+ )+2*z2*(-z10*z5+z9*z6+z8*z7);
+ double fm910 = -4*mQ4*z10-mQ2*s3*z10+2*mQ2*(-2*z1*z10-2*z2*
+ z10+2*z3*z9+2*z3*z7+2*z4*z6-2*z10*z5+z9*z8+2*z8*z7)+s3
+ *(z1*z10-z3*z7-z4*z6)+2*(-z1*z9*z8-z2*z10*z5+z2*z8*z7+z3*
+ z9*z5);
+ double fmxx = -4*mQ4*z10-mQ2*s3*z10+2*mQ2*(-2*z1*z10-2*z2*
+ z10+2*z4*z8+2*z4*z6+2*z3*z7-2*z10*z5+z9*z8+2*z9*z6)+s3
+ *(z1*z10-z3*z7-z4*z6)+2*(-z1*z9*z8-z2*z10*z5+z2*z9*z6+z4*
+ z8*z5);
+ fm910 = 0.5*(fmxx+fm910);
+ double fm1010 = -4*mQ4*z10-mQ2*s3*z10+4*mQ2*(-z1*z10-z2*z10+
+ z3*z7+z4*z6-z10*z5+z9*z3+z8*z4)+s3*(z1*z10-z3*z7-z4*z6
+ )+2*z5*(-z10*z2+z9*z3+z8*z4);
+ fm[7][7] -= 2. * fm99;
+ fm[7][8] -= 2. * fm910;
+ fm[8][8] -= 2. * fm1010;
+
+ // Propagators.
+ double ss1 = (pTemp[1] + pTemp[3]).m2Calc() - mQ2;
+ double ss2 = (pTemp[1] + pTemp[4]).m2Calc() - mQ2;
+ double ss3 = (pTemp[1] + pTemp[5]).m2Calc() - mQ2;
+ double ss4 = (pTemp[2] + pTemp[3]).m2Calc() - mQ2;
+ double ss5 = (pTemp[2] + pTemp[4]).m2Calc() - mQ2;
+ double ss6 = (pTemp[2] + pTemp[5]).m2Calc() - mQ2;
+ double ss7 = sH;
+
+ // Propagator combinations.
+ double dz[9];
+ dz[1] = ss1 * ss6;
+ dz[2] = ss2 * ss6;
+ dz[3] = ss2 * ss4;
+ dz[4] = ss1 * ss5;
+ dz[5] = ss3 * ss5;
+ dz[6] = ss3 * ss4;
+ dz[7] = ss7 * ss1;
+ dz[8] = ss7 * ss4;
+
+ // Colour factors.
+ double clr[9][9];
+ for (int i = 1; i < 4; ++i)
+ for (int j = 1; j < 4; ++j) {
+ clr[i][j] = 16. / 3.;
+ clr[i][j+3] = -2. / 3.;
+ clr[i+3][j] = -2. / 3.;
+ clr[i+3][j+3] = 16. / 3.;
+ }
+ for (int i = 1; i < 4; ++i)
+ for (int j = 1; j < 3; ++j) {
+ clr[i][j+6] = -6.;
+ clr[i+3][j+6] = 6.;
+ clr[j+6][i] = -6.;
+ clr[j+6][i+3] = 6.;
+ }
+ for (int i = 1; i < 3; ++i)
+ for (int j = 1; j < 3; ++j)
+ clr[i+6][j+6] = 12.;
+
+ // Produce final result: matrix elements * colours * propagators.
+ double wtSum = 0.;
+ for (int i = 1; i < 9; ++i)
+ for (int j = i; j < 9; ++j) {
+ double fac = (j == i) ? 4. : 8.;
+ wtSum += fm[i][j] * fac * clr[i][j] / (dz[i] * dz[j]);
+ }
+ wtSum *= -1./256.;
+
+ // Combine factors.
+ sigma = prefac * alpEM * pow2(alpS) * mQ2run * wtSum *pow2(coup2Q);
+
+ // Secondary width for H, Q and Qbar (latter for top only).
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ sigma *= openFracTriplet;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma3gg2HQQbar::setIdColAcol() {
+
+ // Pick out-flavours by relative CKM weights.
+ setId( id1, id2, idRes, idNew, -idNew);
+
+ // Colour flow topologies.
+ if (Rndm::flat() < 0.5) setColAcol( 1, 2, 2, 3, 0, 0, 1, 0, 0, 3);
+ else setColAcol( 1, 2, 3, 1, 0, 0, 3, 0, 0, 2);
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma3gg2HQQbar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma3qqbar2HQQbar class.
+// Cross section for q qbar -> H0 Q Qbar (Q Qbar fusion of SM Higgs).
+// REDUCE output and part of the rest courtesy Z. Kunszt,
+// see Z. Kunszt, Nucl. Phys. B247 (1984) 339.
+
+//*********
+
+// Initialize process.
+
+void Sigma3qqbar2HQQbar::initProc() {
+
+ // Properties specific to Higgs state for the "q qbar -> H ttbar" process.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+
+ if (higgsType == 0 && idNew == 6) {
+ nameSave = "q qbar -> H t tbar (SM)";
+ codeSave = 909;
+ idRes = 25;
+ coup2Q = 1.;
+ }
+ else if (higgsType == 1 && idNew == 6) {
+ nameSave = "q qbar -> h0(H1) t tbar";
+ codeSave = 1009;
+ idRes = 25;
+ coup2Q = Settings::parm("HiggsH1:coup2u");
+ }
+ else if (higgsType == 2 && idNew == 6) {
+ nameSave = "q qbar -> H0(H2) t tbar";
+ codeSave = 1029;
+ idRes = 35;
+ coup2Q = Settings::parm("HiggsH2:coup2u");
+ }
+ else if (higgsType == 3 && idNew == 6) {
+ nameSave = "q qbar -> A0(A3) t tbar";
+ codeSave = 1049;
+ idRes = 36;
+ coup2Q = Settings::parm("HiggsA3:coup2u");
+ }
+
+ // Properties specific to Higgs state for the "q qbar -> H b bbar" process.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ if (higgsType == 0 && idNew == 5) {
+ nameSave = "q qbar -> H b bbar (SM)";
+ codeSave = 913;
+ idRes = 25;
+ coup2Q = 1.;
+ }
+ else if (higgsType == 1 && idNew == 5) {
+ nameSave = "q qbar -> h0(H1) b bbar";
+ codeSave = 1013;
+ idRes = 25;
+ coup2Q = Settings::parm("HiggsH1:coup2d");
+ }
+ else if (higgsType == 2 && idNew == 5) {
+ nameSave = "q qbar -> H0(H2) b bbar";
+ codeSave = 1033;
+ idRes = 35;
+ coup2Q = Settings::parm("HiggsH2:coup2d");
+ }
+ else if (higgsType == 3 && idNew == 5) {
+ nameSave = "q qbar -> A0(A3) b bbar";
+ codeSave = 1053;
+ idRes = 36;
+ coup2Q = Settings::parm("HiggsA3:coup2d");
+ }
+
+ // Common mass and coupling factors.
+ double mWS = pow2(ParticleDataTable::m0(24));
+ prefac = (4. * M_PI / CoupEW::sin2thetaW()) * pow2(4. * M_PI)
+ * 0.25 / mWS;
+
+ // Secondary open width fraction.
+ openFracTriplet = ParticleDataTable::resOpenFrac(idRes, idNew, -idNew);
+
+}
+
+//*********
+
+// Evaluate sigma(sHat), part independent of incoming flavour.
+
+void Sigma3qqbar2HQQbar::sigmaKin() {
+
+ // Running mass of heavy quark.
+ double mQ2run = pow2( ParticleDataTable::mRun(idNew, mH) );
+
+ // Linear combination of p_Q and p_Qbar to ensure common mass.
+ double mQ2 = m4 * m5;
+ double epsi = 0.;
+ if (m4 != m5) {
+ double s45 = (p4cm + p5cm).m2Calc();
+ mQ2 = 0.5 * (s4 + s5) - 0.25 * pow2(s4 - s5) / s45;
+ epsi = 0.5 * (s5 - s4) / s45;
+ }
+
+ // Set up kinematics: q(4) qbar(5) -> H(3) Q(1) Qbar(2) in outgoing sense.
+ Vec4 pTemp[6];
+ pTemp[4] = Vec4( 0., 0., -0.5* mH, -0.5* mH);
+ pTemp[5] = Vec4( 0., 0., 0.5* mH, -0.5* mH);
+ pTemp[1] = p4cm + epsi * (p4cm + p5cm);
+ pTemp[2] = p5cm - epsi * (p4cm + p5cm);
+ pTemp[3] = p3cm;
+
+ // Four-product combinations.
+ double z1 = pTemp[1] * pTemp[2];
+ double z2 = pTemp[1] * pTemp[3];
+ double z3 = pTemp[1] * pTemp[4];
+ double z4 = pTemp[1] * pTemp[5];
+ double z5 = pTemp[2] * pTemp[3];
+ double z6 = pTemp[2] * pTemp[4];
+ double z7 = pTemp[2] * pTemp[5];
+ double z8 = pTemp[3] * pTemp[4];
+ double z9 = pTemp[3] * pTemp[5];
+ double z10 = pTemp[4] * pTemp[5];
+
+ // Powers required as shorthand in matriz elements.
+ double mQ4 = mQ2 * mQ2;
+
+ // Evaluate matrix elements for q + qbar -> Q + Qbar + H.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ double a11 = -8.*mQ4*z10-2.*mQ2*s3*z10-(8.*mQ2)*(z2*z10+z3
+ *z7+z4*z6+z9*z6+z8*z7)+2.*s3*(z3*z7+z4*z6)-(4.*z2)*(z9
+ *z6+z8*z7);
+ double a12 = -8.*mQ4*z10+4.*mQ2*(-z2*z10-z3*z9-2.*z3*z7-z4*z8-
+ 2.*z4*z6-z10*z5-z9*z8-z9*z6-z8*z7)+2.*s3*(-z1*z10+z3*z7
+ +z4*z6)+2.*(2.*z1*z9*z8-z2*z9*z6-z2*z8*z7-z3*z9*z5-z4*z8*
+ z5);
+ double a22 = -8.*mQ4*z10-2.*mQ2*s3*z10-(8.*mQ2)*(z3*z9+z3*
+ z7+z4*z8+z4*z6+z10*z5)+2.*s3*(z3*z7+z4*z6)-(4.*z5)*(z3
+ *z9+z4*z8);
+
+ // Propagators and propagator combinations.
+ double ss1 = (pTemp[1] + pTemp[3]).m2Calc() - mQ2;
+ double ss4 = (pTemp[2] + pTemp[3]).m2Calc() - mQ2;
+ double ss7 = sH;
+ double dz7 = ss7 * ss1;
+ double dz8 = ss7 * ss4;
+
+ // Produce final result: matrix elements * propagators.
+ a11 /= (dz7 * dz7);
+ a12 /= (dz7 * dz8);
+ a22 /= (dz8 * dz8);
+ double wtSum = -(a11 + a22 + 2.*a12) * (8./9.);
+
+ // Combine factors.
+ sigma = prefac * alpEM * pow2(alpS) * mQ2run * wtSum * pow2(coup2Q);
+
+ // Secondary width for H, Q and Qbar (latter for top only).
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ sigma *= openFracTriplet;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma3qqbar2HQQbar::setIdColAcol() {
+
+ // Pick out-flavours by relative CKM weights.
+ setId( id1, id2, idRes, idNew, -idNew);
+
+ // Colour flow topologies.
+ if (id1 > 0) setColAcol( 1, 0, 0, 2, 0, 0, 1, 0, 0, 2);
+ else setColAcol( 0, 1, 2, 0, 0, 0, 2, 0, 0, 1);
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma3qqbar2HQQbar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2Hq class.
+// Cross section for q g -> H q.
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2Hq::initProc() {
+
+ // Properties specific to Higgs state for the "c g -> H c" process.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ if (higgsType == 0 && idNew == 4) {
+ nameSave = "c g -> H c (SM)";
+ codeSave = 911;
+ idRes = 25;
+ }
+ else if (higgsType == 1 && idNew == 4) {
+ nameSave = "c g -> h0(H1) c";
+ codeSave = 1011;
+ idRes = 25;
+ }
+ else if (higgsType == 2 && idNew == 4) {
+ nameSave = "c g -> H0(H2) c";
+ codeSave = 1031;
+ idRes = 35;
+ }
+ else if (higgsType == 3 && idNew == 4) {
+ nameSave = "c g -> A0(A3) c";
+ codeSave = 1051;
+ idRes = 36;
+ }
+
+ // Properties specific to Higgs state for the "b g -> H b" process.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ if (higgsType == 0 && idNew == 5) {
+ nameSave = "b g -> H b (SM)";
+ codeSave = 911;
+ idRes = 25;
+ }
+ else if (higgsType == 1 && idNew == 5) {
+ nameSave = "b g -> h0(H1) b";
+ codeSave = 1011;
+ idRes = 25;
+ }
+ else if (higgsType == 2 && idNew == 5) {
+ nameSave = "b g -> H0(H2) b";
+ codeSave = 1031;
+ idRes = 35;
+ }
+ else if (higgsType == 3 && idNew == 5) {
+ nameSave = "b g -> A0(A3) b";
+ codeSave = 1051;
+ idRes = 36;
+ }
+
+ // Standard parameters.
+ m2W = pow2( ParticleDataTable::m0(24) );
+ thetaWRat = 1. / (24. * CoupEW::sin2thetaW());
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idRes);
+
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qg2Hq::sigmaKin() {
+
+ // Running mass provides coupling.
+ double m2Run = pow2( ParticleDataTable::mRun(idNew, mH) );
+
+ // Cross section, including couplings and kinematics.
+ sigma = (M_PI / sH2) * alpS * alpEM * thetaWRat * (m2Run/m2W)
+ * (sH / (s4 - uH) + 2. * s4 * (s3 - uH) / pow2(s4 - uH)
+ + (s4 - uH) / sH - 2. * s4 / (s4 - uH)
+ + 2. * (s3 - uH) * (s3 - s4 - sH) / ((s4 - uH) * sH) );
+
+ // Include secondary width for H0, H1, H2 or A3. Done.
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma2qg2Hq::sigmaHat() {
+
+ // Check that specified flavour present.
+ if (abs(id1) != idNew && abs(id2) != idNew) return 0.;
+
+ // Answer.
+ return sigma;
+
+}
+
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2Hq::setIdColAcol() {
+
+ // Flavour set up for q g -> H0 q.
+ int idq = (id2 == 21) ? id1 : id2;
+ setId( id1, id2, idRes, idq);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2qg2Hq::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2Hglt class.
+// Cross section for g g -> H g (H SM Higgs or BSM Higgs) via top loop.
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2Hglt::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "g g -> H g (SM; top loop)";
+ codeSave = 914;
+ idRes = 25;
+ }
+ else if (higgsType == 1) {
+ nameSave = "g g -> h0(H1) g (BSM; top loop)";
+ codeSave = 1014;
+ idRes = 25;
+ }
+ else if (higgsType == 2) {
+ nameSave = "g g -> H0(H2) g (BSM; top loop)";
+ codeSave = 1034;
+ idRes = 35;
+ }
+ else if (higgsType == 3) {
+ nameSave = "g g -> A0(A3) g (BSM; top loop)";
+ codeSave = 1054;
+ idRes = 36;
+ }
+
+ // Normalization factor by g g -> H partial width.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ double mHiggs = ParticleDataTable::m0(idRes);
+ widHgg = ParticleDataTable::resWidthChan(idRes, mHiggs, 21, 21);
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2gg2Hglt::sigmaKin() {
+
+ // Evaluate cross section. Secondary width for H0, H1, H2 or A3.
+ sigma = (M_PI / sH2) * (3. / 16.) * alpS * (widHgg / m3)
+ * (sH2 * sH2 + tH2 * tH2 + uH2 * uH2 + pow4(s3))
+ / (sH * tH * uH * s3);
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2Hglt::setIdColAcol() {
+
+ // Flavour set up for g g -> H g trivial.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ setId( 21, 21, idRes, 21);
+
+ // Colour flow topologies: random choice between two mirrors.
+ if (Rndm::flat() < 0.5) setColAcol( 1, 2, 2, 3, 0, 0, 1, 3);
+ else setColAcol( 1, 2, 3, 1, 0, 0, 3, 2);
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2gg2Hglt::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2Hqlt class.
+// Cross section for q g -> H q (H SM or BSM Higgs) via top loop.
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2Hqlt::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "q g -> H q (SM; top loop)";
+ codeSave = 915;
+ idRes = 25;
+ }
+ else if (higgsType == 1) {
+ nameSave = "q g -> h0(H1) q (BSM; top loop)";
+ codeSave = 1015;
+ idRes = 25;
+ }
+ else if (higgsType == 2) {
+ nameSave = "q g -> H0(H2) q (BSM; top loop)";
+ codeSave = 1035;
+ idRes = 35;
+ }
+ else if (higgsType == 3) {
+ nameSave = "q g -> A0(A3) q (BSM; top loop)";
+ codeSave = 1055;
+ idRes = 36;
+ }
+
+ // Normalization factor by g g -> H partial width.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ double mHiggs = ParticleDataTable::m0(idRes);
+ widHgg = ParticleDataTable::resWidthChan(idRes, mHiggs, 21, 21);
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idRes);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat, part independent of incoming flavour).
+
+void Sigma2qg2Hqlt::sigmaKin() {
+
+ // Evaluate cross section. Secondary width for H0, H1, H2 or A3.
+ sigma = (M_PI / sH2) * (1. / 12.) * alpS * (widHgg / m3)
+ * (sH2 + uH2) / (-tH * s3);
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2Hqlt::setIdColAcol() {
+
+ // Flavour set up for q g -> H q.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ int idq = (id2 == 21) ? id1 : id2;
+ setId( id1, id2, idRes, idq);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2qg2Hqlt::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2Hglt class.
+// Cross section for q qbar -> H g (H SM or BSM Higgs) via top loop.
+// (H can be H0 SM or H1, H2, A3 from BSM).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2Hglt::initProc() {
+
+ // Properties specific to Higgs state.
+ if (higgsType == 0) {
+ nameSave = "q qbar -> H g (SM; top loop)";
+ codeSave = 916;
+ idRes = 25;
+ }
+ else if (higgsType == 1) {
+ nameSave = "q qbar -> h0(H1) g (BSM; top loop)";
+ codeSave = 1016;
+ idRes = 25;
+ }
+ else if (higgsType == 2) {
+ nameSave = "q qbar -> H0(H2) g (BSM; top loop)";
+ codeSave = 1036;
+ idRes = 35;
+ }
+ else if (higgsType == 3) {
+ nameSave = "q qbar -> A0(A3) g (BSM; top loop)";
+ codeSave = 1056;
+ idRes = 36;
+ }
+
+ // Normalization factor by g g -> H partial width.
+ // (H can be H0 SM or H1, H2, A3 from BSM).
+ double mHiggs = ParticleDataTable::m0(idRes);
+ widHgg = ParticleDataTable::resWidthChan(idRes, mHiggs, 21, 21);
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(idRes);
+
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qqbar2Hglt::sigmaKin() {
+
+ // Evaluate cross section. Secondary width for H0, H1, H2 or A3.
+ sigma = (M_PI / sH2) * (2. / 9.) * alpS * (widHgg / m3)
+ * (tH2 + uH2) / (sH * s3);
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2Hglt::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, idRes, 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2qqbar2Hglt::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+
+//**************************************************************************
+
+// Sigma1ffbar2Hchg class.
+// Cross section for f fbar -> H+- (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2Hchg::initProc() {
+
+ // Find pointer to H+-.
+ HResPtr = ParticleDataTable::particleDataPtr(37);
+
+ // Store H+- mass and width for propagator.
+ mRes = HResPtr->m0();
+ GammaRes = HResPtr->mWidth();
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Couplings.
+ m2W = pow2(ParticleDataTable::m0(24));
+ thetaWRat = 1. / (8. * CoupEW::sin2thetaW());
+ tan2Beta = pow2(Settings::parm("HiggsHchg:tanBeta"));
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma1ffbar2Hchg::sigmaKin() {
+
+ // Set up Breit-Wigner. Width out only includes open channels.
+ sigBW = 4. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ widthOutPos = HResPtr->resWidthOpen( 37, mH);
+ widthOutNeg = HResPtr->resWidthOpen(-37, mH);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2Hchg::sigmaHat() {
+
+ // Only allow generation-diagonal states.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ int idUp = max(id1Abs, id2Abs);
+ int idDn = min(id1Abs, id2Abs);
+ if (idUp%2 != 0 || idUp - idDn != 1) return 0.;
+
+ // Calculate mass-dependent incoming width. Total cross section.
+ double m2RunUp = pow2(ParticleDataTable::mRun(idUp, mH));
+ double m2RunDn = pow2(ParticleDataTable::mRun(idDn, mH));
+ double widthIn = alpEM * thetaWRat * (mH/m2W)
+ * (m2RunDn * tan2Beta + m2RunUp / tan2Beta);
+ int idUpChg = (id1Abs%2 == 0) ? id1 : id2;
+ double sigma = (idUpChg > 0) ? widthIn * sigBW * widthOutPos
+ : widthIn * sigBW * widthOutNeg;
+
+ // Colour factor. Answer.
+ if (idUp < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2Hchg::setIdColAcol() {
+
+ // Charge of Higgs. Fill flavours.
+ int idUpChg = (abs(id1)%2 == 0) ? id1 : id2;
+ int idHchg = (idUpChg > 0) ? 37 : -37;
+ setId( id1, id2, idHchg);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma1ffbar2Hchg::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2Hq class.
+// Cross section for q g -> H+- q'.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2Hchgq::initProc() {
+
+ // Standard parameters.
+ m2W = pow2( ParticleDataTable::m0(24) );
+ thetaWRat = 1. / (24. * CoupEW::sin2thetaW());
+ tan2Beta = pow2(Settings::parm("HiggsHchg:tanBeta"));
+
+ // Incoming flavour within same doublet. Uptype and downtype flavours.
+ idOld = (idNew%2 == 0) ? idNew - 1 : idNew + 1;
+ idUp = max(idOld, idNew);
+ idDn = min(idOld, idNew);
+
+ // Secondary open width fraction.
+ openFracPos = (idOld%2 == 0) ? ParticleDataTable::resOpenFrac( 37, idNew)
+ : ParticleDataTable::resOpenFrac(-37, idNew);
+ openFracNeg = (idOld%2 == 0) ? ParticleDataTable::resOpenFrac(-37, -idNew)
+ : ParticleDataTable::resOpenFrac( 37, -idNew);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qg2Hchgq::sigmaKin() {
+
+ // Running masses provides coupling.
+ double m2RunUp = pow2(ParticleDataTable::mRun(idUp, mH));
+ double m2RunDn = pow2(ParticleDataTable::mRun(idDn, mH));
+
+ // Cross section, including couplings and kinematics.
+ sigma = (M_PI / sH2) * alpS * alpEM * thetaWRat
+ * (m2RunDn * tan2Beta + m2RunUp / tan2Beta) / m2W
+ * (sH / (s4 - uH) + 2. * s4 * (s3 - uH) / pow2(s4 - uH)
+ + (s4 - uH) / sH - 2. * s4 / (s4 - uH)
+ + 2. * (s3 - uH) * (s3 - s4 - sH) / ((s4 - uH) * sH) );
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma2qg2Hchgq::sigmaHat() {
+
+ // Check that specified flavour present.
+ if (abs(id1) != idOld && abs(id2) != idOld) return 0.;
+
+ // Answer.
+ return (id1 == idOld || id2 == idOld) ? sigma * openFracPos
+ : sigma * openFracNeg;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2Hchgq::setIdColAcol() {
+
+ // Flavour set up for q g -> H+- q'.
+ int idq = (id2 == 21) ? id1 : id2;
+ id3 = ( (idq > 0 && idOld%2 == 0) || (idq < 0 && idOld%2 != 0) )
+ ? 37 : -37;
+ id4 = (idq > 0) ? idNew : -idNew;
+ setId( id1, id2, id3, id4);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2qg2Hchgq::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2A3H12 class.
+// Cross section for f fbar -> A0(H_3) h0(H_1) or A0(H_3) H0(H_2).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2A3H12::initProc() {
+
+ // Set up whether h0(H_1) or H0(H_2).
+ higgs12 = (higgsType == 1) ? 25 : 35;
+ codeSave = (higgsType == 1) ? 1081 : 1082;
+ nameSave = (higgsType == 1) ? "f fbar -> A0(H3) h0(H1)"
+ : "f fbar -> A0(H3) H0(H2)";
+ coupZA3H12 = (higgsType == 1) ? Settings::parm("HiggsA3:coup2H1Z")
+ : Settings::parm("HiggsA3:coup2H2Z");
+
+ // Standard parameters.
+ double mZ = ParticleDataTable::m0(23);
+ double GammaZ = ParticleDataTable::mWidth(23);
+ m2Z = mZ * mZ;
+ mGammaZ = mZ * GammaZ;
+ thetaWRat = 1. / (4. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(36, higgs12);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2ffbar2A3H12::sigmaKin() {
+
+ // Common kinematics factora.
+ sigma0 = (M_PI / sH2) * pow2(alpEM * thetaWRat * coupZA3H12)
+ * (uH * tH - s3 * s4) / ( pow2(sH - m2Z) + pow2(mGammaZ) );
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma2ffbar2A3H12::sigmaHat() {
+
+ // Couplings for incoming flavour.
+ int idAbs = abs(id1);
+ double lIn = CoupEW::lf(idAbs);
+ double rIn = CoupEW::rf(idAbs);
+
+ // Combine to total cross section. Colour factor.
+ double sigma = (pow2(lIn) + pow2(rIn)) * sigma0 * openFrac;
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2A3H12::setIdColAcol() {
+
+ // Flavours trivial
+ setId( id1, id2, 36, higgs12);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2ffbar2A3H12::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2HchgH12 class.
+// Cross section for f fbar -> H+- h0(H_1) or H+- H0(H_2).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2HchgH12::initProc() {
+
+ // Set up whether h0(H_1) or H0(H_2).
+ higgs12 = (higgsType == 1) ? 25 : 35;
+ codeSave = (higgsType == 1) ? 1083 : 1084;
+ nameSave = (higgsType == 1) ? "f fbar' -> H+- h0(H1)"
+ : "f fbar' -> H+- H0(H2)";
+ coupWHchgH12 = (higgsType == 1) ? Settings::parm("HiggsHchg:coup2H1W")
+ : Settings::parm("HiggsHchg:coup2H2W");
+
+ // Standard parameters.
+ double mW = ParticleDataTable::m0(24);
+ double GammaW = ParticleDataTable::mWidth(24);
+ m2W = mW * mW;
+ mGammaW = mW * GammaW;
+ thetaWRat = 1. / (2. * CoupEW::sin2thetaW());
+
+ // Secondary open width fraction.
+ openFracPos = ParticleDataTable::resOpenFrac( 37, higgs12);
+ openFracNeg = ParticleDataTable::resOpenFrac(-37, higgs12);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2ffbar2HchgH12::sigmaKin() {
+
+ // Common kinematics factora.
+ sigma0 = 0.5 * (M_PI / sH2) * pow2(alpEM * thetaWRat * coupWHchgH12)
+ * (uH * tH - s3 * s4) / ( pow2(sH - m2W) + pow2(mGammaW) );
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma2ffbar2HchgH12::sigmaHat() {
+
+ // Combine to total cross section. CKM and colour factor.
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ double sigma = (idUp > 0) ? sigma0 * openFracPos : sigma0 * openFracNeg;
+ if (abs(id1) < 9) sigma *= VCKM::V2id(abs(id1), abs(id2)) / 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2HchgH12::setIdColAcol() {
+
+ // Charge of Higgs. Fill flavours.
+ int idUpChg = (abs(id1)%2 == 0) ? id1 : id2;
+ int idHchg = (idUpChg > 0) ? 37 : -37;
+ setId( id1, id2, idHchg, higgs12);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2ffbar2HchgH12::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2HposHneg class.
+// Cross section for q g -> H+- q'.
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2HposHneg::initProc() {
+
+ // Standard parameters.
+ double mZ = ParticleDataTable::m0(23);
+ double GammaZ = ParticleDataTable::mWidth(23);
+ m2Z = mZ * mZ;
+ mGammaZ = mZ * GammaZ;
+ thetaWRat = 1. / (4. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+ // Charged Higgs coupling to gamma and Z0.
+ eH = -1.;
+ lH = -1. + 2. * CoupEW::sin2thetaW();
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(37, -37);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2ffbar2HposHneg::sigmaKin() {
+
+ // Common kinematics factora.
+ double preFac = M_PI * pow2(alpEM) * ((uH * tH - s3 * s4) / sH2);
+ double propZ = 1. / ( pow2(sH - m2Z) + pow2(mGammaZ) );
+
+ // Separate parts for gamma*, interference and Z0.
+ gamSig = preFac * 2. * pow2(eH) / sH2;
+ intSig = preFac * 2. * eH * lH * thetaWRat * propZ * (sH - m2Z) / sH;
+ resSig = preFac * pow2(lH * thetaWRat) * propZ;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma2ffbar2HposHneg::sigmaHat() {
+
+ // Couplings for incoming flavour.
+ int idAbs = int(id1);
+ double eIn = CoupEW::ef(idAbs);
+ double lIn = CoupEW::lf(idAbs);
+ double rIn = CoupEW::rf(idAbs);
+
+ // Combine to total cross section. Colour factor.
+ double sigma = (pow2(eIn) * gamSig + eIn * (lIn + rIn) * intSig
+ + (pow2(lIn) + pow2(rIn)) * resSig) * openFrac;
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2HposHneg::setIdColAcol() {
+
+ // Flavours trivial
+ setId( id1, id2, 37, -37);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma2ffbar2HposHneg::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For Higgs decay hand over to standard routine.
+ if (idMother == 25 || idMother == 35 || idMother == 36)
+ return weightHiggsDecay( process, iResBeg, iResEnd);
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaLeftRightSym.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// left-right-symmetry simulation classes.
+
+#include "SigmaLeftRightSym.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma1ffbar2ZRight class.
+// Cross section for f fbar -> Z_R^0 (righthanded gauge boson).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2ZRight::initProc() {
+
+ // Store Z_R mass and width for propagator.
+ idZR = 9900023;
+ mRes = ParticleDataTable::m0(idZR);
+ GammaRes = ParticleDataTable::mWidth(idZR);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ sin2tW = CoupEW::sin2thetaW();
+
+ // Set pointer to particle properties and decay table.
+ ZRPtr = ParticleDataTable::particleDataPtr(idZR);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2ZRight::sigmaKin() {
+
+ // Set up Breit-Wigner. Width out only includes open channels.
+ double sigBW = 12. * M_PI/ ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double widthOut = ZRPtr->resWidthOpen(idZR, mH);
+
+ // Prefactor for incoming widths. Combine. Done.
+ double preFac = alpEM * mH / ( 48. * sin2tW * (1. - sin2tW)
+ * (1. - 2. * sin2tW) );
+ sigma0 = preFac * sigBW * widthOut;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2ZRight::sigmaHat() {
+
+ // Vector and axial couplings of incoming fermion pair.
+ int idAbs = abs(id1);
+ double af = 0.;
+ double vf = 0.;
+ if (idAbs < 9 && idAbs%2 == 1) {
+ af = -1. + 2. * sin2tW;
+ vf = -1. + 4. * sin2tW / 3.;
+ } else if (idAbs < 9) {
+ af = 1. - 2. * sin2tW;
+ vf = 1. - 8. * sin2tW / 3.;
+ } else if (idAbs < 19 && idAbs%2 == 1) {
+ af = -1. + 2. * sin2tW;
+ vf = -1. + 4. * sin2tW;
+ }
+
+ // Colour factor. Answer.
+ double sigma = (vf*vf + af*af) * sigma0;
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2ZRight::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, idZR);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for Z_R decay angle.
+
+double Sigma1ffbar2ZRight::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Z_R should sit in entry 5.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Couplings for in- and out-flavours.
+ double ai, vi, af, vf;
+ int idInAbs = process[3].idAbs();
+ if (idInAbs < 9 && idInAbs%2 == 1) {
+ ai = -1. + 2. * sin2tW;
+ vi = -1. + 4. * sin2tW / 3.;
+ } else if (idInAbs < 9) {
+ ai = 1. - 2. * sin2tW;
+ vi = 1. - 8. * sin2tW / 3.;
+ } else {
+ ai = -1. + 2. * sin2tW;
+ vi = -1. + 4. * sin2tW;
+ }
+ int idOutAbs = process[6].idAbs();
+ if (idOutAbs < 9 && idOutAbs%2 == 1) {
+ af = -1. + 2. * sin2tW;
+ vf = -1. + 4. * sin2tW / 3.;
+ } else if (idOutAbs < 9) {
+ af = 1. - 2. * sin2tW;
+ vf = 1. - 8. * sin2tW / 3.;
+ } else {
+ af = -1. + 2. * sin2tW;
+ vf = -1. + 4. * sin2tW;
+ }
+
+ // Phase space factors. Reconstruct decay angle.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+
+ // Angular weight and its maximum.
+ double wt1 = (vi*vi + ai*ai) * (vf*vf + af*af * betaf*betaf);
+ double wt2 = (1. - betaf*betaf) * (vi*vi + ai*ai) * vf*vf;
+ double wt3 = betaf * 4. * vi * ai * vf * af;
+ if (process[3].id() * process[6].id() < 0) wt3 = -wt3;
+ double wt = wt1 * (1. + cosThe*cosThe) + wt2 * (1. - cosThe*cosThe)
+ + 2. * wt3 * cosThe;
+ double wtMax = 2. * (wt1 + abs(wt3));
+
+ // Done.
+ return wt / wtMax;
+
+}
+
+//**************************************************************************
+
+// Sigma1ffbar2WRight class.
+// Cross section for f fbar' -> W_R^+- (righthanded gauge boson).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2WRight::initProc() {
+
+ // Store W_R^+- mass and width for propagator.
+ idWR = 9900024;
+ mRes = ParticleDataTable::m0(idWR);
+ GammaRes = ParticleDataTable::mWidth(idWR);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(idWR);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2WRight::sigmaKin() {
+
+ // Common coupling factors.
+ double colQ = 3. * (1. + alpS / M_PI);
+
+ // Reset quantities to sum. Declare variables inside loop.
+ double widOutPos = 0.;
+ double widOutNeg = 0.;
+ int id1Now, id2Now, id1Abs, id2Abs, id1Neg, id2Neg, onMode;
+ double widNow, widSecPos, widSecNeg, mf1, mf2, mr1, mr2, kinFac;
+
+ // Loop over all W_R^+- decay channels.
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ widNow = 0.;
+ id1Now = particlePtr->decay[i].product(0);
+ id2Now = particlePtr->decay[i].product(1);
+ id1Abs = abs(id1Now);
+ id2Abs = abs(id2Now);
+
+ // Check that above threshold. Phase space.
+ mf1 = ParticleDataTable::m0(id1Abs);
+ mf2 = ParticleDataTable::m0(id2Abs);
+ if (mH > mf1 + mf2 + MASSMARGIN) {
+ mr1 = pow2(mf1 / mH);
+ mr2 = pow2(mf2 / mH);
+ kinFac = (1. - 0.5 * (mr1 + mr2) - 0.5 * pow2(mr1 - mr2))
+ * sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2 );
+
+ // Combine kinematics with colour factor and CKM couplings.
+ widNow = kinFac;
+ if (id1Abs < 9) widNow *= colQ * VCKM::V2id(id1Abs, id2Abs);
+
+ // Secondary width from top and righthanded neutrino decay.
+ id1Neg = (id1Abs < 19) ? -id1Now : id1Abs;
+ id2Neg = (id2Abs < 19) ? -id2Now : id2Abs;
+ widSecPos = ParticleDataTable::resOpenFrac(id1Now, id2Now);
+ widSecNeg = ParticleDataTable::resOpenFrac(id1Neg, id2Neg);
+
+ // Add weight for channels on for all, W_R^+ and W_R^-, respectively.
+ onMode = particlePtr->decay[i].onMode();
+ if (onMode == 1 || onMode == 2) widOutPos += widNow * widSecPos;
+ if (onMode == 1 || onMode == 3) widOutNeg += widNow * widSecNeg;
+
+ // End loop over fermions.
+ }
+ }
+
+ // Set up Breit-Wigner. Cross section for W_R^+ and W_R^- separately.
+ double sigBW = 12. * M_PI * pow2(alpEM * thetaWRat) * sH
+ / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ sigma0Pos = sigBW * widOutPos;
+ sigma0Neg = sigBW * widOutNeg;
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2WRight::sigmaHat() {
+
+ // Secondary width for W_R^+ or W_R^-. CKM and colour factors.
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ double sigma = (idUp > 0) ? sigma0Pos : sigma0Neg;
+ if (abs(id1) < 9) sigma *= VCKM::V2id(abs(id1), abs(id2)) / 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2WRight::setIdColAcol() {
+
+ // Sign of outgoing W_R.
+ int sign = (abs(id1)%2 == 0) ? 1 : -1;
+ if (id1 < 0) sign = -sign;
+ setId( id1, id2, idWR * sign);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for W_R decay angle.
+
+double Sigma1ffbar2WRight::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // W_R should sit in entry 5.
+ if (iResBeg != 5 || iResEnd != 5) return 1.;
+
+ // Phase space factors.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double betaf = sqrtpos( pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+
+ // Sign of asymmetry.
+ double eps = (process[3].id() * process[6].id() > 0) ? 1. : -1.;
+
+ // Reconstruct decay angle and weight for it.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * betaf);
+ double wtMax = 4.;
+ double wt = pow2(1. + betaf * eps * cosThe) - pow2(mr1 - mr2);
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma1ll2Hchgchg class.
+// Cross section for l l -> H_L^++-- or H_R^++-- (doubly charged Higgs).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ll2Hchgchg::initProc() {
+
+ // Set process properties: H_L^++-- or H_R^++--.
+ if (leftRight == 1) {
+ idHLR = 9900041;
+ codeSave = 3121;
+ nameSave = "l l -> H_L^++--";
+ } else {
+ idHLR = 9900042;
+ codeSave = 3141;
+ nameSave = "l l -> H_R^++--";
+ }
+
+ // Read in Yukawa matrix for couplings to a lepton pair.
+ yukawa[1][1] = Settings::parm("LeftRightSymmmetry:coupHee");
+ yukawa[2][1] = Settings::parm("LeftRightSymmmetry:coupHmue");
+ yukawa[2][2] = Settings::parm("LeftRightSymmmetry:coupHmumu");
+ yukawa[3][1] = Settings::parm("LeftRightSymmmetry:coupHtaue");
+ yukawa[3][2] = Settings::parm("LeftRightSymmmetry:coupHtaumu");
+ yukawa[3][3] = Settings::parm("LeftRightSymmmetry:coupHtautau");
+
+ // Store H_L/R mass and width for propagator.
+ mRes = ParticleDataTable::m0(idHLR);
+ GammaRes = ParticleDataTable::mWidth(idHLR);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(idHLR);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ll2Hchgchg::sigmaHat() {
+
+ // Initial state must consist of two identical-sign leptons.
+ if (id1 * id2 < 0) return 0.;
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ if (id1Abs != 11 && id1Abs != 13 && id1Abs != 15) return 0.;
+ if (id2Abs != 11 && id2Abs != 13 && id2Abs != 15) return 0.;
+
+ // Set up Breit-Wigner, inwidth and outwidth.
+ double sigBW = 8. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double widIn = pow2(yukawa[(id1Abs-9)/2][(id2Abs-9)/2])
+ * mH / (8. * M_PI);
+ int idSgn = (id1 < 0) ? idHLR : -idHLR;
+ double widOut = particlePtr->resWidthOpen( idSgn, mH);
+
+ // Answer.
+ return widIn * sigBW * widOut;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ll2Hchgchg::setIdColAcol() {
+
+ // Sign of outgoing H_L/R.
+ int idSgn = (id1 < 0) ? idHLR : -idHLR;
+ setId( id1, id2, idSgn);
+
+ // No colours whatsoever.
+ setColAcol( 0, 0, 0, 0, 0, 0);
+
+}
+
+//*********
+
+// Evaluate weight for H_L/R sequential decay angles.
+
+double Sigma1ll2Hchgchg::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else isotropic decay.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2lgm2Hchgchgl class.
+// Cross section for l l -> H_L^++-- or H_R^++-- (doubly charged Higgs).
+
+//*********
+
+// Initialize process.
+
+void Sigma2lgm2Hchgchgl::initProc() {
+
+ // Set process properties: H_L^++-- or H_R^++-- and e/mu/tau.
+ idHLR = (leftRight == 1) ? 9900041 : 9900042;
+ codeSave = (leftRight == 1) ? 3122 : 3142;
+ if (idLep == 13) codeSave += 2;
+ if (idLep == 15) codeSave += 4;
+ if (codeSave == 3122) nameSave = "l^+- gamma -> H_L^++-- e^-+";
+ else if (codeSave == 3123) nameSave = "l^+- gamma -> H_L^++-- mu^-+";
+ else if (codeSave == 3124) nameSave = "l^+- gamma -> H_L^++-- tau^-+";
+ else if (codeSave == 3142) nameSave = "l^+- gamma -> H_R^++-- e^-+";
+ else if (codeSave == 3143) nameSave = "l^+- gamma -> H_R^++-- mu^-+";
+ else nameSave = "l^+- gamma -> H_R^++-- tau^-+";
+
+ // Read in relevantYukawa matrix for couplings to a lepton pair.
+ if (idLep == 11) {
+ yukawa[1] = Settings::parm("LeftRightSymmmetry:coupHee");
+ yukawa[2] = Settings::parm("LeftRightSymmmetry:coupHmue");
+ yukawa[3] = Settings::parm("LeftRightSymmmetry:coupHtaue");
+ } else if (idLep == 13) {
+ yukawa[1] = Settings::parm("LeftRightSymmmetry:coupHmue");
+ yukawa[2] = Settings::parm("LeftRightSymmmetry:coupHmumu");
+ yukawa[3] = Settings::parm("LeftRightSymmmetry:coupHtaumu");
+ } else {
+ yukawa[1] = Settings::parm("LeftRightSymmmetry:coupHtaue");
+ yukawa[2] = Settings::parm("LeftRightSymmmetry:coupHtaumu");
+ yukawa[3] = Settings::parm("LeftRightSymmmetry:coupHtautau");
+ }
+
+ // Secondary open width fractions.
+ openFracPos = ParticleDataTable::resOpenFrac( idHLR);
+ openFracNeg = ParticleDataTable::resOpenFrac(-idHLR);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma2lgm2Hchgchgl::sigmaHat() {
+
+ // Initial state must consist of a lepton and a photon.
+ int idIn = (id2 == 22) ? id1 : id2;
+ int idInAbs = abs(idIn);
+ if (idInAbs != 11 && idInAbs != 13 && idInAbs != 15) return 0.;
+
+ // Incoming squared lepton mass.
+ double s1 = pow2( ParticleDataTable::m0(idInAbs) );
+
+ // Kinematical expressions.
+ double smm1 = 8. * (sH + tH - s3) * (sH + tH - 2. * s3 - s1 - s4)
+ / pow2(uH - s3);
+ double smm2 = 2. * ( (2. * s3 - 3. * s1) * s4 + (s1 - 2. * s4) * tH
+ - (tH - s4) * sH ) / pow2(tH - s4);
+ double smm3 = 2. * ( (2. * s3 - 3. * s4 + tH) * s1
+ - (2. * s1 - s4 + tH) * sH ) / pow2(sH - s1);
+ double smm12 = 4. * ( (2. * s1 - s4 - 2. * s3 + tH) * sH
+ + (tH - 3. * s3 - 3. * s4) * tH + (2. * s3 - 2. * s1
+ + 3. * s4) * s3 ) / ( (uH - s3) * (tH - s4) );
+ double smm13 = -4. * ( (tH + s1 - 2. * s4) * tH - (s3 + 3. * s1 - 2. * s4)
+ * s3 + (s3 + 3. * s1 + tH) * sH - pow2(tH - s3 + sH) )
+ / ( (uH - s3) * (sH - s1) );
+ double smm23 = -4. * ( (s1 - s4 + s3) * tH - s3*s3 + s3 * (s1 + s4)
+ - 3. * s1 * s4 - (s1 - s4 - s3 + tH) * sH)
+ / ( (sH - s1) * (tH - s4) );
+ double sigma = alpEM * pow2(sH / (sH - s1) ) * (smm1 + smm2 + smm3
+ + smm12 + smm13 + smm23) / (4. * sH2);
+
+ // Lepton Yukawa and secondary widths.
+ sigma *= pow2(yukawa[(idInAbs-9)/2]);
+ sigma *= (idIn < 0) ? openFracPos : openFracNeg;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2lgm2Hchgchgl::setIdColAcol() {
+
+ // Sign of outgoing H_L/R.
+ int idIn = (id2 == 22) ? id1 : id2;
+ int idSgn = (idIn < 0) ? idHLR : -idHLR;
+ int idOut = (idIn < 0) ? idLep : -idLep;
+ setId( id1, id2, idSgn, idOut);
+
+ // tHat is defined between incoming lepton and outgoing Higgs.
+ if (id1 == 22) swapTU = true;
+
+ // No colours whatsoever.
+ setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+
+}
+
+//*********
+
+// Evaluate weight for H_L/R sequential decay angles.
+
+double Sigma2lgm2Hchgchgl::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else isotropic decay.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma3ff2HchgchgfftWW class.
+// Cross section for f_1 f_2 -> H0 f_3 f_4 (W+ W- fusion of SM Higgs).
+
+//*********
+
+// Initialize process.
+
+void Sigma3ff2HchgchgfftWW::initProc() {
+
+ // Set process properties: H_L^++-- or H_R^++--.
+ if (leftRight == 1) {
+ idHLR = 9900041;
+ codeSave = 3125;
+ nameSave = "f_1 f_2 -> H_L^++-- f_3 f_4 (W+- W+- fusion)";
+ } else {
+ idHLR = 9900042;
+ codeSave = 3145;
+ nameSave = "f_1 f_2 -> H_R^++-- f_3 f_4 (W+- W+- fusion)";
+ }
+
+ // Common fixed mass and coupling factor.
+ double mW = ParticleDataTable::m0(24);
+ double mWR = ParticleDataTable::m0(9900024);
+ mWS = (leftRight == 1) ? pow2(mW) : pow2(mWR);
+ double gL = Settings::parm("LeftRightSymmmetry:gL");
+ double gR = Settings::parm("LeftRightSymmmetry:gR");
+ double vL = Settings::parm("LeftRightSymmmetry:vL");
+ prefac = (leftRight == 1) ? pow2(pow4(gL) * vL)
+ : 2. * pow2(pow3(gR) * mWR);
+ // Secondary open width fractions.
+ openFracPos = ParticleDataTable::resOpenFrac( idHLR);
+ openFracNeg = ParticleDataTable::resOpenFrac(-idHLR);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma3ff2HchgchgfftWW::sigmaKin() {
+
+ // Required four-vector products.
+ double pp12 = 0.5 * sH;
+ double pp14 = 0.5 * mH * p4cm.pMinus();
+ double pp15 = 0.5 * mH * p5cm.pMinus();
+ double pp24 = 0.5 * mH * p5cm.pPlus();
+ double pp25 = 0.5 * mH * p5cm.pPlus();
+ double pp45 = p4cm * p5cm;
+
+ // Cross section: kinematics part. Combine with couplings.
+ double propT = 1. / ( (2. * pp14 + mWS) * (2. * pp25 + mWS) );
+ double propU = 1. / ( (2. * pp24 + mWS) * (2. * pp15 + mWS) );
+ sigma0TU = prefac * pp12 * pp45 * pow2(propT + propU);
+ sigma0T = prefac * pp12 * pp45 * 2. * pow2(propT);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma3ff2HchgchgfftWW::sigmaHat() {
+
+ // Do not allow creation of righthanded neutrinos for H_R.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ if ( leftRight == 2 && (id1Abs > 10 || id2Abs > 10) ) return 0.;
+
+ // Many flavour combinations not possible because of charge.
+ int chg1 = (( id1Abs%2 == 0 && id1 > 0)
+ || (id1Abs%2 == 1 && id1 < 0) ) ? 1 : -1;
+ int chg2 = (( id2Abs%2 == 0 && id2 > 0)
+ || (id2Abs%2 == 1 && id2 < 0) ) ? 1 : -1;
+ if (abs(chg1 + chg2) != 2) return 0.;
+
+ // Basic cross section. CKM factors for final states.
+ double sigma = (id2 == id1 && id1Abs > 10) ? sigma0TU : sigma0T;
+ sigma *= VCKM::V2sum(id1Abs) * VCKM::V2sum(id2Abs);
+
+ // Secondary width for H0.
+ sigma *= (chg1 + chg2 == 2) ? openFracPos : openFracNeg;
+
+ // Spin-state extra factor 2 per incoming neutrino.
+ if (id1Abs == 12 || id1Abs == 14 || id1Abs == 16) sigma *= 2.;
+ if (id2Abs == 12 || id2Abs == 14 || id2Abs == 16) sigma *= 2.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma3ff2HchgchgfftWW::setIdColAcol() {
+
+ // Pick out-flavours by relative CKM weights.
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ id4 = VCKM::V2pick(id1);
+ id5 = VCKM::V2pick(id2);
+
+ // Find charge of Higgs .
+ id3 = (( id1Abs%2 == 0 && id1 > 0) || (id1Abs%2 == 1 && id1 < 0) )
+ ? idHLR : -idHLR;
+ setId( id1, id2, id3, id4, id5);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id1Abs < 9 && id2Abs < 9 && id1*id2 > 0)
+ setColAcol( 1, 0, 2, 0, 0, 0, 1, 0, 2, 0);
+ else if (id1Abs < 9 && id2Abs < 9)
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 0, 0, 2);
+ else if (id1Abs < 9) setColAcol( 1, 0, 0, 0, 0, 0, 1, 0, 0, 0);
+ else if (id2Abs < 9) setColAcol( 0, 0, 1, 0, 0, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ if ( (id1Abs < 9 && id1 < 0) || (id1Abs > 10 && id2 < 0) )
+ swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles.
+
+double Sigma3ff2HchgchgfftWW::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else done.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2ffbar2HchgchgHchgchg class.
+// Cross section for f fbar -> H_(L/R)^++ H_(L/R)^-- (doubly charged Higgs).
+
+//*********
+
+// Initialize process.
+
+void Sigma2ffbar2HchgchgHchgchg::initProc() {
+
+ // Set process properties: H_L^++ H_L^-- or H_R^++ H_R^--.
+ if (leftRight == 1) {
+ idHLR = 9900041;
+ codeSave = 3126;
+ nameSave = "f fbar -> H_L^++ H_L^--";
+ } else {
+ idHLR = 9900042;
+ codeSave = 3146;
+ nameSave = "f fbar -> H_R^++ H_R^--";
+ }
+
+ // Read in Yukawa matrix for couplings to a lepton pair.
+ yukawa[1][1] = Settings::parm("LeftRightSymmmetry:coupHee");
+ yukawa[2][1] = Settings::parm("LeftRightSymmmetry:coupHmue");
+ yukawa[2][2] = Settings::parm("LeftRightSymmmetry:coupHmumu");
+ yukawa[3][1] = Settings::parm("LeftRightSymmmetry:coupHtaue");
+ yukawa[3][2] = Settings::parm("LeftRightSymmmetry:coupHtaumu");
+ yukawa[3][3] = Settings::parm("LeftRightSymmmetry:coupHtautau");
+
+ // Electroweak parameters.
+ mRes = ParticleDataTable::m0(23);
+ GammaRes = ParticleDataTable::mWidth(23);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ sin2tW = CoupEW::sin2thetaW();
+ preFac = (1. - 2. * sin2tW) / ( 8. * sin2tW * (1. - sin2tW) );
+
+ // Open fraction from secondary widths.
+ openFrac = ParticleDataTable::resOpenFrac( idHLR, -idHLR);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma2ffbar2HchgchgHchgchg::sigmaHat() {
+
+ // Electroweak couplings to gamma^*/Z^0.
+ int idAbs = abs(id1);
+ double ei = CoupEW::ef(idAbs);
+ double vi = CoupEW::vf(idAbs);
+ double ai = CoupEW::af(idAbs);
+
+ // Part via gamma^*/Z^0 propagator.No Z^0 coupling to H_R.
+ double resProp = 1. / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double sigma = 8. * pow2(alpEM) * ei*ei / sH2;
+ if (leftRight == 1) sigma += 8. * pow2(alpEM)
+ * (2. * ei * vi * preFac * (sH - m2Res) * resProp / sH
+ + (vi * vi + ai * ai) * pow2(preFac) * resProp);
+
+ // Part via t-channel lepton + interference; sum over possibilities.
+ if (idAbs == 11 || idAbs == 13 || idAbs == 15) {
+ double yuk2Sum;
+ if (idAbs == 11) yuk2Sum
+ = pow2(yukawa[1][1]) + pow2(yukawa[2][1]) + pow2(yukawa[3][1]);
+ else if (idAbs == 13) yuk2Sum
+ = pow2(yukawa[2][1]) + pow2(yukawa[2][2]) + pow2(yukawa[3][2]);
+ else yuk2Sum
+ = pow2(yukawa[3][1]) + pow2(yukawa[3][2]) + pow2(yukawa[3][3]);
+ yuk2Sum /= 4. * M_PI;
+ sigma += 8. * alpEM * ei * yuk2Sum / (sH * tH)
+ + 4. * pow2(yuk2Sum) / tH2;
+ if (leftRight == 1) sigma += 8. * alpEM * (vi + ai) * yuk2Sum
+ * preFac * (sH - m2Res) * resProp / tH;
+ }
+
+ // Common kinematical factor. Colour factor.
+ sigma *= M_PI * (tH * uH - s3 * s4) / sH2;
+ if (idAbs < 9) sigma /= 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2ffbar2HchgchgHchgchg::setIdColAcol() {
+
+ // Outgoing flavours trivial.
+ setId( id1, id2, idHLR, -idHLR);
+
+ // tHat is defined between incoming fermion and outgoing H--.
+ if (id1 > 0) swapTU = true;
+
+ // No colours at all or one flow topology. Swap if first is antiquark.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for H_L/R sequential decay angles.
+
+double Sigma2ffbar2HchgchgHchgchg::weightDecay( Event& process,
+ int iResBeg, int iResEnd) {
+
+ // Identity of mother of decaying reseonance(s).
+ int idMother = process[process[iResBeg].mother1()].idAbs();
+
+ // For top decay hand over to standard routine.
+ if (idMother == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Else isotropic decay.
+ return 1.;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaLeptoquark.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// leptoquark simulation classes.
+
+#include "SigmaLeptoquark.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma1ql2LeptoQuark class.
+// Cross section for q l -> LQ (leptoquark state).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ql2LeptoQuark::initProc() {
+
+ // Store LQ mass and width for propagator.
+ mRes = ParticleDataTable::m0(42);
+ GammaRes = ParticleDataTable::mWidth(42);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Yukawa coupling strength.
+ kCoup = Settings::parm("LeptoQuark:kCoup");
+
+ // Set pointer to particle properties and decay table.
+ LQPtr = ParticleDataTable::particleDataPtr(42);
+
+ // Read out quark and lepton the LQ couples to.
+ idQuark = LQPtr->decay[0].product(0);
+ idLepton = LQPtr->decay[0].product(1);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ql2LeptoQuark::sigmaKin() {
+
+ // Incoming width for correct quark-lepton pair..
+ widthIn = 0.25 * alpEM * kCoup * mH;
+
+ // Set up Breit-Wigner.
+ sigBW = 4. * M_PI/ ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat) for specific incoming flavours.
+
+double Sigma1ql2LeptoQuark::sigmaHat() {
+
+ // Identify whether correct incoming flavours.
+ int idLQ = 0;
+ if (id1 == idQuark && id2 == idLepton) idLQ = 42;
+ else if (id2 == idQuark && id1 == idLepton) idLQ = 42;
+ else if (id1 == -idQuark && id2 == -idLepton) idLQ = -42;
+ else if (id2 == -idQuark && id1 == -idLepton) idLQ = -42;
+ if (idLQ == 0) return 0.;
+
+ // Outgoing width and total sigma. Done.
+ return widthIn * sigBW * LQPtr->resWidthOpen(idLQ, mH);
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ql2LeptoQuark::setIdColAcol() {
+
+ // Flavours.
+ int idq = (abs(id1) < 9) ? id1 : id2;
+ int idLQ = (idq > 0) ? 42 : -42;
+ setId( id1, id2, idLQ);
+
+ // Colour flow topology.
+ if (id1 == idq) setColAcol( 1, 0, 0, 0, 1, 0);
+ else setColAcol( 0, 0, 1, 0, 1, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2LeptoQuarkl class.
+// Cross section for q g -> LQ l (leptoquark state).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2LeptoQuarkl::initProc() {
+
+ // Store LQ mass and width for propagator.
+ mRes = ParticleDataTable::m0(42);
+ GammaRes = ParticleDataTable::mWidth(42);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Yukawa coupling strength.
+ kCoup = Settings::parm("LeptoQuark:kCoup");
+
+ // Read out quark and lepton the LQ couples to.
+ ParticleDataEntry* LQPtr = ParticleDataTable::particleDataPtr(42);
+ idQuark = LQPtr->decay[0].product(0);
+ idLepton = LQPtr->decay[0].product(1);
+
+ // Secondary open width fraction.
+ openFracPos = LQPtr->resOpenFrac( 42);
+ openFracNeg = LQPtr->resOpenFrac(-42);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qg2LeptoQuarkl::sigmaKin() {
+
+ // Evaluate cross section.
+ sigma0 = (M_PI / sH2) * kCoup * (alpS * alpEM / 6.) * (-tH / sH)
+ * (uH2 + s3 * s3) / pow2(uH - s3);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat) for specific incoming flavours.
+
+double Sigma2qg2LeptoQuarkl::sigmaHat() {
+
+ // Check that correct incoming flavour.
+ if (abs(id1) != idQuark && abs(id2) != idQuark) return 0.;
+
+ // Answer, with secondary width correction.
+ double sigma = sigma0;
+ sigma *= (id1 == idQuark || id2 == idQuark) ? openFracPos : openFracNeg;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2LeptoQuarkl::setIdColAcol() {
+
+ // Flavour set up for q g -> H q.
+ int idq = (id2 == 21) ? id1 : id2;
+ int idLQ = (idq > 0) ? 42 : -42;
+ int idlp = (idq > 0) ? idLepton : -idLepton;
+ setId( id1, id2, idLQ, idlp);
+
+ // tH defined between f and f': must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 2, 0, 0, 0);
+ else setColAcol( 2, 1, 1, 0, 2, 0, 0, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2LQLQbar class.
+// Cross section for g g -> LQ LQbar (leptoquark state).
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2LQLQbar::initProc() {
+
+ // Store LQ mass and width for propagator.
+ mRes = ParticleDataTable::m0(42);
+ GammaRes = ParticleDataTable::mWidth(42);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(42, -42);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2gg2LQLQbar::sigmaKin() {
+
+ // Average outgoing masses and adjust kinematics accordingly.
+ double delta = 0.25 * pow2(s3 - s4) / sH;
+ double m2avg = 0.5 * (s3 + s4) - delta;
+ double tHavg = tH - delta;
+ double uHavg = uH - delta;
+
+ // Evaluate cross section. Secondary width for G*.
+ sigma = (M_PI / sH2) * 0.5 * pow2(alpS)
+ * ( 7. / 48. + 3. * pow2(uHavg - tHavg) / (16. * sH2) )
+ * ( 1. + 2. * m2avg * tHavg / pow2(tHavg - m2avg)
+ + 2. * m2avg * uHavg / pow2(uHavg - m2avg)
+ + 4. * m2avg * m2avg / ((tHavg - m2avg) * (uHavg - m2avg)) );
+ sigma *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2LQLQbar::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( 21, 21, 42, -42);
+
+ // Colour flow topologies: random choice between two mirrors.
+ if (Rndm::flat() < 0.5) setColAcol( 1, 2, 2, 3, 1, 0, 0, 3);
+ else setColAcol( 1, 2, 3, 1, 3, 0, 0, 2);
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2LQLQbar class.
+// Cross section for q qbar -> LQ LQbar (leptoquark state).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2LQLQbar::initProc() {
+
+ // Store LQ mass and width for propagator.
+ mRes = ParticleDataTable::m0(42);
+ GammaRes = ParticleDataTable::mWidth(42);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+
+ // Yukawa coupling strength.
+ kCoup = Settings::parm("LeptoQuark:kCoup");
+
+ // Read out quark and lepton the LQ couples to.
+ ParticleDataEntry* LQPtr = ParticleDataTable::particleDataPtr(42);
+ idQuark = LQPtr->decay[0].product(0);
+
+ // Secondary open width fraction.
+ openFrac = ParticleDataTable::resOpenFrac(42, -42);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma2qqbar2LQLQbar::sigmaKin() {
+
+ // Average outgoing masses and adjust kinematics accordingly.
+ double delta = 0.25 * pow2(s3 - s4) / sH;
+ double m2avg = 0.5 * (s3 + s4) - delta;
+ double tHavg = tH - delta;
+ double uHavg = uH - delta;
+
+ // Evaluate cross section for quark of different flavour than LQ.
+ sigmaDiff = (M_PI / sH2) * (pow2(alpS) / 9.)
+ * ( sH * (sH - 4. * m2avg) - pow2(uHavg - tHavg) ) / sH2;
+
+ // Evaluate cross section for quark of same flavour as LQ.
+ sigmaSame = sigmaDiff + (M_PI / sH2) * (pow2(kCoup * alpEM) / 8.)
+ * (-sH * tHavg - pow2(m2avg-tHavg)) / pow2(tHavg)
+ + (M_PI / sH2) * (kCoup * alpEM * alpS / 18.) * ( (m2avg - tHavg)
+ * (uHavg - tHavg) + sH * (m2avg + tHavg) ) / (sH * tHavg);
+
+ // Open fraction.
+ sigmaDiff *= openFrac;
+ sigmaSame *= openFrac;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2LQLQbar::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, 42, -42);
+
+ // tH defined between f and LQ: must swap tHat <-> uHat if qbar q in.
+ swapTU = (id1 < 0);
+
+ // Colour flow topologies.
+ if (id1 > 0) setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
+ else setColAcol( 0, 2, 1, 0, 1, 0, 0, 2);
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaNewGaugeBosons.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// leptoquark simulation classes.
+
+#include "SigmaNewGaugeBosons.h"
+
+namespace Pythia8 {
+
+
+//**************************************************************************
+
+// Sigma1ffbarZprimeWprime class.
+// Collects common methods for f fbar -> Z'/W' -> WW/WZ -> 4 fermions.
+// Copied from SigmaEW for gauge-boson-pair production.
+
+//*********
+
+// Calculate and store internal products.
+
+void Sigma1ffbarZprimeWprime::setupProd( Event& process, int i1, int i2,
+ int i3, int i4, int i5, int i6) {
+
+ // Store incoming and outgoing momenta,
+ pRot[1] = process[i1].p();
+ pRot[2] = process[i2].p();
+ pRot[3] = process[i3].p();
+ pRot[4] = process[i4].p();
+ pRot[5] = process[i5].p();
+ pRot[6] = process[i6].p();
+
+ // Do random rotation to avoid accidental zeroes in HA expressions.
+ bool smallPT = false;
+ do {
+ smallPT = false;
+ double thetaNow = acos(2. * Rndm::flat() - 1.);
+ double phiNow = 2. * M_PI * Rndm::flat();
+ for (int i = 1; i <= 6; ++i) {
+ pRot[i].rot( thetaNow, phiNow);
+ if (pRot[i].pT2() < 1e-4 * pRot[i].pAbs2()) smallPT = true;
+ }
+ } while (smallPT);
+
+ // Calculate internal products.
+ for (int i = 1; i < 6; ++i) {
+ for (int j = i + 1; j <= 6; ++j) {
+ hA[i][j] =
+ sqrt( (pRot[i].e() - pRot[i].pz()) * (pRot[j].e() + pRot[j].pz())
+ / pRot[i].pT2() ) * complex( pRot[i].px(), pRot[i].py() )
+ - sqrt( (pRot[i].e() + pRot[i].pz()) * (pRot[j].e() - pRot[j].pz())
+ / pRot[j].pT2() ) * complex( pRot[j].px(), pRot[j].py() );
+ hC[i][j] = conj( hA[i][j] );
+ if (i <= 2) {
+ hA[i][j] *= complex( 0., 1.);
+ hC[i][j] *= complex( 0., 1.);
+ }
+ hA[j][i] = - hA[i][j];
+ hC[j][i] = - hC[i][j];
+ }
+ }
+
+}
+
+//*********
+
+// Evaluate the F function of Gunion and Kunszt.
+
+complex Sigma1ffbarZprimeWprime::fGK(int j1, int j2, int j3, int j4,
+ int j5, int j6) {
+
+ return 4. * hA[j1][j3] * hC[j2][j6]
+ * ( hA[j1][j5] * hC[j1][j4] + hA[j3][j5] * hC[j3][j4] );
+
+}
+
+//*********
+
+// Evaluate the Xi function of Gunion and Kunszt.
+
+double Sigma1ffbarZprimeWprime::xiGK( double tHnow, double uHnow,
+ double s3now, double s4now) {
+
+ return - 4. * s3now * s4now + tHnow * (3. * tHnow + 4. * uHnow)
+ + tHnow * tHnow * ( tHnow * uHnow / (s3now * s4now)
+ - 2. * (1. / s3now + 1./s4now) * (tHnow + uHnow)
+ + 2. * (s3now / s4now + s4now / s3now) );
+
+}
+
+//*********
+
+// Evaluate the Xj function of Gunion and Kunszt.
+
+double Sigma1ffbarZprimeWprime::xjGK( double tHnow, double uHnow,
+ double s3now, double s4now) {
+
+ return 8. * pow2(s3now + s4now) - 8. * (s3now + s4now) * (tHnow + uHnow)
+ - 6. * tHnow * uHnow - 2. * tHnow * uHnow * ( tHnow * uHnow
+ / (s3now * s4now) - 2. * (1. / s3now + 1. / s4now) * (tHnow + uHnow)
+ + 2. * (s3now / s4now + s4now / s3now) );
+
+}
+
+//*************************************************************************
+
+// Sigma1ffbar2gmZZprime class.
+// Cross section for f fbar -> gamma*/Z0/Z'0 (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2gmZZprime::initProc() {
+
+ // Allow to pick only parts of full gamma*/Z0/Z'0 expression.
+ gmZmode = Settings::mode("Zprime:gmZmode");
+
+ // Store Z'0 mass and width for propagator.
+ mRes = ParticleDataTable::m0(32);
+ GammaRes = ParticleDataTable::mWidth(32);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ sin2tW = CoupEW::sin2thetaW();
+ cos2tW = 1. - sin2tW;
+ thetaWRat = 1. / (16. * sin2tW * cos2tW);
+
+ // Properties of Z0 resonance also needed.
+ mZ = ParticleDataTable::m0(23);
+ GammaZ = ParticleDataTable::mWidth(23);
+ m2Z = mZ*mZ;
+ GamMRatZ = GammaZ / mZ;
+
+ // Ensure that arrays initially are empty.
+ for (int i = 0; i < 20; ++i) afZp[i] = 0.;
+ for (int i = 0; i < 20; ++i) vfZp[i] = 0.;
+
+ // Store first-generation axial and vector couplings.
+ afZp[1] = Settings::parm("Zprime:ad");
+ afZp[2] = Settings::parm("Zprime:au");
+ afZp[11] = Settings::parm("Zprime:ae");
+ afZp[12] = Settings::parm("Zprime:anue");
+ vfZp[1] = Settings::parm("Zprime:vd");
+ vfZp[2] = Settings::parm("Zprime:vu");
+ vfZp[11] = Settings::parm("Zprime:ve");
+ vfZp[12] = Settings::parm("Zprime:vnue");
+
+ // Second and third generation could be carbon copy of this...
+ if (Settings::flag("Zprime:universality")) {
+ for (int i = 3; i <= 6; ++i) {
+ afZp[i] = afZp[i-2];
+ vfZp[i] = vfZp[i-2];
+ afZp[i+10] = afZp[i+8];
+ vfZp[i+10] = vfZp[i+8];
+ }
+
+ // ... or could have different couplings.
+ } else {
+ afZp[3] = Settings::parm("Zprime:as");
+ afZp[4] = Settings::parm("Zprime:ac");
+ afZp[5] = Settings::parm("Zprime:ab");
+ afZp[6] = Settings::parm("Zprime:at");
+ afZp[13] = Settings::parm("Zprime:amu");
+ afZp[14] = Settings::parm("Zprime:anumu");
+ afZp[15] = Settings::parm("Zprime:atau");
+ afZp[16] = Settings::parm("Zprime:anutau");
+ vfZp[3] = Settings::parm("Zprime:vs");
+ vfZp[4] = Settings::parm("Zprime:vc");
+ vfZp[5] = Settings::parm("Zprime:vb");
+ vfZp[6] = Settings::parm("Zprime:vt");
+ vfZp[13] = Settings::parm("Zprime:vmu");
+ vfZp[14] = Settings::parm("Zprime:vnumu");
+ vfZp[15] = Settings::parm("Zprime:vtau");
+ vfZp[16] = Settings::parm("Zprime:vnutau");
+ }
+
+ // Coupling for Z' -> W+ W- and decay angular admixture.
+ coupZpWW = Settings::parm("Zprime:coup2WW");
+ anglesZpWW = Settings::parm("Zprime:anglesWW");
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(32);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2gmZZprime::sigmaKin() {
+
+ // Common coupling factors.
+ double colQ = 3. * (1. + alpS / M_PI);
+
+ // Reset quantities to sum. Declare variables in loop.
+ gamSum = 0.;
+ gamZSum = 0.;
+ ZSum = 0.;
+ gamZpSum = 0.;
+ ZZpSum = 0.;
+ ZpSum = 0.;
+ int idAbs, onMode;
+ double mf, mr, ps, kinFacA, kinFacV, ef, af, vf, apf, vpf,
+ ef2, efvf, vaf2, efvpf, vafvapf, vapf2, colf;
+
+ // Loop over all open Z'0 decay channels.
+ for (int i = 0; i < particlePtr->decay.size(); ++i) {
+ onMode = particlePtr->decay[i].onMode();
+ if (onMode != 1 && onMode != 2) continue;
+ idAbs = abs( particlePtr->decay[i].product(0) );
+
+ // Contributions from three fermion generations.
+ if ( (idAbs > 0 && idAbs < 7) || ( idAbs > 10 && idAbs < 17) ) {
+ mf = ParticleDataTable::m0(idAbs);
+
+ // Check that above threshold.
+ if (mH > 2. * mf + MASSMARGIN) {
+ mr = pow2(mf / mH);
+ ps = sqrtpos(1. - 4. * mr);
+
+ // Couplings of gamma^*/Z^0/Z'^0 to final flavour
+ ef = CoupEW::ef(idAbs);
+ af = CoupEW::af(idAbs);
+ vf = CoupEW::vf(idAbs);
+ apf = afZp[idAbs];
+ vpf = vfZp[idAbs];
+
+ // Combine couplings with kinematical factors.
+ kinFacA = pow3(ps);
+ kinFacV = ps * (1. + 2. * mr);
+ ef2 = ef * ef * kinFacV;
+ efvf = ef * vf * kinFacV;
+ vaf2 = vf * vf * kinFacV + af * af * kinFacA;
+ efvpf = ef * vpf * kinFacV;
+ vafvapf = vf * vpf * kinFacV + af * apf * kinFacA;
+ vapf2 = vpf * vpf * kinFacV + apf * apf * kinFacA;
+
+ // Colour factor. Additionally secondary width for top.
+ colf = (idAbs < 9) ? colQ : 1.;
+ if (idAbs == 6) colf *= ParticleDataTable::resOpenFrac(6, -6);
+
+ // Store sum of combinations.
+ gamSum += colf * ef2;
+ gamZSum += colf * efvf;
+ ZSum += colf * vaf2;
+ gamZpSum += colf * efvpf;
+ ZZpSum += colf * vafvapf;
+ ZpSum += colf * vapf2;
+ }
+
+ // Optional contribution from W+ W-.
+ } else if (idAbs == 24) {
+ mf = ParticleDataTable::m0(idAbs);
+ if (mH > 2. * mf + MASSMARGIN) {
+ mr = pow2(mf / mH);
+ ps = sqrtpos(1. - 4. * mr);
+ ZpSum += pow2(coupZpWW * cos2tW) * pow3(ps)
+ * (1. + 20. * mr + 12. * mr*mr)
+ * ParticleDataTable::resOpenFrac(24, -24);
+ }
+ }
+ }
+
+ // Calculate prefactors for gamma/Z0/Z'0 cross section terms.
+ double propZ = sH / ( pow2(sH - m2Z) + pow2(sH * GamMRatZ) );
+ double propZp = sH / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ gamNorm = 4. * M_PI * pow2(alpEM) / (3. * sH);
+ gamZNorm = gamNorm * 2. * thetaWRat * (sH - m2Z) * propZ;
+ ZNorm = gamNorm * pow2(thetaWRat) * sH * propZ;
+ gamZpNorm = gamNorm * 2. * thetaWRat * (sH - m2Res) * propZp;
+ ZZpNorm = gamNorm * 2. * pow2(thetaWRat) * ((sH - m2Z) * (sH - m2Res)
+ + sH * GamMRatZ * sH * GamMRat) * propZ * propZp;
+ ZpNorm = gamNorm * pow2(thetaWRat) * sH * propZp;
+
+ // Optionally only keep some of gamma*, Z0 and Z' terms.
+ if (gmZmode == 1) {gamZNorm = 0; ZNorm = 0.; gamZpNorm = 0.;
+ ZZpNorm = 0.; ZpNorm = 0.;}
+ if (gmZmode == 2) {gamNorm = 0.; gamZNorm = 0.; gamZpNorm = 0.;
+ ZZpNorm = 0.; ZpNorm = 0.;}
+ if (gmZmode == 3) {gamNorm = 0.; gamZNorm = 0.; ZNorm = 0.;
+ gamZpNorm = 0.; ZZpNorm = 0.;}
+ if (gmZmode == 4) {gamZpNorm = 0.; ZZpNorm = 0.; ZpNorm = 0.;}
+ if (gmZmode == 5) {gamZNorm = 0.; ZNorm = 0.; ZZpNorm = 0.;}
+ if (gmZmode == 6) {gamNorm = 0.; gamZNorm = 0.; gamZpNorm = 0.;}
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2gmZZprime::sigmaHat() {
+
+ // Couplings to an incoming flavour.
+ int idAbs = abs(id1);
+ double ei = CoupEW::ef(idAbs);
+ double ai = CoupEW::af(idAbs);
+ double vi = CoupEW::vf(idAbs);
+ double api = afZp[idAbs];
+ double vpi = vfZp[idAbs];
+ double ei2 = ei * ei;
+ double eivi = ei * vi;
+ double vai2 = vi * vi + ai * ai;
+ double eivpi = ei * vpi;
+ double vaivapi = vi * vpi + ai * api;;
+ double vapi2 = vpi * vpi + api * api;
+
+ // Combine gamma, interference and Z0 parts.
+ double sigma = ei2 * gamNorm * gamSum + eivi * gamZNorm * gamZSum
+ + vai2 * ZNorm * ZSum + eivpi * gamZpNorm * gamZpSum
+ + vaivapi * ZZpNorm * ZZpSum + vapi2 * ZpNorm * ZpSum;
+
+ // Colour factor. Answer.
+ if (idAbs < 9) sigma /= 3.;
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2gmZZprime::setIdColAcol() {
+
+ // Flavours trivial.
+ setId( id1, id2, 32);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for gamma*/Z0/Z'0 decay angle.
+
+double Sigma1ffbar2gmZZprime::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Default values, in- and out-flavours in process.
+ double wt = 1.;
+ double wtMax = 1.;
+ int idInAbs = process[3].idAbs();
+ int idOutAbs = process[6].idAbs();
+
+ // Angular weight for outgoing fermion pair.
+ if (iResBeg == 5 && iResEnd == 5 &&
+ (idOutAbs < 7 || ( idOutAbs > 10 && idOutAbs < 17)) ) {
+
+ // Couplings for in- and out-flavours.
+ double ei = CoupEW::ef(idInAbs);
+ double vi = CoupEW::vf(idInAbs);
+ double ai = CoupEW::af(idInAbs);
+ double vpi = vfZp[idInAbs];
+ double api = afZp[idInAbs];
+ double ef = CoupEW::ef(idOutAbs);
+ double vf = CoupEW::vf(idOutAbs);
+ double af = CoupEW::af(idOutAbs);
+ double vpf = vfZp[idOutAbs];
+ double apf = afZp[idOutAbs];
+
+ // Phase space factors. (One power of beta left out in formulae.)
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double ps = sqrtpos(pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+ double mrAvg = 0.5 * (mr1 + mr2) - 0.25 * pow2(mr1 - mr2);
+
+ // Coefficients of angular expression.
+ double coefTran = ei*ei * gamNorm * ef*ef + ei * vi * gamZNorm * ef * vf
+ + (vi*vi + ai*ai) * ZNorm * (vf*vf + ps*ps * af*af)
+ + ei * vpi * gamZpNorm * ef * vpf
+ + (vi * vpi + ai * api) * ZZpNorm * (vf * vpf + ps*ps * af * apf)
+ + (vpi*vpi + api*api) * ZpNorm * (vpf*vpf + ps*ps * apf*apf);
+ double coefLong = 4. * mrAvg * ( ei*ei * gamNorm * ef*ef
+ + ei * vi * gamZNorm * ef * vf + (vi*vi + ai*ai) * ZNorm * vf*vf
+ + ei * vpi * gamZpNorm * ef * vpf
+ + (vi * vpi + ai * api) * ZZpNorm * vf * vpf
+ + (vpi*vpi + api*api) * ZpNorm * vpf*vpf );
+ double coefAsym = ps * ( ei * ai * gamZNorm * ef * af
+ + 4. * vi * ai * ZNorm * vf * af + ei * api * gamZpNorm * ef * apf
+ + (vi * api + vpi * ai) * ZZpNorm * (vf * apf + vpf * af)
+ + 4. * vpi * api * ZpNorm * vpf * apf );
+
+ // Flip asymmetry for in-fermion + out-antifermion.
+ if (process[3].id() * process[6].id() < 0) coefAsym = -coefAsym;
+
+ // Reconstruct decay angle and weight for it.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * ps);
+ wt = coefTran * (1. + pow2(cosThe))
+ + coefLong * (1. - pow2(cosThe)) + 2. * coefAsym * cosThe;
+ wtMax = 2. * (coefTran + abs(coefAsym));
+ }
+
+ // Angular weight for Z' -> W+ W-.
+ else if (iResBeg == 5 && iResEnd == 5 && idOutAbs == 24) {
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double ps = sqrtpos(pow2(1. - mr1 -mr2) - 4. * mr1 * mr2);
+ double cCos2 = - (1./16.) * ps*ps * (1. - 2. * mr1 - 2. * mr2
+ + mr1*mr1 + mr2*mr2 + 10. * mr1 * mr2);
+ double cFlat = -cCos2 + 0.5 * (mr1 + mr2)
+ * (1. - 2. * mr1 - 2. * mr2 + pow2(mr1 - mr2));
+
+ // Reconstruct decay angle and weight for it.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * ps);
+ wt = cFlat + cCos2 * cosThe*cosThe;
+ wtMax = cFlat + max(0., cCos2);
+ }
+
+ // Angular weight for f + fbar -> Z' -> W+ + W- -> 4 fermions..
+ else if (iResBeg == 6 && iResEnd == 7 && idOutAbs == 24) {
+
+ // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
+ // with f' fbar' from W- and f" fbar" from W+.
+ int i1 = (process[3].id() < 0) ? 3 : 4;
+ int i2 = 7 - i1;
+ int i3 = (process[8].id() > 0) ? 8 : 9;
+ int i4 = 17 - i3;
+ int i5 = (process[10].id() > 0) ? 10 : 11;
+ int i6 = 21 - i5;
+ if (process[6].id() > 0) {swap(i3, i5); swap(i4, i6);}
+
+ // Decay distribution like in f fbar -> Z^* -> W+ W-.
+ if (Rndm::flat() > anglesZpWW) {
+
+ // Set up four-products and internal products.
+ setupProd( process, i1, i2, i3, i4, i5, i6);
+
+ // tHat and uHat of fbar f -> W- W+, and their squared masses.
+ int iNeg = (process[6].id() < 0) ? 6 : 7;
+ int iPos = 13 - iNeg;
+ double tHres = (process[i1].p() - process[iNeg].p()).m2Calc();
+ double uHres = (process[i1].p() - process[iPos].p()).m2Calc();
+ double s3now = process[iNeg].m2();
+ double s4now = process[iPos].m2();
+
+ // Kinematics combinations (norm(x) = |x|^2).
+ double fGK135 = norm(fGK( 1, 2, 3, 4, 5, 6) - fGK( 1, 2, 5, 6, 3, 4) );
+ double fGK253 = norm(fGK( 2, 1, 5, 6, 3, 4) - fGK( 2, 1, 3, 4, 5, 6) );
+ double xiT = xiGK( tHres, uHres, s3now, s4now);
+ double xiU = xiGK( uHres, tHres, s3now, s4now);
+ double xjTU = xjGK( tHres, uHres, s3now, s4now);
+
+ // Couplings of incoming (anti)fermion. Combine with kinematics.
+ int idAbs = process[i1].idAbs();
+ double li = 0.5 * (vfZp[idAbs] + afZp[idAbs]);
+ double ri = 0.5 * (vfZp[idAbs] - afZp[idAbs]);
+ wt = li*li * fGK135 + ri*ri * fGK253;
+ wtMax = 4. * s3now * s4now * (li*li + ri*ri)
+ * (xiT + xiU - xjTU);
+
+ // Decay distribution like in f fbar -> h^0 -> W+ W-.
+ } else {
+ double p35 = 2. * process[i3].p() * process[i5].p();
+ double p46 = 2. * process[i4].p() * process[i6].p();
+ wt = 16. * p35 * p46;
+ wtMax = sH2;
+ }
+ }
+
+ // Angular weight in top decay by standard routine.
+ else if (process[process[iResBeg].mother1()].idAbs() == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+//**************************************************************************
+
+// Sigma1ffbar2Wprime class.
+// Cross section for f fbar' -> W'+- (f is quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2Wprime::initProc() {
+
+ // Store W+- mass and width for propagator.
+ mRes = ParticleDataTable::m0(34);
+ GammaRes = ParticleDataTable::mWidth(34);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+ // Axial and vector couplings of fermions.
+ aqWp = Settings::parm("Wprime:aq");
+ vqWp = Settings::parm("Wprime:vq");
+ alWp = Settings::parm("Wprime:al");
+ vlWp = Settings::parm("Wprime:vl");
+
+ // Coupling for W' -> W Z and decay angular admixture.
+ coupWpWZ = Settings::parm("Wprime:coup2WZ");
+ anglesWpWZ = Settings::parm("Wprime:anglesWZ");
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(34);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2Wprime::sigmaKin() {
+
+ // Set up Breit-Wigner. Cross section for W+ and W- separately.
+ double sigBW = 12. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double preFac = alpEM * thetaWRat * mH;
+ sigma0Pos = preFac * sigBW * particlePtr->resWidthOpen(34, mH);
+ sigma0Neg = preFac * sigBW * particlePtr->resWidthOpen(-34, mH);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2Wprime::sigmaHat() {
+
+ // Secondary width for W+ or W-. CKM and colour factors.
+ int idUp = (abs(id1)%2 == 0) ? id1 : id2;
+ double sigma = (idUp > 0) ? sigma0Pos : sigma0Neg;
+ if (abs(id1) < 7) sigma *= VCKM::V2id(abs(id1), abs(id2)) / 3.;
+
+ // Couplings.
+ if (abs(id1) < 7) sigma *= 0.5 * (aqWp * aqWp + vqWp * vqWp);
+ else sigma *= 0.5 * (alWp * alWp + vlWp * vlWp);
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2Wprime::setIdColAcol() {
+
+ // Sign of outgoing W.
+ int sign = 1 - 2 * (abs(id1)%2);
+ if (id1 < 0) sign = -sign;
+ setId( id1, id2, 34 * sign);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for W decay angle.
+
+double Sigma1ffbar2Wprime::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // Default values, in- and out-flavours in process.
+ double wt = 1.;
+ double wtMax = 1.;
+ int idInAbs = process[3].idAbs();
+ int idOutAbs = process[6].idAbs();
+
+ // Angular weight for outgoing fermion pair.
+ if (iResBeg == 5 && iResEnd == 5 &&
+ (idOutAbs < 7 || ( idOutAbs > 10 && idOutAbs < 17)) ) {
+
+ // Couplings for in- and out-flavours.
+ double ai = (idInAbs < 9) ? aqWp : alWp;
+ double vi = (idInAbs < 9) ? vqWp : vlWp;
+ double af = (idOutAbs < 9) ? aqWp : alWp;
+ double vf = (idOutAbs < 9) ? vqWp : vlWp;
+
+ // Asymmetry expression.
+ double coefAsym = 8. * vi * ai * vf * af
+ / ((vi*vi + ai*ai) * (vf*vf + af*af));
+
+ // Flip asymmetry for in-fermion + out-antifermion.
+ if (process[3].id() * process[6].id() < 0) coefAsym = -coefAsym;
+
+ // Phase space factors.
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double ps = sqrtpos(pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+
+ // Reconstruct decay angle and weight for it.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * ps);
+ wt = 1. + coefAsym * cosThe + cosThe * cosThe;
+ wtMax = 2. + abs(coefAsym);
+ }
+
+ // Angular weight for W' -> W Z.
+ else if (iResBeg == 5 && iResEnd == 5 && idOutAbs == 24) {
+ double mr1 = pow2(process[6].m()) / sH;
+ double mr2 = pow2(process[7].m()) / sH;
+ double ps = sqrtpos(pow2(1. - mr1 - mr2) - 4. * mr1 * mr2);
+ double cCos2 = - (1./16.) * ps*ps * (1. - 2. * mr1 - 2. * mr2
+ + mr1*mr1 + mr2*mr2 + 10. * mr1 * mr2);
+ double cFlat = -cCos2 + 0.5 * (mr1 + mr2)
+ * (1. - 2. * mr1 - 2. * mr2 + pow2(mr1 - mr2));
+
+ // Reconstruct decay angle and weight for it.
+ double cosThe = (process[3].p() - process[4].p())
+ * (process[7].p() - process[6].p()) / (sH * ps);
+ wt = cFlat + cCos2 * cosThe*cosThe;
+ wtMax = cFlat + max(0., cCos2);
+ }
+
+ // Angular weight for f + fbar -> W' -> W + Z -> 4 fermions.
+ else if (iResBeg == 6 && iResEnd == 7
+ && (idOutAbs == 24 || idOutAbs == 23)) {
+
+ // Order so that fbar(1) f(2) -> f'(3) fbar'(4) f"(5) fbar"(6).
+ // with f' fbar' from W and f" fbar" from Z.
+ int i1 = (process[3].id() < 0) ? 3 : 4;
+ int i2 = 7 - i1;
+ int i3 = (process[8].id() > 0) ? 8 : 9;
+ int i4 = 17 - i3;
+ int i5 = (process[10].id() > 0) ? 10 : 11;
+ int i6 = 21 - i5;
+ if (process[6].id() == 23) {swap(i3, i5); swap(i4, i6);}
+
+ // Decay distribution like in f fbar -> Z^* -> W+ W-.
+ if (Rndm::flat() > anglesWpWZ) {
+
+ // Set up four-products and internal products.
+ setupProd( process, i1, i2, i3, i4, i5, i6);
+
+ // tHat and uHat of fbar f -> W Z, and their squared masses.
+ int iW = (process[6].id() == 23) ? 7 : 6;
+ int iZ = 13 - iW;
+ double tHres = (process[i1].p() - process[iW].p()).m2Calc();
+ double uHres = (process[i1].p() - process[iZ].p()).m2Calc();
+ double s3now = process[iW].m2();
+ double s4now = process[iZ].m2();
+
+ // Kinematics combinations (norm(x) = |x|^2).
+ double fGK135 = norm(fGK( 1, 2, 3, 4, 5, 6) - fGK( 1, 2, 5, 6, 3, 4) );
+ double fGK136 = norm(fGK( 1, 2, 3, 4, 6, 5) - fGK( 1, 2, 6, 5, 3, 4) );
+ double xiT = xiGK( tHres, uHres, s3now, s4now);
+ double xiU = xiGK( uHres, tHres, s3now, s4now);
+ double xjTU = xjGK( tHres, uHres, s3now, s4now);
+
+ // Couplings of outgoing fermion from Z. Combine with kinematics.
+ int idAbs = process[i5].idAbs();
+ double lfZ = CoupEW::lf(idAbs);
+ double rfZ = CoupEW::rf(idAbs);
+ wt = lfZ*lfZ * fGK135 + rfZ*rfZ * fGK136;
+ wtMax = 4. * s3now * s4now * (lfZ*lfZ + rfZ*rfZ)
+ * (xiT + xiU - xjTU);
+
+ // Decay distribution like in f fbar -> H^+- -> W+- Z0.
+ } else {
+ double p35 = 2. * process[i3].p() * process[i5].p();
+ double p46 = 2. * process[i4].p() * process[i6].p();
+ wt = 16. * p35 * p46;
+ wtMax = sH2;
+ }
+ }
+
+ // Angular weight in top decay by standard routine.
+ else if (process[process[iResBeg].mother1()].idAbs() == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+
+ // Done.
+ return (wt / wtMax);
+
+}
+
+
+//**************************************************************************
+
+// Sigma1ffbar2Rhorizontal class.
+// Cross section for f fbar' -> R^0 (f is a quark or lepton).
+
+//*********
+
+// Initialize process.
+
+void Sigma1ffbar2Rhorizontal::initProc() {
+
+ // Store R^0 mass and width for propagator.
+ mRes = ParticleDataTable::m0(41);
+ GammaRes = ParticleDataTable::mWidth(41);
+ m2Res = mRes*mRes;
+ GamMRat = GammaRes / mRes;
+ thetaWRat = 1. / (12. * CoupEW::sin2thetaW());
+
+ // Set pointer to particle properties and decay table.
+ particlePtr = ParticleDataTable::particleDataPtr(41);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), part independent of incoming flavour.
+
+void Sigma1ffbar2Rhorizontal::sigmaKin() {
+
+ // Set up Breit-Wigner. Cross section for W+ and W- separately.
+ double sigBW = 12. * M_PI / ( pow2(sH - m2Res) + pow2(sH * GamMRat) );
+ double preFac = alpEM * thetaWRat * mH;
+ sigma0Pos = preFac * sigBW * particlePtr->resWidthOpen(41, mH);
+ sigma0Neg = preFac * sigBW * particlePtr->resWidthOpen(-41, mH);
+
+}
+
+//*********
+
+// Evaluate sigmaHat(sHat), including incoming flavour dependence.
+
+double Sigma1ffbar2Rhorizontal::sigmaHat() {
+
+ // Check for allowed flavour combinations, one generation apart.
+ if (id1 * id2 > 0 || abs(id1 + id2) != 2) return 0.;
+
+ // Find whether R0 or R0bar. Colour factors.
+ double sigma = (id1 + id2 > 0) ? sigma0Pos : sigma0Neg;
+ if (abs(id1) < 7) sigma /= 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma1ffbar2Rhorizontal::setIdColAcol() {
+
+ // Outgoing R0 or R0bar.
+ id3 = (id1 +id2 > 0) ? 41 : -41;
+ setId( id1, id2, id3);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaOnia.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// charmonia/bottomonia simulation classes.
+
+#include "SigmaOnia.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma2gg2QQbar3S11g class.
+// Cross section g g -> QQbar[3S1(1)] g (Q = c or b).
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2QQbar3S11g::initProc() {
+
+ // Produced state. Process name. Onium matrix element.
+ idHad = (idNew == 4) ? 443 : 553;
+ nameSave = (idNew == 4) ? "g g -> ccbar[3S1(1)] g"
+ : "g g -> bbbar[3S1(1)] g";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi3S11")
+ : Settings::parm("Bottomonium:OUpsilon3S11");
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat); no explicit flavour dependence.
+
+void Sigma2gg2QQbar3S11g::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ double stH = sH + tH;
+ double tuH = tH + uH;
+ double usH = uH + sH;
+ double sig = (10. * M_PI / 81.) * m3 * ( pow2(sH * tuH)
+ + pow2(tH * usH) + pow2(uH * stH) ) / pow2( stH * tuH * usH );
+
+ // Answer.
+ sigma = (M_PI/sH2) * pow3(alpS) * oniumME * sig;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2QQbar3S11g::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, idHad, 21);
+
+ // Two orientations of colour flow..
+ setColAcol( 1, 2, 2, 3, 0, 0, 1, 3);
+ if (Rndm::flat() > 0.5) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2QQbar3PJ1g class.
+// Cross section g g -> QQbar[3PJ(1)] g (Q = c or b, J = 0, 1 or 2).
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2QQbar3PJ1g::initProc() {
+
+ // Produced state. Process name. Onium matrix element.
+ idHad = 0;
+ nameSave = "illegal process";
+ if (jSave == 0) {
+ idHad = (idNew == 4) ? 10441 : 10551;
+ nameSave = (idNew == 4) ? "g g -> ccbar[3P0(1)] g"
+ : "g g -> bbbar[3P0(1)] g";
+ } else if (jSave == 1) {
+ idHad = (idNew == 4) ? 20443 : 20553;
+ nameSave = (idNew == 4) ? "g g -> ccbar[3P1(1)] g"
+ : "g g -> bbbar[3P1(1)] g";
+ } else if (jSave == 2) {
+ idHad = (idNew == 4) ? 445 : 555;
+ nameSave = (idNew == 4) ? "g g -> ccbar[3P2(1)] g"
+ : "g g -> bbbar[3P2(1)] g";
+ }
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:Ochic03P01")
+ : Settings::parm("Bottomonium:Ochib03P01");
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat); no explicit flavour dependence.
+
+void Sigma2gg2QQbar3PJ1g::sigmaKin() {
+
+ // Useful derived kinematics quantities.
+ double pRat = (sH * uH + uH * tH + tH * sH)/ sH2;
+ double qRat = tH * uH / sH2;
+ double rRat = s3 / sH;
+ double pRat2 = pRat * pRat;
+ double pRat3 = pRat2 * pRat;
+ double pRat4 = pRat3 * pRat;
+ double qRat2 = qRat * qRat;
+ double qRat3 = qRat2 * qRat;
+ double qRat4 = qRat3 * qRat;
+ double rRat2 = rRat * rRat;
+ double rRat3 = rRat2 * rRat;
+ double rRat4 = rRat3 * rRat;
+
+ // Calculate kinematics dependence.
+ double sig = 0.;
+ if (jSave == 0) {
+ sig = (8. * M_PI / (9. * m3 * sH))
+ * ( 9. * rRat2 * pRat4 * (rRat4 - 2. * rRat2 * pRat + pRat2)
+ - 6. * rRat * pRat3 * qRat * (2. * rRat4 - 5. * rRat2 * pRat
+ + pRat2) - pRat2 * qRat2 * (rRat4 + 2. * rRat2 * pRat - pRat2)
+ + 2. * rRat * pRat * qRat3 * (rRat2 - pRat) + 6. * rRat2 * qRat4)
+ / (qRat * pow4(qRat - rRat * pRat));
+ } else if (jSave == 1) {
+ sig = (8. * M_PI / (3.* m3 * sH)) * pRat2
+ * (rRat * pRat2 * (rRat2 - 4. * pRat)
+ + 2. * qRat * (-rRat4 + 5. * rRat2 * pRat + pRat2)
+ - 15. * rRat * qRat2) / pow4(qRat - rRat * pRat);
+ } else if (jSave == 2) {
+ sig = (8. * M_PI / (9. * m3 * sH))
+ * (12. * rRat2 * pRat4 * (rRat4 - 2. * rRat2 * pRat + pRat2)
+ - 3. * rRat * pRat3 * qRat * (8. * rRat4 - rRat2 * pRat + 4. * pRat2)
+ + 2. * pRat2 * qRat2 * (-7. * rRat4 + 43. * rRat2 * pRat + pRat2)
+ + rRat * pRat * qRat3 * (16. * rRat2 - 61. * pRat)
+ + 12. * rRat2 * qRat4) / (qRat * pow4(qRat-rRat * pRat));
+ }
+
+ // Answer.
+ sigma = (M_PI/sH2) * pow3(alpS) * oniumME * sig;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2QQbar3PJ1g::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, idHad, 21);
+
+ // Two orientations of colour flow.
+ setColAcol( 1, 2, 2, 3, 0, 0, 1, 3);
+ if (Rndm::flat() > 0.5) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2QQbar3PJ1q class.
+// Cross section q g -> QQbar[3PJ(1)] q (Q = c or b, J = 0, 1 or 2).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2QQbar3PJ1q::initProc() {
+
+ // Produced state. Process name. Onium matrix element.
+ idHad = 0;
+ nameSave = "illegal process";
+ if (jSave == 0) {
+ idHad = (idNew == 4) ? 10441 : 10551;
+ nameSave = (idNew == 4) ? "q g -> ccbar[3P0(1)] q"
+ : "q g -> bbbar[3P0(1)] q";
+ } else if (jSave == 1) {
+ idHad = (idNew == 4) ? 20443 : 20553;
+ nameSave = (idNew == 4) ? "q g -> ccbar[3P1(1)] q"
+ : "q g -> bbbar[3P1(1)] q";
+ } else if (jSave == 2) {
+ idHad = (idNew == 4) ? 445 : 555;
+ nameSave = (idNew == 4) ? "q g -> ccbar[3P2(1)] q"
+ : "q g -> bbbar[3P2(1)] q";
+ }
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:Ochic03P01")
+ : Settings::parm("Bottomonium:Ochib03P01");
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat); no explicit flavour dependence.
+
+void Sigma2qg2QQbar3PJ1q::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ double usH = uH + sH;
+ double sig = 0.;
+ if (jSave == 0) {
+ sig = - (16. * M_PI / 81.) * pow2(tH - 3. * s3) * (sH2 + uH2)
+ / (m3 * tH * pow4(usH));
+ } else if (jSave == 1) {
+ sig = - (32. * M_PI / 27.) * (4. * s3 * sH * uH + tH * (sH2 + uH2))
+ / (m3 * pow4(usH));
+ } else if (jSave == 2) {
+ sig = - (32. *M_PI / 81.) * ( (6. * s3*s3 + tH2) * pow2(usH)
+ - 2. * sH * uH * (tH2 + 6. * s3 * usH)) / (m3 * tH * pow4(usH));
+ }
+
+ // Answer.
+ sigma = (M_PI/sH2) * pow3(alpS) * oniumME * sig;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2QQbar3PJ1q::setIdColAcol() {
+
+ // Flavours are trivial.
+ int idq = (id2 == 21) ? id1 : id2;
+ setId( id1, id2, idHad, idq);
+
+ // tH defined between q_in and q_out: must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id2 == 21) setColAcol( 1, 0, 2, 1, 0, 0, 2, 0);
+ else setColAcol( 2, 1, 1, 0, 0, 0, 2, 0);
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2QQbar3PJ1g class.
+// Cross section q qbar -> QQbar[3PJ(1)] g (Q = c or b, J = 0, 1 or 2).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2QQbar3PJ1g::initProc() {
+
+ // Produced state. Process name. Onium matrix element.
+ idHad = 0;
+ nameSave = "illegal process";
+ if (jSave == 0) {
+ idHad = (idNew == 4) ? 10441 : 10551;
+ nameSave = (idNew == 4) ? "q qbar -> ccbar[3P0(1)] g"
+ : "q qbar -> bbbar[3P0(1)] g";
+ } else if (jSave == 1) {
+ idHad = (idNew == 4) ? 20443 : 20553;
+ nameSave = (idNew == 4) ? "q qbar -> ccbar[3P1(1)] g"
+ : "q qbar -> bbbar[3P1(1)] g";
+ } else if (jSave == 2) {
+ idHad = (idNew == 4) ? 445 : 555;
+ nameSave = (idNew == 4) ? "q qbar -> ccbar[3P2(1)] g"
+ : "q qbar -> bbbar[3P2(1)] g";
+ }
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:Ochic03P01")
+ : Settings::parm("Bottomonium:Ochib03P01");
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat); no explicit flavour dependence.
+
+void Sigma2qqbar2QQbar3PJ1g::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ double tuH = tH + uH;
+ double sig = 0.;
+ if (jSave == 0) {
+ sig =(128. * M_PI / 243.) * pow2(sH - 3. * s3) * (tH2 + uH2)
+ / (m3 * sH * pow4(tuH));
+ } else if (jSave == 1) {
+ sig = (256. * M_PI / 81.) * (4. * s3 * tH * uH + sH * (tH2 + uH2))
+ / (m3 * pow4(tuH));
+ } else if (jSave == 2) {
+ sig = (256. * M_PI / 243.) * ( (6. * s3*s3 + sH2) * pow2(tuH)
+ - 2. * tH * uH * (sH2 + 6. * s3 * tuH) )/ (m3 * sH * pow4(tuH));
+ }
+
+ // Answer.
+ sigma = (M_PI/sH2) * pow3(alpS) * oniumME * sig;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2QQbar3PJ1g::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, idHad, 21);
+
+ // Colour flow topologies. Swap when antiquarks.
+ setColAcol( 1, 0, 0, 2, 0, 0, 1, 2);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2QQbarX8g class.
+// Cross section g g -> QQbar[X(8)] g (Q = c or b, X = 3S1, 1S0 or 3PJ).
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2QQbarX8g::initProc() {
+
+ // Produced state. Process name. Onium matrix element.
+ idHad = 0;
+ nameSave = "illegal process";
+ if (stateSave == 0) {
+ idHad = (idNew == 4) ? 9900443 : 9900553;
+ nameSave = (idNew == 4) ? "g g -> ccbar[3S1(8)] g"
+ : "g g -> bbbar[3S1(8)] g";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi3S18")
+ : Settings::parm("Bottomonium:OUpsilon3S18");
+ } else if (stateSave == 1) {
+ idHad = (idNew == 4) ? 9900441 : 9900551;
+ nameSave = (idNew == 4) ? "g g -> ccbar[1S0(8)] g"
+ : "g g -> bbbar[1S0(8)] g";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi1S08")
+ : Settings::parm("Bottomonium:OUpsilon1S08");
+ } else if (stateSave == 2) {
+ idHad = (idNew == 4) ? 9910441 : 9910551;
+ nameSave = (idNew == 4) ? "g g -> ccbar[3PJ(8)] g"
+ : "g g -> bbbar[3PJ(8)] g";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi3P08")
+ : Settings::parm("Bottomonium:OUpsilon3P08");
+ }
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat); no explicit flavour dependence.
+
+void Sigma2gg2QQbarX8g::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ double stH = sH + tH;
+ double tuH = tH + uH;
+ double usH = uH + sH;
+ double sig = 0.;
+ if (stateSave == 0) {
+ sig = (M_PI / 72.) * m3 * ( 27. * (pow2(stH) + pow2(tuH)
+ + pow2(usH)) / (s3*s3) - 16. ) * ( pow2(sH * tuH)
+ + pow2(tH * usH) + pow2(uH * stH) ) / pow2( stH * tuH * usH );
+ } else if (stateSave == 1) {
+ sig = (5. * M_PI / 16.) * m3 * ( pow2(uH / (tuH * usH))
+ + pow2(sH / (stH * usH)) + pow2(tH / (stH * tuH)) ) * ( 12.
+ + (pow4(stH) + pow4(tuH) + pow4(usH)) / (s3 * sH * tH * uH) );
+ } else if (stateSave == 2) {
+ double sH3 = sH2 * sH;
+ double sH4 = sH3 * sH;
+ double sH5 = sH4 * sH;
+ double sH6 = sH5 * sH;
+ double sH7 = sH6 * sH;
+ double sH8 = sH7 * sH;
+ double tH3 = tH2 * tH;
+ double tH4 = tH3 * tH;
+ double tH5 = tH4 * tH;
+ double tH6 = tH5 * tH;
+ double tH7 = tH6 * tH;
+ double tH8 = tH7 * tH;
+ double ssttH = sH * sH + sH * tH + tH * tH;
+ sig = 5. * M_PI * (3. * sH * tH * stH * pow4(ssttH)
+ - s3 * pow2(ssttH) * (7. * sH6 + 36. * sH5 * tH + 45. * sH4 * tH2
+ + 28. * sH3 * tH3 + 45. * sH2 * tH4 + 36. * sH * tH5 + 7. * tH6)
+ + pow2(s3) * stH * (35. *sH8 + 169. * sH7 * tH + 299. * sH6 * tH2
+ + 401. * sH5 * tH3 + 418. * sH4 * tH4 + 401. * sH3 * tH5
+ + 299. * sH2 * tH6 + 169. * sH * tH7 + 35. * tH8)
+ - pow3(s3) * (84. *sH8+432. *sH7*tH+905. *sH6*tH2
+ + 1287. * sH5 * tH3 + 1436. * sH4 * tH4 +1287. * sH3 * tH5
+ + 905. * sH2 * tH6 + 432. * sH * tH7 + 84. * tH8)
+ + pow4(s3) * stH * (126. * sH6 + 451. * sH5 * tH +677. * sH4 * tH2
+ + 836. * sH3 * tH3 + 677. * sH2 * tH4 + 451. * sH * tH5
+ + 126. * tH6)
+ - pow5(s3) * 3. * (42. * sH6 + 171. * sH5 * tH + 304. * sH4 * tH2
+ + 362. * sH3 * tH3 + 304. * sH2 * tH4 + 171. * sH * tH5
+ + 42. * tH6)
+ + pow3(s3 * s3) * 2. * stH * (42. * sH4 + 106. * sH3 * tH
+ + 119. * sH2 * tH2 + 106. * sH * tH3 + 42. * tH4)
+ - pow4(s3) * pow3(s3) * (35. * sH4 + 99. * sH3 * tH
+ + 120. * sH2 * tH2 + 99. * sH * tH3 + 35. * tH4)
+ + pow4(s3 * s3) * 7. * stH * ssttH)
+ / (sH * tH * uH * s3 * m3 * pow3(stH * tuH * usH));
+ }
+
+ // Answer.
+ sigma = (M_PI/sH2) * pow3(alpS) * oniumME * sig;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2QQbarX8g::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, idHad, 21);
+
+ // Split total contribution into different colour flows just like in
+ // g g -> g g (with kinematics recalculated for massless partons).
+ double sHr = - (tH + uH);
+ double sH2r = sHr * sHr;
+ double sigTS = tH2/sH2r + 2.*tH/sHr + 3. + 2.*sHr/tH + sH2r/tH2;
+ double sigUS = uH2/sH2r + 2.*uH/sHr + 3. + 2.*sHr/uH + sH2r/uH2;
+ double sigTU = tH2/uH2 + 2.*tH/uH + 3. + 2.*uH/tH + uH2/tH2;
+ double sigSum = sigTS + sigUS + sigTU;
+
+ // Three colour flow topologies, each with two orientations.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 4, 4, 3);
+ else if (sigRand < sigTS + sigUS)
+ setColAcol( 1, 2, 3, 1, 3, 4, 4, 2);
+ else setColAcol( 1, 2, 3, 4, 1, 4, 3, 2);
+ if (Rndm::flat() > 0.5) swapColAcol();
+
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2QQbarX8q class.
+// Cross section q g -> QQbar[X(8)] q (Q = c or b, X = 3S1, 1S0 or 3PJ).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qg2QQbarX8q::initProc() {
+
+ // Produced state. Process name. Onium matrix element.
+ idHad = 0;
+ nameSave = "illegal process";
+ if (stateSave == 0) {
+ idHad = (idNew == 4) ? 9900443 : 9900553;
+ nameSave = (idNew == 4) ? "q g -> ccbar[3S1(8)] q"
+ : "q g -> bbbar[3S1(8)] q";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi3S18")
+ : Settings::parm("Bottomonium:OUpsilon3S18");
+ } else if (stateSave == 1) {
+ idHad = (idNew == 4) ? 9900441 : 9900551;
+ nameSave = (idNew == 4) ? "q g -> ccbar[1S0(8)] q"
+ : "q g -> bbbar[1S0(8)] q";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi1S08")
+ : Settings::parm("Bottomonium:OUpsilon1S08");
+ } else if (stateSave == 2) {
+ idHad = (idNew == 4) ? 9910441 : 9910551;
+ nameSave = (idNew == 4) ? "q g -> ccbar[3PJ(8)] q"
+ : "q g -> bbbar[3PJ(8)] q";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi3P08")
+ : Settings::parm("Bottomonium:OUpsilon3P08");
+ }
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat); no explicit flavour dependence.
+
+void Sigma2qg2QQbarX8q::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ double stH = sH + tH;
+ double tuH = tH + uH;
+ double usH = uH + sH;
+ double stH2 = stH * stH;
+ double tuH2 = tuH * tuH;
+ double usH2 = usH * usH;
+ double sig = 0.;
+ if (stateSave == 0) {
+ sig = - (M_PI / 27.)* (4. * (sH2 + uH2) - sH * uH) * (stH2 +tuH2)
+ / (s3 * m3 * sH * uH * usH2);
+ } else if (stateSave == 1) {
+ sig = - (5. * M_PI / 18.) * (sH2 + uH2) / (m3 * tH * usH2);
+ } else if (stateSave == 2) {
+ sig = - (10. * M_PI / 9.) * ( (7. * usH + 8. * tH) * (sH2 + uH2)
+ + 4. * tH * (2. * pow2(s3) - stH2 - tuH2) )
+ / (s3 * m3 * tH * usH2 * usH);
+ }
+
+ // Answer.
+ sigma = (M_PI/sH2) * pow3(alpS) * oniumME * sig;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2QQbarX8q::setIdColAcol() {
+
+ // Flavours are trivial.
+ int idq = (id2 == 21) ? id1 : id2;
+ setId( id1, id2, idHad, idq);
+
+ // tH defined between q_in and q_out: must swap tHat <-> uHat if q g in.
+ swapTU = (id2 == 21);
+
+ // Split total contribution into different colour flows just like in
+ // q g -> q g (with kinematics recalculated for massless partons).
+ double sHr = - (tH + uH);
+ double sH2r = sHr * sHr;
+ double sigTS = uH2/tH2 - (4./9.) * uH/sHr;
+ double sigTU = sH2r/tH2 - (4./9.) * sHr/uH;
+ double sigSum = sigTS + sigTU;
+
+ // Two colour flow topologies. Swap if first is gluon, or when antiquark.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 0, 2, 1, 2, 3, 3, 0);
+ else setColAcol( 1, 0, 2, 3, 1, 3, 2, 0);
+ if (id1 == 21) swapCol12();
+ if (idq < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2QQbarX8g class.
+// Cross section q qbar -> QQbar[X(8)] g (Q = c or b, X = 3S1, 1S0 or 3PJ).
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2QQbarX8g::initProc() {
+
+ // Produced state. Process name. Onium matrix element.
+ idHad = 0;
+ nameSave = "illegal process";
+ if (stateSave == 0) {
+ idHad = (idNew == 4) ? 9900443 : 9900553;
+ nameSave = (idNew == 4) ? "q qbar -> ccbar[3S1(8)] g"
+ : "q qbar -> bbbar[3S1(8)] g";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi3S18")
+ : Settings::parm("Bottomonium:OUpsilon3S18");
+ } else if (stateSave == 1) {
+ idHad = (idNew == 4) ? 9900441 : 9900551;
+ nameSave = (idNew == 4) ? "q qbar -> ccbar[1S0(8)] g"
+ : "q qbar -> bbbar[1S0(8)] g";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi1S08")
+ : Settings::parm("Bottomonium:OUpsilon1S08");
+ } else if (stateSave == 2) {
+ idHad = (idNew == 4) ? 9910441 : 9910551;
+ nameSave = (idNew == 4) ? "q qbar -> ccbar[3PJ(8)] g"
+ : "q qbar -> bbbar[3PJ(8)] g";
+ oniumME = (idNew == 4) ? Settings::parm("Charmonium:OJpsi3P08")
+ : Settings::parm("Bottomonium:OUpsilon3P08");
+ }
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat); no explicit flavour dependence.
+
+void Sigma2qqbar2QQbarX8g::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ double stH = sH + tH;
+ double tuH = tH + uH;
+ double usH = uH + sH;
+ double stH2 = stH * stH;
+ double tuH2 = tuH * tuH;
+ double usH2 = usH * usH;
+ double sig = 0.;
+ if (stateSave == 0) {
+ sig = (8. * M_PI / 81.) * (4. * (tH2 + uH2) - tH * uH)
+ * (stH2 + usH2) / (s3 * m3 * tH * uH * tuH2);
+ } else if (stateSave == 1) {
+ sig = (20. * M_PI / 27.) * (tH2 + uH2) / (m3 * sH * tuH2);
+ } else if (stateSave == 2) {
+ sig = (80. * M_PI / 27.) * ( (7. * tuH + 8. * sH) * (tH2 + uH2)
+ + 4. * sH * (2. * pow2(s3) - stH2 -usH2) )
+ / (s3 * m3 * sH * tuH2 * tuH);
+ }
+
+ // Answer.
+ sigma = (M_PI/sH2) * pow3(alpS) * oniumME * sig;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2QQbarX8g::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, idHad, 21);
+
+ // Split total contribution into different colour flows just like in
+ // q qbar -> g g (with kinematics recalculated for massless partons).
+ double sHr = - (tH + uH);
+ double sH2r = sHr * sHr;
+ double sigTS = (4. / 9.) * uH / tH - uH2 / sH2r;
+ double sigUS = (4. / 9.) * tH / uH - tH2 / sH2r;
+ double sigSum = sigTS + sigUS;
+
+ // Two colour flow topologies. Swap if first is antiquark.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 0, 0, 2, 1, 3, 3, 2);
+ else setColAcol( 1, 0, 0, 2, 3, 2, 1, 3);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
--- /dev/null
+// SigmaProcess.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// SigmaProcess class, and classes derived from it.
+
+#include "SigmaProcess.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The SigmaProcess class.
+// Base class for cross sections.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Conversion of GeV^{-2} to mb for cross section.
+const double SigmaProcess::CONVERT2MB = 0.389380;
+
+// The sum of outgoing masses must not be too close to the cm energy.
+const double SigmaProcess::MASSMARGIN = 0.1;
+
+//*********
+
+// Perform simple initialization and store pointers.
+
+void SigmaProcess::init(Info* infoPtrIn, BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn, AlphaStrong* alphaSPtrIn,
+ AlphaEM* alphaEMPtrIn,SigmaTotal* sigmaTotPtrIn,
+ SusyLesHouches* slhaPtrIn) {
+
+ // Store pointers.
+ infoPtr = infoPtrIn;
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+ alphaSPtr = alphaSPtrIn;
+ alphaEMPtr = alphaEMPtrIn;
+ sigmaTotPtr = sigmaTotPtrIn;
+ slhaPtr = slhaPtrIn;
+
+ // Read out some properties of beams to allow shorthand.
+ idA = beamAPtr->id();
+ idB = beamBPtr->id();
+ mA = beamAPtr->m();
+ mB = beamBPtr->m();
+ isLeptonA = beamAPtr->isLepton();
+ isLeptonB = beamBPtr->isLepton();
+ hasLeptonBeams = isLeptonA || isLeptonB;
+
+ // K factor, multiplying resolved processes. (But not here for MI.)
+ Kfactor = Settings::parm("SigmaProcess:Kfactor");
+
+ // Maximum incoming quark flavour.
+ nQuarkIn = Settings::mode("PDFinProcess:nQuarkIn");
+
+ // Renormalization scale choice.
+ renormScale1 = Settings::mode("SigmaProcess:renormScale1");
+ renormScale2 = Settings::mode("SigmaProcess:renormScale2");
+ renormScale3 = Settings::mode("SigmaProcess:renormScale3");
+ renormScale3VV = Settings::mode("SigmaProcess:renormScale3VV");
+ renormMultFac = Settings::parm("SigmaProcess:renormMultFac");
+ renormFixScale = Settings::parm("SigmaProcess:renormFixScale");
+
+ // Factorization scale choice.
+ factorScale1 = Settings::mode("SigmaProcess:factorScale1");
+ factorScale2 = Settings::mode("SigmaProcess:factorScale2");
+ factorScale3 = Settings::mode("SigmaProcess:factorScale3");
+ factorScale3VV = Settings::mode("SigmaProcess:factorScale3VV");
+ factorMultFac = Settings::parm("SigmaProcess:factorMultFac");
+ factorFixScale = Settings::parm("SigmaProcess:factorFixScale");
+
+ // CP violation parameters for the BSM Higgs sector.
+ higgsH1parity = Settings::mode("HiggsH1:parity");
+ higgsH1eta = Settings::parm("HiggsH1:etaParity");
+ higgsH2parity = Settings::mode("HiggsH2:parity");
+ higgsH2eta = Settings::parm("HiggsH2:etaParity");
+ higgsA3parity = Settings::mode("HiggsA3:parity");
+ higgsA3eta = Settings::parm("HiggsA3:etaParity");
+
+ // If BSM not switched on then H1 should have SM properties.
+ if (!Settings::flag("Higgs:useBSM")){
+ higgsH1parity = 1;
+ higgsH1eta = 0.;
+ }
+
+}
+
+//*********
+
+// Set up allowed flux of incoming partons.
+// addBeam: set up PDF's that need to be evaluated for the two beams.
+// addPair: set up pairs of incoming partons from the two beams.
+
+bool SigmaProcess::initFlux() {
+
+ // Read in process-specific channel information.
+ string fluxType = inFlux();
+
+ // Case with g g incoming state.
+ if (fluxType == "gg") {
+ addBeamA(21);
+ addBeamB(21);
+ addPair(21, 21);
+ }
+
+ // Case with q g incoming state.
+ else if (fluxType == "qg") {
+ for (int i = -nQuarkIn; i <= nQuarkIn; ++i) {
+ int idNow = (i == 0) ? 21 : i;
+ addBeamA(idNow);
+ addBeamB(idNow);
+ }
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addPair(idNow, 21);
+ addPair(21, idNow);
+ }
+ }
+
+ // Case with q q', q qbar' or qbar qbar' incoming state.
+ else if (fluxType == "qq") {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addBeamB(idNow);
+ }
+ for (int id1Now = -nQuarkIn; id1Now <= nQuarkIn; ++id1Now)
+ if (id1Now != 0)
+ for (int id2Now = -nQuarkIn; id2Now <= nQuarkIn; ++id2Now)
+ if (id2Now != 0)
+ addPair(id1Now, id2Now);
+ }
+
+ // Case with q qbar incoming state.
+ else if (fluxType == "qqbarSame") {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addBeamB(idNow);
+ }
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0)
+ addPair(idNow, -idNow);
+ }
+
+ // Case with f f', f fbar', fbar fbar' incoming state.
+ else if (fluxType == "ff") {
+ // If beams are leptons then they are also the colliding partons.
+ if ( isLeptonA && isLeptonB ) {
+ addBeamA(idA);
+ addBeamB(idB);
+ addPair(idA, idB);
+ // First beam is lepton and second is hadron.
+ } else if ( isLeptonA ) {
+ addBeamA(idA);
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamB(idNow);
+ addPair(idA, idNow);
+ }
+ // First beam is hadron and second is lepton.
+ } else if ( isLeptonB ) {
+ addBeamB(idB);
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addPair(idNow, idB);
+ }
+ // Hadron beams gives quarks.
+ } else {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addBeamB(idNow);
+ }
+ for (int id1Now = -nQuarkIn; id1Now <= nQuarkIn; ++id1Now)
+ if (id1Now != 0)
+ for (int id2Now = -nQuarkIn; id2Now <= nQuarkIn; ++id2Now)
+ if (id2Now != 0)
+ addPair(id1Now, id2Now);
+ }
+ }
+
+ // Case with f fbar incoming state.
+ else if (fluxType == "ffbarSame") {
+ // If beams are antiparticle pair and leptons then also colliding partons.
+ if ( idA + idB == 0 && isLeptonA ) {
+ addBeamA(idA);
+ addBeamB(idB);
+ addPair(idA, idB);
+ // Else assume both to be hadrons, for better or worse.
+ } else {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addBeamB(idNow);
+ }
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0)
+ addPair(idNow, -idNow);
+ }
+ }
+
+ // Case with f fbar' charged(+-1) incoming state.
+ else if (fluxType == "ffbarChg") {
+ // If beams are leptons then also colliding partons.
+ if ( isLeptonA && isLeptonB && abs( ParticleDataTable::chargeType(idA)
+ + ParticleDataTable::chargeType(idB) ) == 3 ) {
+ addBeamA(idA);
+ addBeamB(idB);
+ addPair(idA, idB);
+ // Hadron beams gives quarks.
+ } else {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addBeamB(idNow);
+ }
+ for (int id1Now = -nQuarkIn; id1Now <= nQuarkIn; ++id1Now)
+ if (id1Now != 0)
+ for (int id2Now = -nQuarkIn; id2Now <= nQuarkIn; ++id2Now)
+ if (id2Now != 0 && id1Now * id2Now < 0
+ && (abs(id1Now) + abs(id2Now))%2 == 1) addPair(id1Now, id2Now);
+ }
+ }
+
+ // Case with f fbar' generic incoming state.
+ else if (fluxType == "ffbar") {
+ // If beams are leptons then also colliding partons.
+ if (isLeptonA && isLeptonB && idA * idB < 0) {
+ addBeamA(idA);
+ addBeamB(idB);
+ addPair(idA, idB);
+ // Hadron beams gives quarks.
+ } else {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addBeamB(idNow);
+ }
+ for (int id1Now = -nQuarkIn; id1Now <= nQuarkIn; ++id1Now)
+ if (id1Now != 0)
+ for (int id2Now = -nQuarkIn; id2Now <= nQuarkIn; ++id2Now)
+ if (id2Now != 0 && id1Now * id2Now < 0)
+ addPair(id1Now, id2Now);
+ }
+ }
+
+ // Case with f gamma incoming state.
+ else if (fluxType == "fgm") {
+ // Fermion from incoming side A.
+ if ( isLeptonA ) {
+ addBeamA(idA);
+ addPair(idA, 22);
+ } else {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamA(idNow);
+ addPair(idNow, 22);
+ }
+ }
+ // Fermion from incoming side B.
+ if ( isLeptonB ) {
+ addBeamB( idB);
+ addPair(22, idB);
+ } else {
+ for (int idNow = -nQuarkIn; idNow <= nQuarkIn; ++idNow)
+ if (idNow != 0) {
+ addBeamB(idNow);
+ addPair(22, idNow);
+ }
+ }
+ // Photons in the beams.
+ addBeamA(22);
+ addBeamB(22);
+ }
+
+ // Case with gamma gamma incoming state.
+ else if (fluxType == "ggm") {
+ addBeamA(21);
+ addBeamA(22);
+ addBeamB(21);
+ addBeamB(22);
+ addPair(21, 22);
+ addPair(22, 21);
+ }
+
+ // Case with gamma gamma incoming state.
+ else if (fluxType == "gmgm") {
+ addBeamA(22);
+ addBeamB(22);
+ addPair(22, 22);
+ }
+
+ // Unrecognized fluxType is bad sign. Else done.
+ else {
+ infoPtr->errorMsg("Error in SigmaProcess::initFlux: "
+ "unrecognized inFlux type", fluxType);
+ return false;
+ }
+ return true;
+
+}
+
+//*********
+
+// Convolute matrix-element expression(s) with parton flux and K factor.
+
+double SigmaProcess::sigmaPDF() {
+
+ // Evaluate and store the required parton densities.
+ for (int j = 0; j < sizeBeamA(); ++j)
+ inBeamA[j].pdf = beamAPtr->xfHard( inBeamA[j].id, x1Save, Q2FacSave);
+ for (int j = 0; j < sizeBeamB(); ++j)
+ inBeamB[j].pdf = beamBPtr->xfHard( inBeamB[j].id, x2Save, Q2FacSave);
+
+ // Loop over allowed incoming channels.
+ sigmaSumSave = 0.;
+ for (int i = 0; i < sizePair(); ++i) {
+
+ // Evaluate hard-scattering cross section. Include K factor.
+ inPair[i].pdfSigma = Kfactor
+ * sigmaHatWrap(inPair[i].idA, inPair[i].idB);
+
+ // Multiply by respective parton densities.
+ for (int j = 0; j < sizeBeamA(); ++j)
+ if (inPair[i].idA == inBeamA[j].id) {
+ inPair[i].pdfA = inBeamA[j].pdf;
+ inPair[i].pdfSigma *= inBeamA[j].pdf;
+ break;
+ }
+ for (int j = 0; j < sizeBeamB(); ++j)
+ if (inPair[i].idB == inBeamB[j].id) {
+ inPair[i].pdfB = inBeamB[j].pdf;
+ inPair[i].pdfSigma *= inBeamB[j].pdf;
+ break;
+ }
+
+ // Sum for all channels.
+ sigmaSumSave += inPair[i].pdfSigma;
+ }
+
+ // Done.
+ return sigmaSumSave;
+
+}
+
+//*********
+
+// Select incoming parton channel and extract parton densities (resolved).
+
+void SigmaProcess::pickInState(int id1in, int id2in) {
+
+ // Multiple interactions: partons already selected.
+ if (id1in != 0 && id2in != 0) {
+ id1 = id1in;
+ id2 = id2in;
+ }
+
+ // Pick channel. Extract channel flavours and pdf's.
+ double sigmaRand = sigmaSumSave * Rndm::flat();
+ for (int i = 0; i < sizePair(); ++i) {
+ sigmaRand -= inPair[i].pdfSigma;
+ if (sigmaRand <= 0.) {
+ id1 = inPair[i].idA;
+ id2 = inPair[i].idB;
+ pdf1Save = inPair[i].pdfA;
+ pdf2Save = inPair[i].pdfB;
+ break;
+ }
+ }
+
+}
+
+//*********
+
+// Evaluate weight for W decay distribution in t -> W b -> f fbar b.
+
+double SigmaProcess::weightTopDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // If not pair W d/s/b and mother t then return unit weight.
+ if (iResEnd - iResBeg != 1) return 1.;
+ int iW1 = iResBeg;
+ int iB2 = iResBeg + 1;
+ int idW1 = process[iW1].idAbs();
+ int idB2 = process[iB2].idAbs();
+ if (idW1 != 24) {
+ swap(iW1, iB2);
+ swap(idW1, idB2);
+ }
+ if (idW1 != 24 || (idB2 != 1 && idB2 != 3 && idB2 != 5)) return 1.;
+ int iT = process[iW1].mother1();
+ if (iT <= 0 || process[iT].idAbs() != 6) return 1.;
+
+ // Find sign-matched order of W decay products.
+ int iF = process[iW1].daughter1();
+ int iFbar = process[iW1].daughter2();
+ if (iFbar - iF != 1) return 1.;
+ if (process[iT].id() * process[iF].id() < 0) swap(iF, iFbar);
+
+ // Weight and maximum weight.
+ double wt = (process[iT].p() * process[iFbar].p())
+ * (process[iF].p() * process[iB2].p());
+ double wtMax = ( pow4(process[iT].m()) - pow4(process[iW1].m()) ) / 8.;
+
+ // Done.
+ return wt / wtMax;
+
+}
+
+
+//*********
+
+// Evaluate weight for Z0/W+- decay distributions in H -> Z0/W+ Z0/W- -> 4f.
+
+double SigmaProcess::weightHiggsDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // If not pair Z0 Z0 or W+ W- then return unit weight.
+ if (iResEnd - iResBeg != 1) return 1.;
+ int iZW1 = iResBeg;
+ int iZW2 = iResBeg + 1;
+ int idZW1 = process[iZW1].id();
+ int idZW2 = process[iZW2].id();
+ if (idZW1 < 0) {
+ swap(iZW1, iZW2);
+ swap(idZW1, idZW2);
+ }
+ if ( (idZW1 != 23 || idZW2 != 23) && (idZW1 != 24 || idZW2 != -24) )
+ return 1.;
+
+ // If mother is not Higgs then return unit weight.
+ int iH = process[iZW1].mother1();
+ if (iH <= 0) return 1.;
+ int idH = process[iH].id();
+ if (idH != 25 && idH != 35 && idH !=36) return 1.;
+
+ // Parameters depend on Higgs type: H0(H_1), H^0(H_2) or A^0(H_3).
+ int higgsParity = higgsH1parity;
+ double higgsEta = higgsH1eta;
+ if (idH == 35) {
+ higgsParity = higgsH2parity;
+ higgsEta = higgsH2eta;
+ } else if (idH == 36) {
+ higgsParity = higgsA3parity;
+ higgsEta = higgsA3eta;
+ }
+
+ // Option with isotropic decays.
+ if (higgsParity == 0) return 1.;
+
+ // Maximum and initial weight.
+ double wtMax = pow4(process[iH].m());
+ double wt = wtMax;
+
+ // Find sign-matched order of Z0/W+- decay products.
+ int i3 = process[iZW1].daughter1();
+ int i4 = process[iZW1].daughter2();
+ if (process[i3].id() < 0) swap( i3, i4);
+ int i5 = process[iZW2].daughter1();
+ int i6 = process[iZW2].daughter2();
+ if (process[i5].id() < 0) swap( i5, i6);
+
+ // Evaluate four-vector products and find masses..
+ double p35 = 2. * process[i3].p() * process[i5].p();
+ double p36 = 2. * process[i3].p() * process[i6].p();
+ double p45 = 2. * process[i4].p() * process[i5].p();
+ double p46 = 2. * process[i4].p() * process[i6].p();
+ double p34 = 2. * process[i3].p() * process[i4].p();
+ double p56 = 2. * process[i5].p() * process[i6].p();
+ double mZW1 = process[iZW1].m();
+ double mZW2 = process[iZW2].m();
+
+ // For mixed CP states need epsilon product and gauge boson masses.
+ double epsilonProd = 0.;
+ if (higgsParity == 3) {
+ double p[4][4];
+ for (int i = 0; i < 4; ++i) {
+ int ii = i3;
+ if (i == 1) ii = i4;
+ if (i == 2) ii = i5;
+ if (i == 3) ii = i6;
+ p[i][0] = process[ii].e();
+ p[i][1] = process[ii].px();
+ p[i][2] = process[ii].py();
+ p[i][3] = process[ii].pz();
+ }
+ epsilonProd
+ = p[0][0]*p[1][1]*p[2][2]*p[3][3] - p[0][0]*p[1][1]*p[2][3]*p[3][2]
+ - p[0][0]*p[1][2]*p[2][1]*p[3][3] + p[0][0]*p[1][2]*p[2][3]*p[3][1]
+ + p[0][0]*p[1][3]*p[2][1]*p[3][2] - p[0][0]*p[1][3]*p[2][2]*p[3][1]
+ - p[0][1]*p[1][0]*p[2][2]*p[3][3] + p[0][1]*p[1][0]*p[2][3]*p[3][2]
+ + p[0][1]*p[1][2]*p[2][0]*p[3][3] - p[0][1]*p[1][2]*p[2][3]*p[3][0]
+ - p[0][1]*p[1][3]*p[2][0]*p[3][2] + p[0][1]*p[1][3]*p[2][2]*p[3][0]
+ + p[0][2]*p[1][0]*p[2][1]*p[3][3] - p[0][2]*p[1][0]*p[2][3]*p[3][1]
+ - p[0][2]*p[1][1]*p[2][0]*p[3][3] + p[0][2]*p[1][1]*p[2][3]*p[3][0]
+ + p[0][2]*p[1][3]*p[2][0]*p[3][1] - p[0][2]*p[1][3]*p[2][1]*p[3][0]
+ - p[0][3]*p[1][0]*p[2][1]*p[3][2] + p[0][3]*p[1][0]*p[2][2]*p[3][1]
+ + p[0][3]*p[1][1]*p[2][0]*p[3][2] - p[0][3]*p[1][1]*p[2][2]*p[3][0]
+ - p[0][3]*p[1][2]*p[2][0]*p[3][1] + p[0][3]*p[1][2]*p[2][1]*p[3][0];
+ }
+
+ // Z0 Z0 decay: vector and axial couplings of two fermion pairs.
+ if (idZW1 == 23) {
+ double vf1 = CoupEW::vf(process[i3].idAbs());
+ double af1 = CoupEW::af(process[i3].idAbs());
+ double vf2 = CoupEW::vf(process[i5].idAbs());
+ double af2 = CoupEW::af(process[i5].idAbs());
+ double va12asym = 4. * vf1 * af1 * vf2 * af2
+ / ( (vf1*vf1 + af1*af1) * (vf2*vf2 + af2*af2) );
+ double etaMod = higgsEta / pow2( ParticleDataTable::m0(23) );
+
+ // Normal CP-even decay.
+ if (higgsParity == 1) wt = 8. * (1. + va12asym) * p35 * p46
+ + 8. * (1. - va12asym) * p36 * p45;
+
+ // CP-odd decay (normal for A0(H_3)).
+ else if (higgsParity == 2) wt = ( pow2(p35 + p46)
+ + pow2(p36 + p45) - 2. * p34 * p56
+ - 2. * pow2(p35 * p46 - p36 * p45) / (p34 * p56)
+ + va12asym * (p35 + p36 - p45 - p46) * (p35 + p45 - p36 - p46) )
+ / (1. + va12asym);
+
+ // Mixed CP states.
+ else wt = 32. * ( 0.25 * ( (1. + va12asym) * p35 * p46
+ + (1. - va12asym) * p36 * p45 ) - 0.5 * etaMod * epsilonProd
+ * ( (1. + va12asym) * (p35 + p46) - (1. - va12asym) * (p36 + p45) )
+ + 0.0625 * etaMod * etaMod * (-2. * pow2(p34 * p56)
+ - 2. * pow2(p35 * p46 - p36 * p45)
+ + p34 * p56 * (pow2(p35 + p46) + pow2(p36 + p45))
+ + va12asym * p34 * p56 * (p35 + p36 - p45 - p46)
+ * (p35 + p45 - p36 - p46) ) ) / ( 1. + 2. * etaMod * mZW1 * mZW2
+ + 2. * pow2(etaMod * mZW1 * mZW2) * (1. + va12asym) );
+
+ // W+ W- decay.
+ } else if (idZW1 == 24) {
+ double etaMod = higgsEta / pow2( ParticleDataTable::m0(24) );
+
+ // Normal CP-even decay.
+ if (higgsParity == 1) wt = 16. * p35 * p46;
+
+ // CP-odd decay (normal for A0(H_3)).
+ else if (higgsParity == 2) wt = 0.5 * ( pow2(p35 + p46)
+ + pow2(p36 + p45) - 2. * p34 * p56
+ - 2. * pow2(p35 * p46 - p36 * p45) / (p34 * p56)
+ + (p35 + p36 - p45 - p46) * (p35 + p45 - p36 - p46) );
+
+ // Mixed CP states.
+ else wt = 32. * ( 0.25 * 2. * p35 * p46
+ - 0.5 * etaMod * epsilonProd * 2. * (p35 + p46)
+ + 0.0625 * etaMod * etaMod * (-2. * pow2(p34 * p56)
+ - 2. * pow2(p35 * p46 - p36 * p45)
+ + p34 * p56 * (pow2(p35 + p46) + pow2(p36 + p45))
+ + p34 * p56 * (p35 + p36 - p45 - p46) * (p35 + p45 - p36 - p46) ) )
+ / ( 1. * 2. * etaMod * mZW1 * mZW2 + 2. * pow2(etaMod * mZW1 * mZW2) );
+ }
+
+ // Done.
+ return wt / wtMax;
+
+}
+
+//**************************************************************************
+
+// The Sigma1Process class.
+// Base class for resolved 2 -> 1 cross sections; derived from SigmaProcess.
+
+//*********
+
+// Input and complement kinematics for resolved 2 -> 1 process.
+
+void Sigma1Process::store1Kin( double x1in, double x2in, double sHin) {
+
+ // Default value only sensible for these processes.
+ swapTU = false;
+
+ // Incoming parton momentum fractions and sHat.
+ x1Save = x1in;
+ x2Save = x2in;
+ sH = sHin;
+ mH = sqrt(sH);
+ sH2 = sH * sH;
+
+ // Different options for renormalization scale, but normally sHat.
+ Q2RenSave = renormMultFac * sH;
+ if (renormScale1 == 2) Q2RenSave = renormFixScale;
+
+ // Different options for factorization scale, but normally sHat.
+ Q2FacSave = factorMultFac * sH;
+ if (factorScale1 == 2) Q2RenSave = factorFixScale;
+
+ // Evaluate alpha_strong and alpha_EM.
+ alpS = alphaSPtr->alphaS(Q2RenSave);
+ alpEM = alphaEMPtr->alphaEM(Q2RenSave);
+
+}
+
+//**************************************************************************
+
+// The Sigma2Process class.
+// Base class for resolved 2 -> 2 cross sections; derived from SigmaProcess.
+
+//*********
+
+// Input and complement kinematics for resolved 2 -> 2 process.
+
+void Sigma2Process::store2Kin( double x1in, double x2in, double sHin,
+ double tHin, double m3in, double m4in, double runBW3in, double runBW4in) {
+
+ // Default ordering of particles 3 and 4.
+ swapTU = false;
+
+ // Incoming parton momentum fractions.
+ x1Save = x1in;
+ x2Save = x2in;
+
+ // Incoming masses and their squares.
+ bool masslessKin = (id3Mass() == 0) && (id4Mass() == 0);
+ if (masslessKin) {
+ m3 = 0.;
+ m4 = 0.;
+ } else {
+ m3 = m3in;
+ m4 = m4in;
+ }
+ mSave[3] = m3;
+ mSave[4] = m4;
+ s3 = m3 * m3;
+ s4 = m4 * m4;
+
+ // Standard Mandelstam variables and their squares.
+ sH = sHin;
+ tH = tHin;
+ uH = (masslessKin) ? -(sH + tH) : s3 + s4 - (sH + tH);
+ mH = sqrt(sH);
+ sH2 = sH * sH;
+ tH2 = tH * tH;
+ uH2 = uH * uH;
+
+ // The nominal Breit-Wigner factors with running width.
+ runBW3 = runBW3in;
+ runBW4 = runBW4in;
+
+ // Calculate squared transverse momentum.
+ pT2 = (masslessKin) ? tH * uH / sH : (tH * uH - s3 * s4) / sH;
+
+ // Special case: pick scale as if 2 -> 1 process in disguise.
+ if (isSChannel()) {
+
+ // Different options for renormalization scale, but normally sHat.
+ Q2RenSave = renormMultFac * sH;
+ if (renormScale1 == 2) Q2RenSave = renormFixScale;
+
+ // Different options for factorization scale, but normally sHat.
+ Q2FacSave = factorMultFac * sH;
+ if (factorScale1 == 2) Q2RenSave = factorFixScale;
+
+ // Normal case with "true" 2 -> 2.
+ } else {
+
+ // Different options for renormalization scale.
+ if (masslessKin) Q2RenSave = (renormScale2 < 4) ? pT2 : sH;
+ else if (renormScale2 == 1) Q2RenSave = pT2 + min(s3, s4);
+ else if (renormScale2 == 2) Q2RenSave = sqrt((pT2 + s3) * (pT2 + s4));
+ else if (renormScale2 == 3) Q2RenSave = pT2 + 0.5 * (s3 + s4);
+ else Q2RenSave = sH;
+ Q2RenSave *= renormMultFac;
+ if (renormScale2 == 5) Q2RenSave = renormFixScale;
+
+ // Different options for factorization scale.
+ if (masslessKin) Q2FacSave = (factorScale2 < 4) ? pT2 : sH;
+ else if (factorScale2 == 1) Q2FacSave = pT2 + min(s3, s4);
+ else if (factorScale2 == 2) Q2FacSave = sqrt((pT2 + s3) * (pT2 + s4));
+ else if (factorScale2 == 3) Q2FacSave = pT2 + 0.5 * (s3 + s4);
+ else Q2FacSave = sH;
+ Q2FacSave *= factorMultFac;
+ if (factorScale2 == 5) Q2FacSave = factorFixScale;
+ }
+
+ // Evaluate alpha_strong and alpha_EM.
+ alpS = alphaSPtr->alphaS(Q2RenSave);
+ alpEM = alphaEMPtr->alphaEM(Q2RenSave);
+
+}
+
+//*********
+
+// As above, special kinematics for multiple interactions.
+
+void Sigma2Process::store2KinMI( double x1in, double x2in,
+ double sHin, double tHin, double uHin, double alpSin, double alpEMin,
+ bool needMasses, double m3in, double m4in) {
+
+ // Default ordering of particles 3 and 4.
+ swapTU = false;
+
+ // Incoming x values.
+ x1Save = x1in;
+ x2Save = x2in;
+
+ // Standard Mandelstam variables and their squares.
+ sH = sHin;
+ tH = tHin;
+ uH = uHin;
+ mH = sqrt(sH);
+ sH2 = sH * sH;
+ tH2 = tH * tH;
+ uH2 = uH * uH;
+
+ // Strong and electroweak couplings.
+ alpS = alpSin;
+ alpEM = alpEMin;
+
+ // Assume vanishing masses. (Will be modified in final kinematics.)
+ m3 = 0.;
+ s3 = 0.;
+ m4 = 0.;
+ s4 = 0.;
+ sHBeta = sH;
+
+ // Scattering angle.
+ cosTheta = (tH - uH) / sH;
+ sinTheta = 2. * sqrtpos( tH * uH ) / sH;
+
+ // In some cases must use masses and redefine meaning of tHat and uHat.
+ if (needMasses) {
+ m3 = m3in;
+ s3 = m3 * m3;
+ m4 = m4in;
+ s4 = m4 * m4;
+ sHMass = sH - s3 - s4;
+ sHBeta = sqrtpos(sHMass*sHMass - 4. * s3 * s4);
+ tH = -0.5 * (sHMass - sHBeta * cosTheta);
+ uH = -0.5 * (sHMass + sHBeta * cosTheta);
+ tH2 = tH * tH;
+ uH2 = uH * uH;
+ }
+
+ // pT2 with masses (at this stage) included.
+ pT2Mass = 0.25 * sHBeta * pow2(sinTheta);
+
+}
+
+//*********
+
+// Perform kinematics for a Multiple Interaction.
+
+bool Sigma2Process::final2KinMI() {
+
+ // Have to set flavours and colours.
+ setIdColAcol();
+
+ // Check that masses of outgoing particles not too big.
+ m3 = ParticleDataTable::m0(idSave[3]);
+ m4 = ParticleDataTable::m0(idSave[4]);
+ mH = sqrt(sH);
+ if (m3 + m4 + MASSMARGIN > mH) return false;
+ s3 = m3 * m3;
+ s4 = m4 * m4;
+
+ // Do kinematics of the decay.
+ double eIn = 0.5 * mH;
+ double e3 = 0.5 * (sH + s3 - s4) / mH;
+ double e4 = 0.5 * (sH + s4 - s3) / mH;
+ double pAbs = sqrtpos( e3*e3 - s3 );
+ phi = 2. * M_PI * Rndm::flat();
+ double pZ = pAbs * cosTheta;
+ double pX = pAbs * sinTheta * sin(phi);
+ double pY = pAbs * sinTheta * cos(phi);
+ double scale = eIn * sinTheta;
+
+ // Fill particle info.
+ parton[1] = Particle( idSave[1], -31, 0, 0, 3, 4, colSave[1], acolSave[1],
+ 0., 0., eIn, eIn, 0., scale);
+ parton[2] = Particle( idSave[2], -31, 0, 0, 3, 4, colSave[2], acolSave[2],
+ 0., 0., -eIn, eIn, 0., scale);
+ parton[3] = Particle( idSave[3], 33, 1, 2, 0, 0, colSave[3], acolSave[3],
+ pX, pY, pZ, e3, m3, scale);
+ parton[4] = Particle( idSave[4], 33, 1, 2, 0, 0, colSave[4], acolSave[4],
+ -pX, -pY, -pZ, e4, m4, scale);
+
+ // Boost particles from subprocess rest frame to event rest frame.
+ double betaZ = (x1Save - x2Save) / (x1Save + x2Save);
+ for (int i = 1; i <= 4; ++i) parton[i].bst(0., 0., betaZ);
+
+ // Done.
+ return true;
+
+}
+
+//**************************************************************************
+
+// The Sigma3Process class.
+// Base class for resolved 2 -> 3 cross sections; derived from SigmaProcess.
+
+//*********
+
+// Input and complement kinematics for resolved 2 -> 3 process.
+
+void Sigma3Process::store3Kin( double x1in, double x2in, double sHin,
+ Vec4 p3cmIn, Vec4 p4cmIn, Vec4 p5cmIn, double m3in, double m4in,
+ double m5in, double runBW3in, double runBW4in, double runBW5in) {
+
+ // Default ordering of particles 3 and 4 - not relevant here.
+ swapTU = false;
+
+ // Incoming parton momentum fractions.
+ x1Save = x1in;
+ x2Save = x2in;
+
+ // Incoming masses and their squares.
+ if (id3Mass() == 0 && id4Mass() == 0 && id5Mass() == 0) {
+ m3 = 0.;
+ m4 = 0.;
+ m5 = 0.;
+ } else {
+ m3 = m3in;
+ m4 = m4in;
+ m5 = m5in;
+ }
+ mSave[3] = m3;
+ mSave[4] = m4;
+ mSave[5] = m5;
+ s3 = m3 * m3;
+ s4 = m4 * m4;
+ s5 = m5 * m5;
+
+ // Standard Mandelstam variables and four-momenta in rest frame.
+ sH = sHin;
+ mH = sqrt(sH);
+ p3cm = p3cmIn;
+ p4cm = p4cmIn;
+ p5cm = p5cmIn;
+
+ // The nominal Breit-Wigner factors with running width.
+ runBW3 = runBW3in;
+ runBW4 = runBW4in;
+ runBW5 = runBW5in;
+
+ // Special case: pick scale as if 2 -> 1 process in disguise.
+ if (isSChannel()) {
+
+ // Different options for renormalization scale, but normally sHat.
+ Q2RenSave = renormMultFac * sH;
+ if (renormScale1 == 2) Q2RenSave = renormFixScale;
+
+ // Different options for factorization scale, but normally sHat.
+ Q2FacSave = factorMultFac * sH;
+ if (factorScale1 == 2) Q2RenSave = factorFixScale;
+
+ // "Normal" 2 -> 3 processes, i.e. not vector boson fusion.
+ } else if ( idTchan1() != 23 && idTchan1() != 24 && idTchan2() != 23
+ && idTchan1() != 24 ) {
+ double mT3S = s3 + p3cm.pT2();
+ double mT4S = s4 + p4cm.pT2();
+ double mT5S = s5 + p5cm.pT2();
+
+ // Different options for renormalization scale.
+ if (renormScale3 == 1) Q2RenSave = min( mT3S, min(mT4S, mT5S) );
+ else if (renormScale3 == 2) Q2RenSave = sqrt( mT3S * mT4S * mT5S
+ / max( mT3S, max(mT4S, mT5S) ) );
+ else if (renormScale3 == 3) Q2RenSave = pow( mT3S * mT4S * mT5S,
+ 1./3. );
+ else if (renormScale3 == 4) Q2RenSave = (mT3S * mT4S * mT5S) / 3.;
+ else Q2RenSave = sH;
+ Q2RenSave *= renormMultFac;
+ if (renormScale3 == 6) Q2RenSave = renormFixScale;
+
+ // Different options for factorization scale.
+ if (factorScale3 == 1) Q2FacSave = min( mT3S, min(mT4S, mT5S) );
+ else if (factorScale3 == 2) Q2FacSave = sqrt( mT3S * mT4S * mT5S
+ / max( mT3S, max(mT4S, mT5S) ) );
+ else if (factorScale3 == 3) Q2FacSave = pow( mT3S * mT4S * mT5S,
+ 1./3. );
+ else if (factorScale3 == 4) Q2FacSave = (mT3S * mT4S * mT5S) / 3.;
+ else Q2FacSave = sH;
+ Q2RenSave *= factorMultFac;
+ if (factorScale3 == 6) Q2FacSave = factorFixScale;
+
+ // Vector boson fusion 2 -> 3 processes; recoils in positions 4 and 5.
+ } else {
+ double sV4 = pow2( ParticleDataTable::m0(idTchan1()) );
+ double sV5 = pow2( ParticleDataTable::m0(idTchan2()) );
+ double mT3S = s3 + p3cm.pT2();
+ double mTV4S = sV4 + p4cm.pT2();
+ double mTV5S = sV5 + p5cm.pT2();
+
+ // Different options for renormalization scale.
+ if (renormScale3VV == 1) Q2RenSave = max( sV4, sV5);
+ else if (renormScale3VV == 2) Q2RenSave = sqrt( mTV4S * mTV5S );
+ else if (renormScale3VV == 3) Q2RenSave = pow( mT3S * mTV4S * mTV5S,
+ 1./3. );
+ else if (renormScale3VV == 4) Q2RenSave = (mT3S * mTV4S * mTV5S) / 3.;
+ else Q2RenSave = sH;
+ Q2RenSave *= renormMultFac;
+ if (renormScale3VV == 6) Q2RenSave = renormFixScale;
+
+ // Different options for factorization scale.
+ if (factorScale3VV == 1) Q2FacSave = max( sV4, sV5);
+ else if (factorScale3VV == 2) Q2FacSave = sqrt( mTV4S * mTV5S );
+ else if (factorScale3VV == 3) Q2FacSave = pow( mT3S * mTV4S * mTV5S,
+ 1./3. );
+ else if (factorScale3VV == 4) Q2FacSave = (mT3S * mTV4S * mTV5S) / 3.;
+ else Q2FacSave = sH;
+ Q2RenSave *= factorMultFac;
+ if (factorScale3VV == 6) Q2FacSave = factorFixScale;
+ }
+
+ // Evaluate alpha_strong and alpha_EM.
+ alpS = alphaSPtr->alphaS(Q2RenSave);
+ alpEM = alphaEMPtr->alphaEM(Q2RenSave);
+
+}
+
+//**************************************************************************
+
+// The SigmaLHAProcess class.
+// Wrapper for Les Houches Accord external input; derived from SigmaProcess.
+// Note: arbitrary subdivision into PhaseSpaceLHA and SigmaLHAProcess tasks.
+
+//*********
+
+// Obtain number of final-state partons from LHA object.
+
+int SigmaLHAProcess::nFinal() const {
+
+ // At initialization size unknown, so return 0.
+ if (lhaUpPtr->sizePart() <= 0) return 0;
+
+ // Sum up all particles that has first mother = 1.
+ int nFin = 0;
+ for (int i = 3; i < lhaUpPtr->sizePart(); ++i)
+ if (lhaUpPtr->mother1(i) == 1) ++nFin;
+ return nFin;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaQCD.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// QCD simulation classes.
+
+#include "SigmaQCD.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma0AB2AB class.
+// Cross section for elastic scattering A B -> A B.
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma0AB2AB::setIdColAcol() {
+
+ // Flavours and colours are trivial.
+ setId( idA, idB, idA, idB);
+ setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+}
+
+//**************************************************************************
+
+// Sigma0AB2XB class.
+// Cross section for single diffractive scattering A B -> X B.
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma0AB2XB::setIdColAcol() {
+
+ // Flavours and colours are trivial.
+ int idX = 10* (abs(idA) / 10) + 9900000;
+ if (idA < 0) idX = -idX;
+ setId( idA, idB, idX, idB);
+ setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+
+}
+
+//**************************************************************************
+
+// Sigma0AB2AX class.
+// Cross section for single diffractive scattering A B -> A X.
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma0AB2AX::setIdColAcol() {
+
+ // Flavours and colours are trivial.
+ int idX = 10* (abs(idB) / 10) + 9900000;
+ if (idB < 0) idX = -idX;
+ setId( idA, idB, idA, idX);
+ setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+
+}
+
+//**************************************************************************
+
+// Sigma0AB2XX class.
+// Cross section for double diffractive scattering A B -> X X.
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma0AB2XX::setIdColAcol() {
+
+ // Flavours and colours are trivial.
+ int idX1 = 10* (abs(idA) / 10) + 9900000;
+ if (idA < 0) idX1 = -idX1;
+ int idX2 = 10* (abs(idB) / 10) + 9900000;
+ if (idB < 0) idX2 = -idX2;
+ setId( idA, idB, idX1, idX2);
+ setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2gg class.
+// Cross section for g g -> g g.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
+
+void Sigma2gg2gg::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ sigTS = (9./4.) * (tH2 / sH2 + 2. * tH / sH + 3. + 2. * sH / tH
+ + sH2 / tH2);
+ sigUS = (9./4.) * (uH2 / sH2 + 2. * uH / sH + 3. + 2. * sH / uH
+ + sH2 / uH2);
+ sigTU = (9./4.) * (tH2 / uH2 + 2. * tH / uH + 3. + 2. * uH / tH
+ + uH2 / tH2);
+ sigSum = sigTS + sigUS + sigTU;
+
+ // Answer contains factor 1/2 from identical gluons.
+ sigma = (M_PI / sH2) * pow2(alpS) * 0.5 * sigSum;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2gg::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, 21, 21);
+
+ // Three colour flow topologies, each with two orientations.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 4, 4, 3);
+ else if (sigRand < sigTS + sigUS)
+ setColAcol( 1, 2, 3, 1, 3, 4, 4, 2);
+ else setColAcol( 1, 2, 3, 4, 1, 4, 3, 2);
+ if (Rndm::flat() > 0.5) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2qqbar class.
+// Cross section for g g -> q qbar (q = u, d, s, i.e. almost massless).
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2qqbar::initProc() {
+
+ // Read number of quarks to be considered in massless approximation.
+ nQuarkNew = Settings::mode("HardQCD:nQuarkNew");
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
+
+void Sigma2gg2qqbar::sigmaKin() {
+
+ // Pick new flavour.
+ idNew = 1 + int( nQuarkNew * Rndm::flat() );
+ mNew = ParticleDataTable::m0(idNew);
+ m2New = mNew*mNew;
+
+ // Calculate kinematics dependence.
+ sigTS = 0.;
+ sigUS = 0.;
+ if (sH > 4. * m2New) {
+ sigTS = (1./6.) * uH / tH - (3./8.) * uH2 / sH2;
+ sigUS = (1./6.) * tH / uH - (3./8.) * tH2 / sH2;
+ }
+ sigSum = sigTS + sigUS;
+
+ // Answer is proportional to number of outgoing flavours.
+ sigma = (M_PI / sH2) * pow2(alpS) * nQuarkNew * sigSum;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2qqbar::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, idNew, -idNew);
+
+ // Two colour flow topologies.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 0, 0, 3);
+ else setColAcol( 1, 2, 3, 1, 3, 0, 0, 2);
+
+}
+
+//**************************************************************************
+
+// Sigma2qg2qg class.
+// Cross section for q g -> q g.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
+
+void Sigma2qg2qg::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ sigTS = uH2 / tH2 - (4./9.) * uH / sH;
+ sigTU = sH2 / tH2 - (4./9.) * sH / uH;
+ sigSum = sigTS + sigTU;
+
+ // Answer.
+ sigma = (M_PI / sH2) * pow2(alpS) * sigSum;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qg2qg::setIdColAcol() {
+
+ // Outgoing = incoming flavours.
+ setId( id1, id2, id1, id2);
+
+ // Two colour flow topologies. Swap if first is gluon, or when antiquark.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 0, 2, 1, 3, 0, 2, 3);
+ else setColAcol( 1, 0, 2, 3, 2, 0, 1, 3);
+ if (id1 == 21) swapCol1234();
+ if (id1 < 0 || id2 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qq2qq class.
+// Cross section for q qbar' -> q qbar' or q q' -> q q'
+// (qbar qbar' -> qbar qbar'), q' may be same as q.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qq2qq::sigmaKin() {
+
+ // Calculate kinematics dependence for different terms.
+ sigT = (4./9.) * (sH2 + uH2) / tH2;
+ sigU = (4./9.) * (sH2 + tH2) / uH2;
+ sigTU = - (8./27.) * sH2 / (tH * uH);
+ sigST = - (8./27.) * uH2 / (sH * tH);
+
+}
+
+//*********
+
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+double Sigma2qq2qq::sigmaHat() {
+
+ // Combine cross section terms; factor 1/2 when identical quarks.
+ if (id2 == id1) sigSum = 0.5 * (sigT + sigU + sigTU);
+ else if (id2 == -id1) sigSum = sigT + sigST;
+ else sigSum = sigT;
+
+ // Answer.
+ return (M_PI/sH2) * pow2(alpS) * sigSum;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qq2qq::setIdColAcol() {
+
+ // Outgoing = incoming flavours.
+ setId( id1, id2, id1, id2);
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (id1 * id2 > 0) setColAcol( 1, 0, 2, 0, 2, 0, 1, 0);
+ else setColAcol( 1, 0, 0, 1, 2, 0, 0, 2);
+ if (id2 == id1 && (sigT + sigU) * Rndm::flat() > sigT)
+ setColAcol( 1, 0, 2, 0, 1, 0, 2, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2gg class.
+// Cross section for q qbar -> g g.
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
+
+void Sigma2qqbar2gg::sigmaKin() {
+
+ // Calculate kinematics dependence.
+ sigTS = (32./27.) * uH / tH - (8./3.) * uH2 / sH2;
+ sigUS = (32./27.) * tH / uH - (8./3.) * tH2 / sH2;
+ sigSum = sigTS + sigUS;
+
+ // Answer contains factor 1/2 from identical gluons.
+ sigma = (M_PI / sH2) * pow2(alpS) * 0.5 * sigSum;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2gg::setIdColAcol() {
+
+ // Outgoing flavours trivial.
+ setId( id1, id2, 21, 21);
+
+ // Two colour flow topologies. Swap if first is antiquark.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 0, 0, 2, 1, 3, 3, 2);
+ else setColAcol( 1, 0, 0, 2, 3, 2, 1, 3);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2qqbarNew class.
+// Cross section q qbar -> q' qbar'.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2qqbarNew::initProc() {
+
+ // Read number of quarks to be considered in massless approximation.
+ nQuarkNew = Settings::mode("HardQCD:nQuarkNew");
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
+
+void Sigma2qqbar2qqbarNew::sigmaKin() {
+
+ // Pick new flavour.
+ idNew = 1 + int( nQuarkNew * Rndm::flat() );
+ mNew = ParticleDataTable::m0(idNew);
+ m2New = mNew*mNew;
+
+ // Calculate kinematics dependence.
+ sigS = 0.;
+ if (sH > 4. * m2New) sigS = (4./9.) * (tH2 + uH2) / sH2;
+
+ // Answer is proportional to number of outgoing flavours.
+ sigma = (M_PI / sH2) * pow2(alpS) * nQuarkNew * sigS;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2qqbarNew::setIdColAcol() {
+
+ // Set outgoing flavours ones.
+ id3 = (id1 > 0) ? idNew : -idNew;
+ setId( id1, id2, id3, -id3);
+
+ // Colour flow topologies. Swap when antiquarks.
+ setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+// Sigma2gg2QQbar class.
+// Cross section g g -> Q Qbar (Q = c, b or t).
+// Only provided for fixed m3 = m4 so do some gymnastics:
+// i) s34Avg picked so that beta34 same when s3, s4 -> s34Avg.
+// ii) tHQ = tH - mQ^2 = -0.5 sH (1 - beta34 cos(thetaH)) for m3 = m4 = mQ,
+// but tH - uH = sH beta34 cos(thetaH) also for m3 != m4, so use
+// tH, uH selected for m3 != m4 to derive tHQ, uHQ valid for m3 = m4.
+
+//*********
+
+// Initialize process.
+
+void Sigma2gg2QQbar::initProc() {
+
+ // Process name.
+ nameSave = "g g -> Q Qbar";
+ if (idNew == 4) nameSave = "g g -> c cbar";
+ if (idNew == 5) nameSave = "g g -> b bbar";
+ if (idNew == 6) nameSave = "g g -> t tbar";
+ if (idNew == 7) nameSave = "g g -> b' b'bar";
+ if (idNew == 8) nameSave = "g g -> t' t'bar";
+
+ // Secondary open width fraction.
+ openFracPair = ParticleDataTable::resOpenFrac(idNew, -idNew);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
+
+void Sigma2gg2QQbar::sigmaKin() {
+
+ // Modified Mandelstam variables for massive kinematics with m3 = m4.
+ double s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH;
+ double tHQ = -0.5 * (sH - tH + uH);
+ double uHQ = -0.5 * (sH + tH - uH);
+ double tHQ2 = tHQ * tHQ;
+ double uHQ2 = uHQ * uHQ;
+
+ // Calculate kinematics dependence.
+ double tumHQ = tHQ * uHQ - s34Avg * sH;
+ sigTS = ( uHQ / tHQ - 2.25 * uHQ2 / sH2 + 4.5 * s34Avg * tumHQ
+ / ( sH * tHQ2) + 0.5 * s34Avg * (tHQ + s34Avg) / tHQ2
+ - s34Avg*s34Avg / (sH * tHQ) ) / 6.;
+ sigUS = ( tHQ / uHQ - 2.25 * tHQ2 / sH2 + 4.5 * s34Avg * tumHQ
+ / ( sH * uHQ2) + 0.5 * s34Avg * (uHQ + s34Avg) / uHQ2
+ - s34Avg*s34Avg / (sH * uHQ) ) / 6.;
+ sigSum = sigTS + sigUS;
+
+ // Answer.
+ sigma = (M_PI / sH2) * pow2(alpS) * sigSum * openFracPair;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2gg2QQbar::setIdColAcol() {
+
+ // Flavours are trivial.
+ setId( id1, id2, idNew, -idNew);
+
+ // Two colour flow topologies.
+ double sigRand = sigSum * Rndm::flat();
+ if (sigRand < sigTS) setColAcol( 1, 2, 2, 3, 1, 0, 0, 3);
+ else setColAcol( 1, 2, 3, 1, 3, 0, 0, 2);
+
+}
+
+//*********
+
+// Evaluate weight for decay angles of W in top decay.
+
+double Sigma2gg2QQbar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // For top decay hand over to standard routine, else done.
+ if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+ else return 1.;
+
+}
+
+//**************************************************************************
+
+// Sigma2qqbar2QQbar class.
+// Cross section q qbar -> Q Qbar (Q = c, b or t).
+// Only provided for fixed m3 = m4 so do some gymnastics:
+// i) s34Avg picked so that beta34 same when s3, s4 -> s34Avg.
+// ii) tHQ = tH - mQ^2 = -0.5 sH (1 - beta34 cos(thetaH)) for m3 = m4 = mQ,
+// but tH - uH = sH beta34 cos(thetaH) also for m3 != m4, so use
+// tH, uH selected for m3 != m4 to derive tHQ, uHQ valid for m3 = m4.
+
+//*********
+
+// Initialize process, especially parton-flux object.
+
+void Sigma2qqbar2QQbar::initProc() {
+
+ // Process name.
+ nameSave = "q qbar -> Q Qbar";
+ if (idNew == 4) nameSave = "q qbar -> c cbar";
+ if (idNew == 5) nameSave = "q qbar -> b bbar";
+ if (idNew == 6) nameSave = "q qbar -> t tbar";
+ if (idNew == 7) nameSave = "q qbar -> b' b'bar";
+ if (idNew == 8) nameSave = "q qbar -> t' t'bar";
+
+ // Secondary open width fraction.
+ openFracPair = ParticleDataTable::resOpenFrac(idNew, -idNew);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat) - no incoming flavour dependence.
+
+void Sigma2qqbar2QQbar::sigmaKin() {
+
+ // Modified Mandelstam variables for massive kinematics with m3 = m4.
+ double s34Avg = 0.5 * (s3 + s4) - 0.25 * pow2(s3 - s4) / sH;
+ double tHQ = -0.5 * (sH - tH + uH);
+ double uHQ = -0.5 * (sH + tH - uH);
+ double tHQ2 = tHQ * tHQ;
+ double uHQ2 = uHQ * uHQ;
+
+ // Calculate kinematics dependence.
+ double sigS = (4./9.) * ((tHQ2 + uHQ2) / sH2 + 2. * s34Avg / sH);
+
+ // Answer.
+ sigma = (M_PI / sH2) * pow2(alpS) * sigS * openFracPair;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2QQbar::setIdColAcol() {
+
+ // Set outgoing flavours.
+ id3 = (id1 > 0) ? idNew : -idNew;
+ setId( id1, id2, id3, -id3);
+
+ // Colour flow topologies. Swap when antiquarks.
+ setColAcol( 1, 0, 0, 2, 1, 0, 0, 2);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//*********
+
+// Evaluate weight for decay angles of W in top decay.
+
+double Sigma2qqbar2QQbar::weightDecay( Event& process, int iResBeg,
+ int iResEnd) {
+
+ // For top decay hand over to standard routine, else done.
+ if (idNew == 6 && process[process[iResBeg].mother1()].idAbs() == 6)
+ return weightTopDecay( process, iResBeg, iResEnd);
+ else return 1.;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SigmaSUSY.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// supersymmetry simulation classes.
+
+#include "SigmaSUSY.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// Sigma2qqbar2gauginogaugino "mother" class.
+// Cross section for gaugino pair production: neutralino pair,
+// neutralino-chargino, and chargino pair production all inherit from this.
+
+//*********
+
+// Initialize process.
+
+void Sigma2qqbar2gauginogaugino::initProc() {
+
+ // Construct name of process.
+ nameSave = "q qbar -> " + ParticleDataTable::name(id3) + " "
+ + ParticleDataTable::name(id4);
+
+ // Count number of final-state charged particles (default = 0)
+ // (useful since charginos inherit from this class.)
+ nCharged=0;
+ if (abs(id3) == 1000024 || abs(id3) == 1000037) nCharged++;
+ if (abs(id4) == 1000024 || abs(id4) == 1000037) nCharged++;
+
+ // Set up couplings
+ mZpole = ParticleDataTable::m0(23);
+ wZpole = ParticleDataTable::mWidth(23);
+ double mWpole = ParticleDataTable::m0(24);
+
+ // Running masses and weak mixing angle
+ // (default to pole values if no running available)
+ double mW = mWpole;
+ double mZ = mZpole;
+ sin2W = 1.0 - pow(mW/mZ,2);
+ if (slhaPtr->gauge.exists(1) && slhaPtr->gauge.exists(2)
+ && slhaPtr->hmix.exists(3)) {
+ double gp=slhaPtr->gauge(1);
+ double g =slhaPtr->gauge(2);
+ double v =slhaPtr->hmix(3);
+ mW = g * v / 2.0;
+ mZ = sqrt(pow(gp,2)+pow(g,2)) * v / 2.0;
+ sin2W = pow2(gp)/(pow2(g)+pow2(gp));
+ }
+
+ // Shorthand for SUSY couplings
+ // By default, use the running one in HMIX
+ // If not found, use the MZ one in MINPAR
+ double tanb = slhaPtr->hmix.exists(2) ?
+ slhaPtr->hmix(2) : slhaPtr->minpar(3);
+ double sinW=sqrt(sin2W);
+ double cosW=sqrt(1.0-sin2W);
+ double cosb = sqrt( 1.0 / (1.0 + tanb*tanb) );
+ double sinb = sqrt(max(0.0,1.0-cosb*cosb));
+ SusyLesHouches::matrixblock<6> Ru(slhaPtr->usqmix);
+ SusyLesHouches::matrixblock<6> Rd(slhaPtr->dsqmix);
+ SusyLesHouches::matrixblock<6> imRu(slhaPtr->imusqmix);
+ SusyLesHouches::matrixblock<6> imRd(slhaPtr->imusqmix);
+
+ // Local complex copies of neutralino mixing matrix entries.
+ // (incl NMSSM for future use)
+ complex ni1,nj1,ni2,nj2,ni3,nj3,ni4,nj4,ni5,nj5;
+ if (slhaPtr->modsel(3) != 1) {
+ ni1=complex( slhaPtr->nmix(id3chi,1), slhaPtr->imnmix(id3chi,1) );
+ nj1=complex( slhaPtr->nmix(id4chi,1), slhaPtr->imnmix(id4chi,1) );
+ ni2=complex( slhaPtr->nmix(id3chi,2), slhaPtr->imnmix(id3chi,2) );
+ nj2=complex( slhaPtr->nmix(id4chi,2), slhaPtr->imnmix(id4chi,2) );
+ ni3=complex( slhaPtr->nmix(id3chi,3), slhaPtr->imnmix(id3chi,3) );
+ nj3=complex( slhaPtr->nmix(id4chi,3), slhaPtr->imnmix(id4chi,3) );
+ ni4=complex( slhaPtr->nmix(id3chi,4), slhaPtr->imnmix(id3chi,4) );
+ nj4=complex( slhaPtr->nmix(id4chi,4), slhaPtr->imnmix(id4chi,4) );
+ ni5=complex( 0.,0.);
+ nj5=complex( 0.,0.);
+ } else {
+ ni1=complex( slhaPtr->nmnmix(id3chi,1), slhaPtr->imnmnmix(id3chi,1) );
+ nj1=complex( slhaPtr->nmnmix(id4chi,1), slhaPtr->imnmnmix(id4chi,1) );
+ ni2=complex( slhaPtr->nmnmix(id3chi,2), slhaPtr->imnmnmix(id3chi,2) );
+ nj2=complex( slhaPtr->nmnmix(id4chi,2), slhaPtr->imnmnmix(id4chi,2) );
+ ni3=complex( slhaPtr->nmnmix(id3chi,3), slhaPtr->imnmnmix(id3chi,3) );
+ nj3=complex( slhaPtr->nmnmix(id4chi,3), slhaPtr->imnmnmix(id4chi,3) );
+ ni4=complex( slhaPtr->nmnmix(id3chi,4), slhaPtr->imnmnmix(id3chi,4) );
+ nj4=complex( slhaPtr->nmnmix(id4chi,4), slhaPtr->imnmnmix(id4chi,4) );
+ ni5=complex( slhaPtr->nmnmix(id3chi,5), slhaPtr->imnmnmix(id3chi,5) );
+ nj5=complex( slhaPtr->nmnmix(id4chi,5), slhaPtr->imnmnmix(id4chi,5) );
+ }
+
+ // Change to positive mass convention.
+ complex iRot( 0., 1.);
+ if (slhaPtr->mass(abs(id3)) < 0.) {
+ ni1 *= iRot;
+ ni2 *= iRot;
+ ni3 *= iRot;
+ ni4 *= iRot;
+ ni5 *= iRot;
+ };
+ if (slhaPtr->mass(abs(id4)) < 0.) {
+ nj1 *= iRot;
+ nj2 *= iRot;
+ nj3 *= iRot;
+ nj4 *= iRot;
+ nj5 *= iRot;
+ };
+
+ // Local copies of Chargino mixing
+ complex ui1,ui2,vi1,vi2,uj1,uj2,vj1,vj2;
+ if (id3chi <= 2) {
+ ui1=complex( slhaPtr->umix(id3chi,1), slhaPtr->imumix(id3chi,1) );
+ ui2=complex( slhaPtr->umix(id3chi,2), slhaPtr->imumix(id3chi,2) );
+ vi1=complex( slhaPtr->vmix(id3chi,1), slhaPtr->imvmix(id3chi,1) );
+ vi2=complex( slhaPtr->vmix(id3chi,2), slhaPtr->imvmix(id3chi,2) );
+ }
+ if (id4chi <= 2) {
+ uj1=complex( slhaPtr->umix(id4chi,1), slhaPtr->imumix(id4chi,1) );
+ uj2=complex( slhaPtr->umix(id4chi,2), slhaPtr->imumix(id4chi,2) );
+ vj1=complex( slhaPtr->vmix(id4chi,1), slhaPtr->imvmix(id4chi,1) );
+ vj2=complex( slhaPtr->vmix(id4chi,2), slhaPtr->imvmix(id4chi,2) );
+ }
+
+ // Z chi_i chi_j
+ OLpp = -0.5 * ni3 * conj(nj3) + 0.5 * ni4 * conj(nj4);
+ ORpp = 0.5 * conj(ni3) * nj3 - 0.5 * conj(ni4) * nj4;
+
+ // Z cha_i cha_j
+ OLp = -vi1*conj(vj1) - 0.5*vi2*conj(vj2)
+ + ( (id3chi == id4chi) ? sin2W : 0.0);
+ ORp = -conj(ui1)*uj1 - 0.5*conj(ui2)*uj2
+ + ( (id3chi == id4chi) ? sin2W : 0.0);
+
+ // W chi_i cha_j
+ OL = -1.0/sqrt(2.0)*ni4*conj(vj2)+ni2*conj(vj1);
+ OR = 1.0/sqrt(2.0)*conj(ni3)*uj2+conj(ni2)*uj1;
+
+ // Z q_{idq} q_{idq} (def with extra factor 2 compared to [Okun])
+ for (int idq = 1; idq <= 5; ++idq) {
+ // No FCNC in Zqq, so here sum over diagonal only
+ // No t in beam, so only sum up to 5
+ LqqZ[idq] = CoupEW::lf(idq);
+ RqqZ[idq] = CoupEW::rf(idq);
+ }
+
+ // ~chi^0_i ~q_jsq idq
+ for (int jsq = 1; jsq<=6; jsq++) {
+ // Sum jsq over all squarks
+ for (int idq = 1; idq<=5; idq++) {
+ // No t in beam, so only sum iq over 5 lightest quarks.
+
+ // quark index
+ int k=(idq+1)/2;
+
+ // Set quark mass for use in couplings
+ // Initial guess 0,0,0,mc,mb, with the latter from the PDT
+ double mq = ParticleDataTable::m0(idq);
+ if (idq <= 3) mq=0.0;
+
+ // Treat u and d quarks separately
+ if (idq % 2 == 1) {
+
+ // idq = d quark
+ double eq = -1.0/3.0;
+ double T3q = -0.5;
+
+ // Compute running mass from Yukawas and vevs if possible.
+ if (slhaPtr->yd.exists() && slhaPtr->hmix.exists(3)) {
+ double ykk=slhaPtr->yd(k,k);
+ double v1=slhaPtr->hmix(3)/sqrt(1+pow(tanb,2));
+ if (ykk != 0.0) mq = ykk * v1 / sqrt(2.0) ;
+ // cout <<scientific<<" q "<<idq << " (k="<<k<<") Y = "
+ // <<ykk<<" v = "<<v1<<" m = "<<mq<<endl;
+ }
+
+ // Shorthand for squark mixing matrices
+ complex RdjkL(Rd(jsq,k),imRd(jsq,k));
+ complex RdjkR(Rd(jsq,k+3),imRd(jsq,k+3));
+
+ // L(~d_jsq,d_k,~chi^0_i)
+ LsqXi[jsq][idq]=((eq-T3q)*sinW*ni1+T3q*cosW*ni2) * conj(RdjkL)
+ + mq*cosW*ni3*conj(RdjkR)/2.0/mW/cosb ;
+
+ // L(~d_jsq,d_k,~chi^0_j)
+ LsqXj[jsq][idq]=((eq-T3q)*sinW*nj1+T3q*cosW*nj2) * conj(RdjkL)
+ + mq*cosW*nj3*conj(RdjkR)/2.0/mW/cosb ;
+
+ // R(~d_jsq,d_k,~chi^0_i)
+ RsqXi[jsq][idq]=eq*sinW*ni1*RdjkR - mq*cosW*ni3*RdjkL/2.0/mW/cosb ;
+ RsqXi[jsq][idq]=-conj(RsqXi[jsq][idq]) ;
+
+ // R(~d_jsq,d_k,~chi^0_j)
+ RsqXj[jsq][idq]=eq*sinW*nj1*RdjkR - mq*cosW*nj3*RdjkL/2.0/mW/cosb ;
+ RsqXj[jsq][idq]=-conj(RsqXj[jsq][idq]) ;
+
+ // Chargino couplings (initialize)
+ LsqCi[jsq][idq]=0.0;
+ RsqCi[jsq][idq]=0.0;
+ LsqCj[jsq][idq]=0.0;
+ RsqCj[jsq][idq]=0.0;
+
+ // Sum over flavours (off-diagonal mixings)
+ // (note l <-> k with respect to [Klasen et al])
+ for (int l=1; l<=3; l++) {
+
+ // Set quark masses for use in couplings
+ // Initial guess 0,0,0,mc,mb, with the latter from the PDT
+ double mu = ParticleDataTable::m0(2*l);
+ if (2*l <= 3) mu=0.0;
+
+ // Compute running u mass from Yukawas and vevs if possible.
+ if (slhaPtr->yu.exists() && slhaPtr->hmix.exists(3)) {
+ double yll=slhaPtr->yu(l,l);
+ double v2=slhaPtr->hmix(3)/sqrt(1.0+1.0/pow(tanb,2));
+ if (yll != 0.0) mu = yll * v2 / sqrt(2.0) ;
+ }
+
+ // Shorthand for u squark mixing
+ complex RujlL(Ru(jsq,l),imRu(jsq,l));
+ complex RujlR(Ru(jsq,l+3),imRu(jsq,l+3));
+
+ // CKM matrix (use Pythia-8 one if no SLHA)
+ complex Vlk=VCKM::Vid(l,k);
+ if (slhaPtr->vckm.exists())
+ Vlk=complex(slhaPtr->vckm(l,k),slhaPtr->imvckm(l,k));
+
+ // L(~u_jsq,d_k,~chi^+/-_i)
+ LsqCi[jsq][idq] += Vlk*(conj(vi1)*RujlL
+ -mu*conj(vi2)*RujlR/sqrt(2.0)/mW/sinb );
+
+ // L(~u_jsq,d_k,~chi^+/-_j)
+ LsqCj[jsq][idq] += Vlk*(conj(vj1)*RujlL
+ -mu*conj(vj2)*RujlR/sqrt(2.0)/mW/sinb );
+
+ // R(~u_jsq,d_k,~chi^+/-_i)
+ RsqCi[jsq][idq] += - Vlk*mq*ui2*RujlL/sqrt(2.0)/mW/cosb ;
+
+ // R(~u_jsq,d_k,~chi^+/-_j)
+ RsqCj[jsq][idq] += - Vlk*mq*uj2*RujlL/sqrt(2.0)/mW/cosb ;
+
+ }
+
+ } else {
+
+ // idq = u quark
+ double eq = 2.0/3.0;
+ double T3q = 0.5;
+
+ // Compute mass from Yukawas and vevs if possible.
+ if (slhaPtr->yu.exists() && slhaPtr->hmix.exists(3)) {
+ double ykk=slhaPtr->yu(k,k);
+ double v2=slhaPtr->hmix(3)/sqrt(1.0+1.0/pow(tanb,2));
+ if (ykk != 0.0) mq = ykk * v2 / sqrt(2.0) ;
+ // cout <<scientific<<" q "<<idq << " (k="<<k<<") Y = "
+ // <<ykk<<" v = "<<v2<<" m = "<<mq<<endl;
+ }
+
+ // Shorthand for squark mixing matrices
+ complex RujkL(Ru(jsq,k),imRu(jsq,k));
+ complex RujkR(Ru(jsq,k+3),imRu(jsq,k+3));
+
+ // L(~u_jsq,u_k,~chi^0_i)
+ LsqXi[jsq][idq]=((eq-T3q)*sinW*ni1+T3q*cosW*ni2) * conj(RujkL)
+ + mq*cosW*ni4*conj(RujkR)/2.0/mW/sinb ;
+
+ // L(~u_jsq,u_k,~chi^0_j)
+ LsqXj[jsq][idq]=((eq-T3q)*sinW*nj1+T3q*cosW*nj2) * conj(RujkL)
+ + mq*cosW*nj4*conj(RujkR)/2.0/mW/sinb ;
+
+ // R(~u_jsq,u_k,~chi^0_i)
+ RsqXi[jsq][idq]=eq*sinW*ni1*RujkR - mq*cosW*ni4*RujkL/2.0/mW/sinb ;
+ RsqXi[jsq][idq]=-conj(RsqXi[jsq][idq]);
+
+ // R(~u_jsq,u_k,~chi^0_i)
+ RsqXj[jsq][idq]=eq*sinW*nj1*RujkR - mq*cosW*nj4*RujkL/2.0/mW/sinb ;
+ RsqXj[jsq][idq]=-conj(RsqXj[jsq][idq]);
+
+ // Chargino couplings (initialize)
+ LsqCi[jsq][idq]=0.0;
+ RsqCi[jsq][idq]=0.0;
+ LsqCj[jsq][idq]=0.0;
+ RsqCj[jsq][idq]=0.0;
+
+ // Sum over flavours (off-diagonal mixings)
+ // (note l <-> k with respect to [Klasen et al])
+ for (int l=1; l<=3; l++) {
+
+ // Set quark masses for use in couplings
+ // Initial guess 0,0,0,mc,mb, with the latter from the PDT
+ double md = ParticleDataTable::m0(2*l-1);
+ if (2*l-1 <= 3) md=0.0;
+
+ // Compute running d mass from Yukawas and vevs if possible.
+ if (slhaPtr->yd.exists() && slhaPtr->hmix.exists(3)) {
+ double yll=slhaPtr->yd(l,l);
+ double v1=slhaPtr->hmix(3)/sqrt(1+pow(tanb,2));
+ if (yll != 0.0) md = yll * v1 / sqrt(2.0) ;
+ }
+
+ // Shorthand for d squark mixing
+ complex RdjlL(Rd(jsq,l),imRd(jsq,l));
+ complex RdjlR(Rd(jsq,l+3),imRd(jsq,l+3));
+
+ // CKM matrix (use Pythia-8 one if no SLHA)
+ complex Vkl=VCKM::Vid(k,l);
+ if (slhaPtr->vckm.exists())
+ Vkl=complex(slhaPtr->vckm(k,l),slhaPtr->imvckm(k,l));
+
+ // L(~d_jsq,u_k,~chi^+/-_i)
+ LsqCi[jsq][idq] += Vkl*(ui1*conj(RdjlL)
+ -md*ui2*conj(RdjlR)/sqrt(2.0)/mW/cosb) ;
+
+ // L(~d_jsq,u_k,~chi^+/-_j)
+ LsqCj[jsq][idq] += Vkl*(uj1*conj(RdjlL)
+ -md*uj2*conj(RdjlR)/sqrt(2.0)/mW/cosb) ;
+
+ // R(~d_jsq,u_k,~chi^+/-_i)
+ RsqCi[jsq][idq] += - Vkl*mq*conj(vi2*RdjlL)/sqrt(2.0)/mW/sinb ;
+
+ // R(~d_jsq,u_k,~chi^+/-_j)
+ RsqCj[jsq][idq] += - Vkl*mq*conj(vi2*RdjlL)/sqrt(2.0)/mW/sinb ;
+
+ }
+
+ }
+ }
+ }
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), part independent of incoming flavour.
+
+void Sigma2qqbar2gauginogaugino::sigmaKin() {
+
+ // Common flavour-independent factor.
+ sigma0 = (M_PI / sH2) * pow2(alpEM) ;
+
+ // Factor 1/2 for identical final particles.
+ if (id3 == id4 && nCharged == 0) sigma0 *= 0.5;
+
+ // Auxiliary factors for use below
+ ui = uH - s3;
+ uj = uH - s4;
+ ti = tH - s3;
+ tj = tH - s4;
+ sz = sH - pow2(mZpole);
+ d = pow2(sz) + pow2(mZpole * wZpole);
+ propZ = complex( sz / d, mZpole * wZpole / d);
+
+}
+
+//*********
+
+// Evaluate d(sigmaHat)/d(tHat), including incoming flavour dependence.
+
+// neutralino pairs:
+
+double Sigma2qqbar2gauginogaugino::sigmaHat() {
+
+ // Only allow quark-antiquark incoming states
+ if (id1*id2 >= 0) {
+ return 0.0;
+ }
+
+ // Only allow incoming states with sum(charge) = 0
+ if ((id1+id2) % 2 != 0) {
+ return 0.0;
+ }
+
+ // Flavour-dependent kinematics-dependent couplings.
+ int idAbs1 = abs(id1);
+ int idAbs2 = abs(id2);
+ complex QuLL = (id1 == -id2) ? LqqZ[idAbs1] * OLpp/2.0 * propZ : 0.0;
+ complex QtLL = (id1 == -id2) ? LqqZ[idAbs1] * ORpp/2.0 * propZ : 0.0;
+ complex QuRR = (id1 == -id2) ? RqqZ[idAbs1] * ORpp/2.0 * propZ : 0.0;
+ complex QtRR = (id1 == -id2) ? RqqZ[idAbs1] * OLpp/2.0 * propZ : 0.0;
+ complex QuLR = 0.0;
+ complex QtLR = 0.0;
+ complex QuRL = 0.0;
+ complex QtRL = 0.0;
+
+ // Add t-channel squark flavour sums to QmXY couplings
+ for (int jsq=1; jsq<=6; jsq++) {
+ int idsq=((jsq+2)/3)*1000000 + 2*((jsq-1) % 3) + (idAbs1+1) % 2 + 1;
+ double msq2=pow(ParticleDataTable::m0(idsq),2);
+ double usq = uH - msq2;
+ double tsq = tH - msq2;
+ QuLL += LsqXi[jsq][idAbs2]*conj(LsqXj[jsq][idAbs1])/usq;
+ QtLL -= conj(LsqXi[jsq][idAbs1])*LsqXj[jsq][idAbs2]/tsq;
+ QuRR += RsqXi[jsq][idAbs2]*conj(RsqXj[jsq][idAbs1])/usq;
+ QtRR -= conj(RsqXi[jsq][idAbs1])*RsqXj[jsq][idAbs2]/tsq;
+ QuLR += RsqXi[jsq][idAbs2]*conj(LsqXj[jsq][idAbs1])/usq;
+ QtLR += conj(LsqXi[jsq][idAbs1])*RsqXj[jsq][idAbs2]/tsq;
+ QuRL += LsqXi[jsq][idAbs2]*conj(RsqXj[jsq][idAbs1])/usq;
+ QtRL += conj(RsqXi[jsq][idAbs1])*LsqXj[jsq][idAbs2]/tsq;
+ }
+
+ // Multiply by overall normalization
+ QuLL *= 1.0/(sin2W * (1 - sin2W));
+ QtLL *= 1.0/(sin2W * (1 - sin2W));
+ QuRR *= 1.0/(sin2W * (1 - sin2W));
+ QtRR *= 1.0/(sin2W * (1 - sin2W));
+ QuLR *= 1.0/(sin2W * (1 - sin2W));
+ QtLR *= 1.0/(sin2W * (1 - sin2W));
+ QuRL *= 1.0/(sin2W * (1 - sin2W));
+ QtRL *= 1.0/(sin2W * (1 - sin2W));
+
+ // Compute matrix element weight
+ double weight = 0;
+ // Average over separate helicity contributions
+ // LL (ha = -1, hb = +1) (divided by 4 for average)
+ weight += norm(QuLL) * ui * uj + norm(QtLL) * ti * tj
+ + 2 * real(conj(QuLL) * QtLL) * m3 * m4 * sH;
+ // RR (ha = 1, hb = -1) (divided by 4 for average)
+ weight += norm(QtRR) * ti * tj + norm(QuRR) * ui * uj
+ + 2 * real(conj(QuRR) * QtRR) * m3 * m4 * sH;
+ // RL (ha = 1, hb = 1) (divided by 4 for average)
+ weight += norm(QuRL) * ui * uj + norm(QtRL) * ti * tj
+ - real(conj(QuRL) * QtRL) * (uH * tH - s3 * s4);
+ // LR (ha = -1, hb = -1) (divided by 4 for average)
+ weight += norm(QuLR) * ui * uj + norm(QtLR) * ti * tj
+ - real(conj(QuLR) * QtLR) * (uH * tH - s3 * s4);
+
+ // Cross section, including colour factor.
+ double sigma = sigma0 * weight;
+ if (idAbs1 < 9) sigma /= 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+// neutralino-chargino
+
+double Sigma2qqbar2chi0char::sigmaHat() {
+
+ // This cross section not fully debugged yet, skip.
+ return 0.0;
+
+ // Only allow quark-antiquark incoming states
+ if (id1*id2 >= 0) {
+ return 0.0;
+ }
+
+ // Only allow incoming states with sum(charge) = +/- 1
+ if ((id1+id2) % 2 == 0) {
+ return 0.0;
+ }
+
+ // Flavour-dependent kinematics-dependent couplings.
+ int idAbs1 = abs(id1);
+ int idAbs2 = abs(id2);
+ complex QuLL = (id1 == -id2) ? LqqZ[idAbs1] * OLpp/2.0 * propZ : 0.0;
+ complex QtLL = (id1 == -id2) ? LqqZ[idAbs1] * ORpp/2.0 * propZ : 0.0;
+ complex QuRR = (id1 == -id2) ? RqqZ[idAbs1] * ORpp/2.0 * propZ : 0.0;
+ complex QtRR = (id1 == -id2) ? RqqZ[idAbs1] * OLpp/2.0 * propZ : 0.0;
+ complex QuLR = 0.0;
+ complex QtLR = 0.0;
+ complex QuRL = 0.0;
+ complex QtRL = 0.0;
+
+ // Add t-channel squark flavour sums to QmXY couplings
+ for (int jsq=1; jsq<=6; jsq++) {
+ int idsq=((jsq+2)/3)*1000000 + 2*((jsq-1) % 3) + (idAbs1+1) % 2 + 1;
+ double msq2=pow(ParticleDataTable::m0(idsq),2);
+ double usq = uH - msq2;
+ double tsq = tH - msq2;
+ QuLL += LsqXi[jsq][idAbs2]*conj(LsqXj[jsq][idAbs1])/usq;
+ QtLL -= conj(LsqXi[jsq][idAbs1])*LsqXj[jsq][idAbs2]/tsq;
+ QuRR += RsqXi[jsq][idAbs2]*conj(RsqXj[jsq][idAbs1])/usq;
+ QtRR -= conj(RsqXi[jsq][idAbs1])*RsqXj[jsq][idAbs2]/tsq;
+ QuLR += RsqXi[jsq][idAbs2]*conj(LsqXj[jsq][idAbs1])/usq;
+ QtLR += conj(LsqXi[jsq][idAbs1])*RsqXj[jsq][idAbs2]/tsq;
+ QuRL += LsqXi[jsq][idAbs2]*conj(RsqXj[jsq][idAbs1])/usq;
+ QtRL += conj(RsqXi[jsq][idAbs1])*LsqXj[jsq][idAbs2]/tsq;
+ }
+
+ // Compute matrix element weight
+ double weight = 0;
+ // Average over separate helicity contributions
+ // LL (ha = -1, hb = +1) (divided by 4 for average)
+ weight += norm(QuLL) * ui * uj + norm(QtLL) * ti * tj
+ + 2 * real(conj(QuLL) * QtLL) * m3 * m4 * sH;
+ // RR (ha = 1, hb = -1) (divided by 4 for average)
+ weight += norm(QtRR) * ti * tj + norm(QuRR) * ui * uj
+ + 2 * real(conj(QuRR) * QtRR) * m3 * m4 * sH;
+ // RL (ha = 1, hb = 1) (divided by 4 for average)
+ weight += norm(QuRL) * ui * uj + norm(QtRL) * ti * tj
+ - real(conj(QuRL) * QtRL) * (uH * tH - s3 * s4);
+ // LR (ha = -1, hb = -1) (divided by 4 for average)
+ weight += norm(QuLR) * ui * uj + norm(QtLR) * ti * tj
+ - real(conj(QuLR) * QtLR) * (uH * tH - s3 * s4);
+
+ // Cross section, including colour factor.
+ double sigma = sigma0 * weight;
+ if (idAbs1 < 9) sigma /= 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+// chargino-chargino
+
+double Sigma2qqbar2charchar::sigmaHat() {
+
+ // This cross section not fully debugged yet, skip.
+ return 0.0;
+
+ // Only allow quark-antiquark incoming states
+ if (id1*id2 >= 0) {
+ return 0.0;
+ }
+
+ // Only allow incoming states with sum(charge) = 0
+ if ((id1+id2) % 2 != 0) {
+ return 0.0;
+ }
+
+ // Flavour-dependent kinematics-dependent couplings.
+ int idAbs1 = abs(id1);
+ int idAbs2 = abs(id2);
+
+ // Add s-channel Z
+ complex QuLL = (id1 == -id2) ? - LqqZ[idAbs1] * conj(OLp)/2.0 * propZ
+ / (sin2W * (1 - sin2W)) : 0.0;
+ complex QtLL = (id1 == -id2) ? - LqqZ[idAbs1] * conj(ORp)/2.0 * propZ
+ / (sin2W * (1 - sin2W)) : 0.0;
+ complex QuRR = (id1 == -id2) ? - RqqZ[idAbs1] * conj(ORp)/2.0 * propZ
+ / (sin2W * (1 - sin2W)) : 0.0;
+ complex QtRR = (id1 == -id2) ? - RqqZ[idAbs1] * conj(OLp)/2.0 * propZ
+ / (sin2W * (1 - sin2W)) : 0.0;
+ complex QuLR = 0.0;
+ complex QtLR = 0.0;
+ complex QuRL = 0.0;
+ complex QtRL = 0.0;
+
+ // Add s-channel photon
+ if (idAbs1 == idAbs2 && abs(id3) == abs(id4)) {
+ double e = -1.0/3.0;
+ if (idAbs1 % 2 == 0) e = 2.0/3.0;
+ if (idAbs1 > 10) e = -1.0;
+ QuLL += e/sH;
+ QtLL += e/sH;
+ QuRR += e/sH;
+ QtRR += e/sH;
+ }
+
+ // Add t-channel squark flavour sums to QmXY couplings
+ for (int jsq=1; jsq<=6; jsq++) {
+ int idsq=((jsq+2)/3)*1000000 + 2*((jsq-1) % 3) + (idAbs1 % 2) + 1;
+ double msq2=pow(ParticleDataTable::m0(idsq),2);
+ double usq = uH - msq2;
+ double tsq = tH - msq2;
+
+ // up-type quarks get u-channel d-squark contributions
+ if (idAbs1 % 2 == 0 ) {
+
+ // Flip 1<->2 and i<->j if id1 is antiquark
+ if (id1 > 0) {
+ QuLL += LsqCi[jsq][idAbs2]*conj(LsqCj[jsq][idAbs1])/usq/2.0/sin2W;
+ QuRR += RsqCi[jsq][idAbs2]*conj(RsqCj[jsq][idAbs1])/usq/2.0/sin2W;
+ QuLR += RsqCi[jsq][idAbs2]*conj(LsqCj[jsq][idAbs1])/usq/2.0/sin2W;
+ QuRL += LsqCi[jsq][idAbs2]*conj(RsqCj[jsq][idAbs1])/usq/2.0/sin2W;
+ } else {
+ QuLL += LsqCj[jsq][idAbs1]*conj(LsqCi[jsq][idAbs2])/usq/2.0/sin2W;
+ QuRR += RsqCj[jsq][idAbs1]*conj(RsqCi[jsq][idAbs2])/usq/2.0/sin2W;
+ QuLR += RsqCj[jsq][idAbs1]*conj(LsqCi[jsq][idAbs2])/usq/2.0/sin2W;
+ QuRL += LsqCj[jsq][idAbs1]*conj(RsqCi[jsq][idAbs2])/usq/2.0/sin2W;
+ }
+ }
+
+ // down-type quarks get t-channel u-squark contributions
+ else if (idAbs1 % 2 == 1) {
+ // Flip 1<->2 and i<->j if id1 is antiquark
+ if (id1 > 0) {
+ QtLL -= LsqCi[jsq][idAbs1]*conj(LsqCj[jsq][idAbs2])/tsq/2.0/sin2W;
+ QtRR -= RsqCi[jsq][idAbs1]*conj(RsqCj[jsq][idAbs2])/tsq/2.0/sin2W;
+ QtLR += LsqCi[jsq][idAbs1]*conj(RsqCj[jsq][idAbs2])/tsq/2.0/sin2W;
+ QtRL += RsqCi[jsq][idAbs1]*conj(LsqCj[jsq][idAbs2])/tsq/2.0/sin2W;
+ } else {
+ QtLL -= LsqCj[jsq][idAbs2]*conj(LsqCi[jsq][idAbs1])/tsq/2.0/sin2W;
+ QtRR -= RsqCj[jsq][idAbs2]*conj(RsqCi[jsq][idAbs1])/tsq/2.0/sin2W;
+ QtLR += LsqCj[jsq][idAbs2]*conj(RsqCi[jsq][idAbs1])/tsq/2.0/sin2W;
+ QtRL += RsqCj[jsq][idAbs2]*conj(LsqCi[jsq][idAbs1])/tsq/2.0/sin2W;
+ }
+
+ }
+ }
+
+ // Compute matrix element weight
+ double weight = 0;
+ // Average over separate helicity contributions
+ // LL (ha = -1, hb = +1) (divided by 4 for average)
+ weight += norm(QuLL) * ui * uj + norm(QtLL) * ti * tj
+ + 2 * real(conj(QuLL) * QtLL) * m3 * m4 * sH;
+ // RR (ha = 1, hb = -1) (divided by 4 for average)
+ weight += norm(QtRR) * ti * tj + norm(QuRR) * ui * uj
+ + 2 * real(conj(QuRR) * QtRR) * m3 * m4 * sH;
+ // RL (ha = 1, hb = 1) (divided by 4 for average)
+ weight += norm(QuRL) * ui * uj + norm(QtRL) * ti * tj
+ - real(conj(QuRL) * QtRL) * (uH * tH - s3 * s4);
+ // LR (ha = -1, hb = -1) (divided by 4 for average)
+ weight += norm(QuLR) * ui * uj + norm(QtLR) * ti * tj
+ - real(conj(QuLR) * QtLR) * (uH * tH - s3 * s4);
+
+ // Cross section, including colour factor.
+ double sigma = sigma0 * weight;
+ if (idAbs1 < 9) sigma /= 3.;
+
+ // Answer.
+ return sigma;
+
+}
+
+//*********
+
+// Select identity, colour and anticolour.
+
+void Sigma2qqbar2gauginogaugino::setIdColAcol() {
+
+ // Set flavours.
+
+ if (nCharged == 0) {
+ // Neutralino-Neutralino
+ setId( id1, id2, id3, id4);
+
+ } else if (nCharged == 1) {
+ // Neutralino-Chargino: set charge according to in-states
+ if ( abs(id1%1) == 1 && id1 > 0 ) {
+ setId( id1, id2, id3, -id4);
+ } else {
+ setId( id1, id2, id3, id4);
+ }
+
+ } else if (nCharged == 2) {
+ // Chargino-Chargino: charge already included in id3, id4
+ setId( id1, id2, id3, id4);
+ }
+
+ // Colour flow topologies. Swap when antiquarks.
+ if (abs(id1) < 9) setColAcol( 1, 0, 0, 1, 0, 0, 0, 0);
+ else setColAcol( 0, 0, 0, 0, 0, 0, 0, 0);
+ if (id1 < 0) swapColAcol();
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
+
--- /dev/null
+// SigmaTotal.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the SigmaTotal class.
+
+#include "SigmaTotal.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The SigmaTotal class.
+
+// Formulae are taken from:
+// G.A. Schuler and T. Sjostrand, Phys. Rev. D49 (1994) 2257,
+// Z. Phys. C73 (1997) 677
+// which borrows some total cross sections from
+// A. Donnachie and P.V. Landshoff, Phys. Lett. B296 (1992) 227.
+
+// Implemented processes with their process number iProc:
+// = 0 : p + p; = 1 : pbar + p;
+// = 2 : pi+ + p; = 3 : pi- + p; = 4 : pi0/rho0 + p;
+// = 5 : phi + p; = 6 : J/psi + p;
+// = 7 : rho + rho; = 8 : rho + phi; = 9 : rho + J/psi;
+// = 10 : phi + phi; = 11 : phi + J/psi; = 12 : J/psi + J/psi.
+
+//*********
+
+// Definitions of static variables.
+// Note that a lot of parameters are hardcoded as const here, rather
+// than being interfaced for public change, since any changes would
+// have to be done in a globally consistent manner. Which basically
+// means a rewrite/replacement of the whole class.
+
+// Minimum threshold below which no cross sections will be defined.
+const double SigmaTotal::MMIN = 2.;
+
+// General constants in total cross section parametrization:
+// sigmaTot = X * s^epsilon + Y * s^eta (pomeron + reggeon).
+const double SigmaTotal::EPSILON = 0.0808;
+const double SigmaTotal::ETA = -0.4525;
+const double SigmaTotal::X[] = { 21.70, 21.70, 13.63, 13.63, 13.63,
+ 10.01, 0.970, 8.56, 6.29, 0.609, 4.62, 0.447, 0.0434};
+const double SigmaTotal::Y[] = { 56.08, 98.39, 27.56, 36.02, 31.79,
+ 1.51, -0.146, 13.08, -0.62, -0.060, 0.030, -0.0028, 0.00028};
+
+// Type of the two incoming hadrons as function of the process number:
+// = 0 : p/n ; = 1 : pi/rho/omega; = 2 : phi; = 3 : J/psi.
+const int SigmaTotal::IHADATABLE[] = { 0, 0, 1, 1, 1, 2, 3, 1, 1,
+ 1, 2, 2, 3};
+const int SigmaTotal::IHADBTABLE[] = { 0, 0, 0, 0, 0, 0, 0, 1, 2,
+ 3, 2, 3, 3};
+
+// Hadron-Pomeron coupling beta(t) = beta(0) * exp(b*t).
+const double SigmaTotal::BETA0[] = { 4.658, 2.926, 2.149, 0.208};
+const double SigmaTotal::BHAD[] = { 2.3, 1.4, 1.4, 0.23};
+
+// Pomeron trajectory alpha(t) = 1 + epsilon + alpha' * t
+const double SigmaTotal::ALPHAPRIME = 0.25;
+
+// Conversion coefficients = 1/(16pi) * (mb <-> GeV^2) * (G_3P)^n,
+// with n = 0 elastic, n = 1 single and n = 2 double diffractive.
+const double SigmaTotal::CONVERTEL = 0.0510925;
+const double SigmaTotal::CONVERTSD = 0.0336;
+const double SigmaTotal::CONVERTDD = 0.0084;
+
+// Diffractive mass spectrum starts at m + MMIN0 and has a low-mass
+// enhancement, factor cRes, up to around m + mRes0.
+const double SigmaTotal::MMIN0 = 0.28;
+const double SigmaTotal::CRES = 2.0;
+const double SigmaTotal::MRES0 = 1.062;
+
+// Parameters and coefficients for single diffractive scattering.
+const int SigmaTotal::ISDTABLE[] = { 0, 0, 1, 1, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9};
+const double SigmaTotal::CSD[10][8] = {
+ { 0.213, 0.0, -0.47, 150., 0.213, 0.0, -0.47, 150., } ,
+ { 0.213, 0.0, -0.47, 150., 0.267, 0.0, -0.47, 100., } ,
+ { 0.213, 0.0, -0.47, 150., 0.232, 0.0, -0.47, 110., } ,
+ { 0.213, 7.0, -0.55, 800., 0.115, 0.0, -0.47, 110., } ,
+ { 0.267, 0.0, -0.46, 75., 0.267, 0.0, -0.46, 75., } ,
+ { 0.232, 0.0, -0.46, 85., 0.267, 0.0, -0.48, 100., } ,
+ { 0.115, 0.0, -0.50, 90., 0.267, 6.0, -0.56, 420., } ,
+ { 0.232, 0.0, -0.48, 110., 0.232, 0.0, -0.48, 110., } ,
+ { 0.115, 0.0, -0.52, 120., 0.232, 6.0, -0.56, 470., } ,
+ { 0.115, 5.5, -0.58, 570., 0.115, 5.5, -0.58, 570. } };
+
+// Parameters and coefficients for double diffractive scattering.
+const int SigmaTotal::IDDTABLE[] = { 0, 0, 1, 1, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9};
+const double SigmaTotal::CDD[10][9] = {
+ { 3.11, -7.34, 9.71, 0.068, -0.42, 1.31, -1.37, 35.0, 118., } ,
+ { 3.11, -7.10, 10.6, 0.073, -0.41, 1.17, -1.41, 31.6, 95., } ,
+ { 3.12, -7.43, 9.21, 0.067, -0.44, 1.41, -1.35, 36.5, 132., } ,
+ { 3.13, -8.18, -4.20, 0.056, -0.71, 3.12, -1.12, 55.2, 1298., } ,
+ { 3.11, -6.90, 11.4, 0.078, -0.40, 1.05, -1.40, 28.4, 78., } ,
+ { 3.11, -7.13, 10.0, 0.071, -0.41, 1.23, -1.34, 33.1, 105., } ,
+ { 3.12, -7.90, -1.49, 0.054, -0.64, 2.72, -1.13, 53.1, 995., } ,
+ { 3.11, -7.39, 8.22, 0.065, -0.44, 1.45, -1.36, 38.1, 148., } ,
+ { 3.18, -8.95, -3.37, 0.057, -0.76, 3.32, -1.12, 55.6, 1472., } ,
+ { 4.18, -29.2, 56.2, 0.074, -1.36, 6.67, -1.14, 116.2, 6532. } };
+const double SigmaTotal::SPROTON = 0.880;
+
+//*********
+
+// Store pointer to Info and initialize data members.
+
+void SigmaTotal::init(Info* infoPtrIn) {
+
+ // Store pointer.
+ infoPtr = infoPtrIn;
+
+ // User-set values for cross sections.
+ setTotal = Settings::flag("SigmaTotal:setOwn");
+ sigTotOwn = Settings::parm("SigmaTotal:sigmaTot");
+ sigElOwn = Settings::parm("SigmaTotal:sigmaEl");
+ sigXBOwn = Settings::parm("SigmaTotal:sigmaXB");
+ sigAXOwn = Settings::parm("SigmaTotal:sigmaAX");
+ sigXXOwn = Settings::parm("SigmaTotal:sigmaXX");
+
+ // User-set values for handling of elastic sacattering.
+ setElastic = Settings::flag("SigmaElastic:setOwn");
+ bSlope = Settings::parm("SigmaElastic:bSlope");
+ rho = Settings::parm("SigmaElastic:rho");
+ lambda = Settings::parm("SigmaElastic:lambda");
+ tAbsMin = Settings::parm("SigmaElastic:tAbsMin");
+ alphaEM0 = Settings::parm("StandardModel:alphaEM0");
+}
+
+//*********
+
+// Function that calculates the relevant properties.
+
+bool SigmaTotal::calc( int idA, int idB, double eCM) {
+
+ // Derived quantities.
+ alP2 = 2. * ALPHAPRIME;
+ s0 = 1. / ALPHAPRIME;
+
+ // Reset everything to zero to begin with.
+ isCalc = false;
+ sigTot = sigEl = sigXB = sigAX = sigXX = sigND = bEl = s = bA = bB = 0.;
+
+ // Order flavour of incoming hadrons: idAbsA < idAbsB (restore later).
+ int idAbsA = abs(idA);
+ int idAbsB = abs(idB);
+ bool swapped = false;
+ if (idAbsA > idAbsB) {
+ swap( idAbsA, idAbsB);
+ swapped = true;
+ }
+ double sameSign = (idA * idB > 0);
+
+ // Find process number.
+ int iProc = -1;
+ if (idAbsA > 1000) {
+ iProc = (sameSign) ? 0 : 1;
+ } else if (idAbsA > 100 && idAbsB > 1000) {
+ iProc = (sameSign) ? 2 : 3;
+ if (idAbsA/10 == 11 || idAbsA/10 == 22) iProc = 4;
+ if (idAbsA > 300) iProc = 5;
+ if (idAbsA > 400) iProc = 6;
+ } else if (idAbsA > 100) {
+ iProc = 7;
+ if (idAbsB > 300) iProc = 8;
+ if (idAbsB > 400) iProc = 9;
+ if (idAbsA > 300) iProc = 10;
+ if (idAbsA > 300 && idAbsB > 400) iProc = 11;
+ if (idAbsA > 400) iProc = 12;
+ }
+ if (iProc == -1) return false;
+
+ // Find hadron masses and check that energy is enough.
+ // For mesons use the corresponding vector meson masses.
+ int idModA = (idAbsA > 1000) ? idAbsA : 10 * (idAbsA/10) + 3;
+ int idModB = (idAbsB > 1000) ? idAbsB : 10 * (idAbsB/10) + 3;
+ double mA = ParticleDataTable::m0(idModA);
+ double mB = ParticleDataTable::m0(idModB);
+ if (eCM < mA + mB + MMIN) return false;
+
+ // Evaluate the total cross section.
+ s = eCM*eCM;
+ double sEps = pow( s, EPSILON);
+ double sEta = pow( s, ETA);
+ sigTot = X[iProc] * sEps + Y[iProc] * sEta;
+
+ // Slope of hadron form factors.
+ int iHadA = IHADATABLE[iProc];
+ int iHadB = IHADBTABLE[iProc];
+ bA = BHAD[iHadA];
+ bB = BHAD[iHadB];
+
+ // Elastic slope parameter and cross section.
+ bEl = 2.*bA + 2.*bB + 4.*sEps - 4.2;
+ sigEl = CONVERTEL * pow2(sigTot) / bEl;
+
+ // Lookup coefficients for single and double diffraction.
+ int iSD = ISDTABLE[iProc];
+ int iDD = IDDTABLE[iProc];
+ double sum1, sum2, sum3, sum4;
+
+ // Single diffractive scattering A + B -> X + B cross section.
+ mMinXBsave = mA + MMIN0;
+ double sMinXB = pow2(mMinXBsave);
+ mResXBsave = mA + MRES0;
+ double sResXB = pow2(mResXBsave);
+ double sRMavgXB = mResXBsave * mMinXBsave;
+ double sRMlogXB = log(1. + sResXB/sMinXB);
+ double sMaxXB = CSD[iSD][0] * s + CSD[iSD][1];
+ double BcorrXB = CSD[iSD][2] + CSD[iSD][3] / s;
+ sum1 = log( (2.*bB + alP2 * log(s/sMinXB))
+ / (2.*bB + alP2 * log(s/sMaxXB)) ) / alP2;
+ sum2 = CRES * sRMlogXB / (2.*bB + alP2 * log(s/sRMavgXB) + BcorrXB) ;
+ sigXB = CONVERTSD * X[iProc] * BETA0[iHadB] * max( 0., sum1 + sum2);
+
+ // Single diffractive scattering A + B -> A + X cross section.
+ mMinAXsave = mB + MMIN0;
+ double sMinAX = pow2(mMinAXsave);
+ mResAXsave = mB + MRES0;
+ double sResAX = pow2(mResAXsave);
+ double sRMavgAX = mResAXsave * mMinAXsave;
+ double sRMlogAX = log(1. + sResAX/sMinAX);
+ double sMaxAX = CSD[iSD][4] * s + CSD[iSD][5];
+ double BcorrAX = CSD[iSD][6] + CSD[iSD][7] / s;
+ sum1 = log( (2.*bA + alP2 * log(s/sMinAX))
+ / (2.*bA + alP2 * log(s/sMaxAX)) ) / alP2;
+ sum2 = CRES * sRMlogAX / (2.*bA + alP2 * log(s/sRMavgAX) + BcorrAX) ;
+ sigAX = CONVERTSD * X[iProc] * BETA0[iHadA] * max( 0., sum1 + sum2);
+
+ // Order single diffractive correctly.
+ if (swapped) {
+ swap( bB, bA);
+ swap( sigXB, sigAX);
+ swap( mMinXBsave, mMinAXsave);
+ swap( mResXBsave, mResAXsave);
+ }
+
+ // Double diffractive scattering A + B -> X1 + X2 cross section.
+ double y0min = log( s * SPROTON / (sMinXB * sMinAX) ) ;
+ double sLog = log(s);
+ double Delta0 = CDD[iDD][0] + CDD[iDD][1] / sLog
+ + CDD[iDD][2] / pow2(sLog);
+ sum1 = (y0min * (log( max( 1e-10, y0min/Delta0) ) - 1.) + Delta0)/ alP2;
+ if (y0min < 0.) sum1 = 0.;
+ double sMaxXX = s * ( CDD[iDD][3] + CDD[iDD][4] / sLog
+ + CDD[iDD][5] / pow2(sLog) );
+ double sLogUp = log( max( 1.1, s * s0 / (sMinXB * sRMavgAX) ));
+ double sLogDn = log( max( 1.1, s * s0 / (sMaxXX * sRMavgAX) ));
+ sum2 = CRES * log( sLogUp / sLogDn ) * sRMlogAX / alP2;
+ sLogUp = log( max( 1.1, s * s0 / (sMinAX * sRMavgXB) ));
+ sLogDn = log( max( 1.1, s * s0 / (sMaxXX * sRMavgXB) ));
+ sum3 = CRES * log(sLogUp / sLogDn) * sRMlogXB / alP2;
+ double BcorrXX = CDD[iDD][6] + CDD[iDD][7] / eCM + CDD[iDD][8] / s;
+ sum4 = pow2(CRES) * sRMlogAX * sRMlogXB
+ / max( 0.1, alP2 * log( s * s0 / (sRMavgAX * sRMavgXB) ) + BcorrXX);
+ sigXX = CONVERTDD * X[iProc] * max( 0., sum1 + sum2 + sum3 + sum4);
+
+ // Option with user-set values for total and partial cross sections.
+ // (Is not done earlier since want diffractive slopes anyway.)
+ double sigNDOwn = sigTotOwn - sigElOwn - sigXBOwn - sigAXOwn - sigXXOwn;
+ double sigElMax = sigEl;
+ if (setTotal && sigNDOwn > 0.) {
+ sigTot = sigTotOwn;
+ sigEl = sigElOwn;
+ sigXB = sigXBOwn;
+ sigAX = sigAXOwn;
+ sigXX = sigXXOwn;
+ sigElMax = sigEl;
+
+ // Sub-option to set elastic parameters, including Coulomb contribution.
+ if (setElastic) {
+ bEl = bSlope;
+ sigEl = CONVERTEL * pow2(sigTot) * (1. + rho*rho) / bSlope;
+ sigElMax = 2. * (sigEl * exp(-bSlope * tAbsMin)
+ + alphaEM0 * alphaEM0 / (4. * CONVERTEL * tAbsMin) );
+ }
+ }
+
+ // Inelastic nondiffractive by unitarity.
+ sigND = sigTot - sigEl - sigXB - sigAX - sigXX;
+ if (sigND < 0.) infoPtr->errorMsg("Error in SigmaTotal::init: "
+ "sigND < 0");
+ else if (sigND < 0.4 * sigTot) infoPtr->errorMsg("Warning in "
+ "SigmaTotal::init: sigND suspiciously low");
+
+ // Upper estimate of elastic, including Coulomb term, where appropriate.
+ sigEl = sigElMax;
+
+ // Done.
+ isCalc = true;
+ return true;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SpaceShower.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the
+// SpaceShower class.
+
+#include "SpaceShower.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The SpaceShower class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Leftover companion can give PDF > 0 at small Q2 where other PDF's = 0,
+// and then one can end in infinite loop of impossible kinematics.
+const int SpaceShower::MAXLOOPTINYPDF = 10;
+
+// Switch to alternative (but equivalent) backwards evolution for
+// g -> Q Qbar (Q = c or b) when below QTHRESHOLD * mQ2.
+const double SpaceShower::CTHRESHOLD = 2.0;
+const double SpaceShower::BTHRESHOLD = 2.0;
+
+// Renew evaluation of PDF's when the pT2 step is bigger than this
+// (in addition to initial scale and c and b thresholds.)
+const double SpaceShower::EVALPDFSTEP = 0.1;
+
+// Lower limit on PDF value in order to avoid division by zero.
+const double SpaceShower::TINYPDF = 1e-10;
+
+// Lower limit on estimated evolution rate, below which stop.
+const double SpaceShower::TINYKERNELPDF = 1e-6;
+
+// Lower limit on pT2, below which branching is rejected.
+const double SpaceShower::TINYPT2 = 0.25e-6;
+
+// No attempt to do backwards evolution of a heavy (c or b) quark
+// if evolution starts at a scale pT2 < HEAVYPT2EVOL * mQ2.
+const double SpaceShower::HEAVYPT2EVOL = 1.1;
+
+// No attempt to do backwards evolution of a heavy (c or b) quark
+// if evolution starts at a x > HEAVYXEVOL * x_max, where
+// x_max is the largest possible x value for a g -> Q Qbar branching.
+const double SpaceShower::HEAVYXEVOL = 0.9;
+
+// When backwards evolution Q -> g + Q creates a heavy quark Q,
+// an earlier branching g -> Q + Qbar will restrict kinematics
+// to M_{Q Qbar}^2 > EXTRASPACEQ * 4 m_Q^2. (Smarter to be found??)
+const double SpaceShower::EXTRASPACEQ = 2.0;
+
+// Never pick pT so low that alphaS is evaluated too close to Lambda_3.
+const double SpaceShower::LAMBDA3MARGIN = 1.1;
+
+// Cutoff for f_e^e at x < 1 - 10^{-10} to be used in z selection.
+// Note: the x_min quantity come from 1 - x_max.
+const double SpaceShower::LEPTONXMIN = 1e-10;
+const double SpaceShower::LEPTONXMAX = 1. - 1e-10;
+
+// Stop l -> l gamma evolution slightly above m2l.
+const double SpaceShower::LEPTONPT2MIN = 1.2;
+
+// Enhancement of l -> l gamma trial rate to compensate imperfect modelling.
+const double SpaceShower::LEPTONFUDGE = 10.;
+
+//*********
+
+// Initialize alphaStrong, alphaEM and related pTmin parameters.
+
+void SpaceShower::init( BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn) {
+
+ // Store input pointers for future use.
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+
+ // Main flags to switch on and off branchings.
+ doQCDshower = Settings::flag("SpaceShower:QCDshower");
+ doQEDshowerByQ = Settings::flag("SpaceShower:QEDshowerByQ");
+ doQEDshowerByL = Settings::flag("SpaceShower:QEDshowerByL");
+
+ // Matching in pT of hard interaction to shower evolution.
+ pTmaxMatch = Settings::mode("SpaceShower:pTmaxMatch");
+ pTdampMatch = Settings::mode("SpaceShower:pTdampMatch");
+ pTmaxFudge = Settings::parm("SpaceShower:pTmaxFudge");
+ pTdampFudge = Settings::parm("SpaceShower:pTdampFudge");
+
+ // Optionally force emissions to be ordered in rapidity/angle.
+ doRapidityOrder = Settings::flag("SpaceShower:rapidityOrder");
+
+ // Charm, bottom and lepton mass thresholds.
+ mc = ParticleDataTable::m0(4);
+ mb = ParticleDataTable::m0(5);
+ m2c = pow2(mc);
+ m2b = pow2(mb);
+
+ // Parameters of alphaStrong generation.
+ alphaSvalue = Settings::parm("SpaceShower:alphaSvalue");
+ alphaSorder = Settings::mode("SpaceShower:alphaSorder");
+ alphaS2pi = 0.5 * alphaSvalue / M_PI;
+
+ // Initialize alpha_strong generation.
+ alphaS.init( alphaSvalue, alphaSorder);
+
+ // Lambda for 5, 4 and 3 flavours.
+ Lambda5flav = alphaS.Lambda5();
+ Lambda4flav = alphaS.Lambda4();
+ Lambda3flav = alphaS.Lambda3();
+ Lambda5flav2 = pow2(Lambda5flav);
+ Lambda4flav2 = pow2(Lambda4flav);
+ Lambda3flav2 = pow2(Lambda3flav);
+
+ // Regularization of QCD evolution for pT -> 0. Can be taken
+ // same as for multiple interactions, or be set separately.
+ useSamePTasMI = Settings::flag("SpaceShower:samePTasMI");
+ if (useSamePTasMI) {
+ pT0Ref = Settings::parm("MultipleInteractions:pT0Ref");
+ ecmRef = Settings::parm("MultipleInteractions:ecmRef");
+ ecmPow = Settings::parm("MultipleInteractions:ecmPow");
+ pTmin = Settings::parm("MultipleInteractions:pTmin");
+ } else {
+ pT0Ref = Settings::parm("SpaceShower:pT0Ref");
+ ecmRef = Settings::parm("SpaceShower:ecmRef");
+ ecmPow = Settings::parm("SpaceShower:ecmPow");
+ pTmin = Settings::parm("SpaceShower:pTmin");
+ }
+
+ // Calculate nominal invariant mass of events. Set current pT0 scale.
+ sCM = m2( beamAPtr->p(), beamBPtr->p());
+ eCM = sqrt(sCM);
+ pT0 = pT0Ref * pow(eCM / ecmRef, ecmPow);
+
+ // Restrict pTmin to ensure that alpha_s(pTmin^2 + pT_0^2) does not blow up.
+ pTmin = max( pTmin, sqrtpos(pow2(LAMBDA3MARGIN) * Lambda3flav2 - pT0*pT0) );
+
+ // Parameters of alphaEM generation.
+ alphaEMorder = Settings::mode("SpaceShower:alphaEMorder");
+
+ // Initialize alphaEM generation.
+ alphaEM.init( alphaEMorder);
+
+ // Parameters of QED evolution.
+ pTminChgQ = Settings::parm("SpaceShower:pTminchgQ");
+ pTminChgL = Settings::parm("SpaceShower:pTminchgL");
+
+ // Derived parameters of QCD evolution.
+ pT20 = pow2(pT0);
+ pT2min = pow2(pTmin);
+ pT2minChgQ = pow2(pTminChgQ);
+ pT2minChgL = pow2(pTminChgL);
+
+ // Various other parameters.
+ doMEcorrections = Settings::flag("SpaceShower:MEcorrections");
+ doPhiPolAsym = Settings::flag("SpaceShower:phiPolAsym");
+ nQuarkIn = Settings::mode("SpaceShower:nQuarkIn");
+
+}
+
+//*********
+
+// Find whether to limit maximum scale of emissions.
+
+bool SpaceShower::limitPTmax( Event& event, double Q2Fac, double Q2Ren) {
+
+ // Find whether to limit pT. Begin by user-set cases.
+ bool dopTlimit = false;
+ if (pTmaxMatch == 1) dopTlimit = true;
+ else if (pTmaxMatch == 2) dopTlimit = false;
+
+ // Look if any quark (u, d, s, c, b), gluon or photon in final state.
+ else {
+ for (int i = 5; i < event.size(); ++i)
+ if (event[i].status() != -21) {
+ int idAbs = event[i].idAbs();
+ if (idAbs <= 5 || idAbs == 21 || idAbs == 22) dopTlimit = true;
+ }
+ }
+
+ // Dampening at factorization or renormalization scale.
+ dopTdamp = false;
+ pT2damp = 0.;
+ if ( !dopTlimit && (pTdampMatch == 1 || pTdampMatch == 2) ) {
+ dopTdamp = true;
+ pT2damp = pow2(pTdampFudge) * ((pTdampMatch == 1) ? Q2Fac : Q2Ren);
+ }
+
+ // Done.
+ return dopTlimit;
+
+}
+
+//*********
+
+// Prepare system for evolution; identify ME.
+// Routine may be called after multiple interactions, for a new subystem.
+
+void SpaceShower::prepare( int iSys, Event& event, bool limitPTmaxIn) {
+
+ // Find positions of incoming colliding partons.
+ int in1 = event.getInSystem( iSys, 0);
+ int in2 = event.getInSystem( iSys, 1);
+
+ // Reset dipole-ends list for first interaction.
+ if (iSys == 0) dipEnd.resize(0);
+
+ // Find matrix element corrections for system.
+ int MEtype = findMEtype( iSys, event);
+
+ // Maximum pT scale for dipole ends.
+ double pTmax1 = (limitPTmaxIn) ? event[in1].scale() : eCM;
+ double pTmax2 = (limitPTmaxIn) ? event[in2].scale() : eCM;
+ if (iSys == 0 && limitPTmaxIn) {
+ pTmax1 *= pTmaxFudge;
+ pTmax2 *= pTmaxFudge;
+ }
+
+ // Find dipole ends for QCD radiation.
+ if (doQCDshower) {
+ int colType1 = event[in1].colType();
+ dipEnd.push_back( SpaceDipoleEnd( iSys, 1, in1, in2, pTmax1,
+ colType1, 0, MEtype) );
+ int colType2 = event[in2].colType();
+ dipEnd.push_back( SpaceDipoleEnd( iSys, 2, in2, in1, pTmax2,
+ colType2, 0, MEtype) );
+ }
+
+ // Find dipole ends for QED radiation.
+ if (doQEDshowerByQ || doQEDshowerByL) {
+ int chgType1 = ( (event[in1].isQuark() && doQEDshowerByQ)
+ || (event[in1].isLepton() && doQEDshowerByL) )
+ ? event[in1].chargeType() : 0;
+ dipEnd.push_back( SpaceDipoleEnd( iSys, -1, in1, in2, pTmax1,
+ 0, chgType1, MEtype) );
+ int chgType2 = ( (event[in2].isQuark() && doQEDshowerByQ)
+ || (event[in2].isLepton() && doQEDshowerByL) )
+ ? event[in2].chargeType() : 0;
+ dipEnd.push_back( SpaceDipoleEnd( iSys, -2, in2, in1, pTmax2,
+ 0, chgType2, MEtype) );
+ }
+
+}
+
+//*********
+
+// Select next pT in downwards evolution of the existing dipoles.
+
+double SpaceShower::pTnext( Event& , double pTbegAll, double pTendAll,
+ int nRadIn) {
+
+ // Current cm energy, in case it varies between events.
+ sCM = m2( beamAPtr->p(), beamBPtr->p());
+
+ // Starting values: no radiating dipole found.
+ nRad = nRadIn;
+ double pT2sel = pow2(pTendAll);
+ iDipSel = 0;
+ iSysSel = 0;
+ dipEndSel = 0;
+
+ // Loop over all possible dipole ends.
+ for (int iDipEnd = 0; iDipEnd < int(dipEnd.size()); ++iDipEnd) {
+ iDipNow = iDipEnd;
+ dipEndNow = &dipEnd[iDipEnd];
+ iSysNow = dipEndNow->system;
+ dipEndNow->pT2 = 0.;
+
+ // Check whether dipole end should be allowed to shower.
+ double pT2begDip = pow2( min( pTbegAll, dipEndNow->pTmax ));
+ if (pT2begDip > pT2sel
+ && ( dipEndNow->colType != 0 || dipEndNow->chgType != 0 ) ) {
+ double pT2endDip = 0.;
+
+ // Determine lower cut for evolution, for QCD or QED (q or l).
+ if (dipEndNow->colType != 0) pT2endDip = max( pT2sel, pT2min );
+ else if (abs(dipEndNow->chgType) != 3) pT2endDip
+ = max( pT2sel, pT2minChgQ );
+ else pT2endDip = max( pT2sel, pT2minChgL );
+
+ // Find properties of dipole and radiating dipole end.
+ bool ordered = ( abs(dipEndNow->side) == 1 );
+ BeamParticle& beamNow = (ordered) ? *beamAPtr : *beamBPtr;
+ BeamParticle& beamRec = (ordered) ? *beamBPtr : *beamAPtr;
+ iNow = beamNow[iSysNow].iPos();
+ iRec = beamRec[iSysNow].iPos();
+ idDaughter = beamNow[iSysNow].id();
+ xDaughter = beamNow[iSysNow].x();
+ x1Now = (ordered) ? xDaughter : beamRec[iSysNow].x();
+ x2Now = (ordered) ? beamRec[iSysNow].x() : xDaughter;
+ m2Dip = x1Now * x2Now * sCM;
+
+ // Now do evolution in pT2, for QCD or QED
+ if (pT2begDip > pT2endDip) {
+ if (dipEndNow->colType != 0) pT2nextQCD( pT2begDip, pT2endDip);
+ else pT2nextQED( pT2begDip, pT2endDip);
+ }
+
+ // Update if found larger pT than current maximum.
+ if (dipEndNow->pT2 > pT2sel) {
+ pT2sel = dipEndNow->pT2;
+ iDipSel = iDipNow;
+ iSysSel = iSysNow;
+ dipEndSel = dipEndNow;
+ }
+
+ // End loop over dipole ends.
+ }
+ }
+
+ // Return nonvanishing value if found pT is bigger than already found.
+ return (dipEndSel == 0) ? 0. : sqrt(pT2sel);
+}
+
+//*********
+
+// Evolve a QCD dipole end.
+
+void SpaceShower::pT2nextQCD( double pT2begDip, double pT2endDip) {
+
+ // Some properties and kinematical starting values.
+ BeamParticle& beam = ( abs(dipEndNow->side) == 1 )
+ ? *beamAPtr : *beamBPtr;
+ bool isGluon = (idDaughter == 21);
+ bool isValence = beam[iSysNow].isValence();
+ int MEtype = dipEndNow->MEtype;
+ double pT2 = pT2begDip;
+ double xMaxAbs = beam.xMax(iSysNow);
+ double zMinAbs = xDaughter / xMaxAbs;
+
+ // Starting values for handling of massive quarks (c/b), if any.
+ double idMassive = 0;
+ if ( abs(idDaughter) == 4 ) idMassive = 4;
+ if ( abs(idDaughter) == 5 ) idMassive = 5;
+ bool isMassive = (idMassive > 0);
+ double m2Massive = 0.;
+ double mRatio = 0.;
+ double zMaxMassive = 1.;
+ double m2Threshold = pT2;
+
+ // Evolution below scale of massive quark or at large x is impossible.
+ if (isMassive) {
+ m2Massive = (idMassive == 4) ? m2c : m2b;
+ if (pT2 < HEAVYPT2EVOL * m2Massive) return;
+ mRatio = sqrt( m2Massive / m2Dip );
+ zMaxMassive = (1. - mRatio) / ( 1. + mRatio * (1. - mRatio) );
+ if (xDaughter > HEAVYXEVOL * zMaxMassive * xMaxAbs) return;
+
+ // Find threshold scale below which only g -> Q + Qbar will be allowed.
+ m2Threshold = (idMassive == 4) ? min( pT2, CTHRESHOLD * m2c)
+ : min( pT2, BTHRESHOLD * m2b);
+ }
+
+ // Variables used inside evolution loop. (Mainly dummy starting values.)
+ int nFlavour = 3;
+ double b0 = 4.5;
+ double Lambda2 = Lambda3flav2;
+ double pT2minNow = pT2endDip;
+ int idMother = 0;
+ int idSister = 0;
+ double z = 0.;
+ double zMaxAbs = 0.;
+ double zRootMax = 0.;
+ double zRootMin = 0.;
+ double g2gInt = 0.;
+ double q2gInt = 0.;
+ double q2qInt = 0.;
+ double g2qInt = 0.;
+ double g2Qenhance = 0.;
+ double xPDFdaughter = 0.;
+ double xPDFmother[21] = {0.};
+ double xPDFgMother = 0.;
+ double xPDFmotherSum = 0.;
+ double kernelPDF = 0.;
+ double xMother = 0.;
+ double wt = 0.;
+ double Q2 = 0.;
+ double mSister = 0.;
+ double m2Sister = 0.;
+ double pT2corr = 0.;
+ double phi = 0.;
+ double pT2PDF = pT2;
+ bool needNewPDF = true;
+
+ // Begin evolution loop towards smaller pT values.
+ int loopTinyPDFdau = 0;
+ bool hasTinyPDFdau = false;
+ do {
+ wt = 0.;
+
+ // Bad sign if repeated looping with small daughter PDF, so fail.
+ // (Example: if all PDF's = 0 below Q_0, except for c/b companion.)
+ if (hasTinyPDFdau) ++loopTinyPDFdau;
+ if (loopTinyPDFdau > MAXLOOPTINYPDF) {
+ infoPtr->errorMsg("Warning in SpaceShower::pT2nextQCD: "
+ "small daughter PDF");
+ return;
+ }
+
+ // Initialize integrals of splitting kernels and evaluate parton
+ // densities at the beginning. Reinitialize after long evolution
+ // in pT2 or when crossing c and b flavour thresholds.
+ if (needNewPDF || pT2 < EVALPDFSTEP * pT2PDF) {
+ pT2PDF = pT2;
+ hasTinyPDFdau = false;
+
+ // Determine overestimated z range; switch at c and b masses.
+ if (pT2 > m2b) {
+ nFlavour = 5;
+ pT2minNow = m2b;
+ b0 = 23./6.;
+ Lambda2 = Lambda5flav2;
+ } else if (pT2 > m2c) {
+ nFlavour = 4;
+ pT2minNow = m2c;
+ b0 = 25./6.;
+ Lambda2 = Lambda4flav2;
+ } else {
+ nFlavour = 3;
+ pT2minNow = pT2endDip;
+ b0 = 27./6.;
+ Lambda2 = Lambda3flav2;
+ }
+ zMaxAbs = 1. - 0.5 * (pT2minNow / m2Dip) *
+ ( sqrt( 1. + 4. * m2Dip / pT2minNow ) - 1. );
+ if (isMassive) zMaxAbs = min( zMaxAbs, zMaxMassive);
+
+ // Go to another z range with lower mass scale if current is closed.
+ if (zMinAbs > zMaxAbs) {
+ if (nFlavour == 3 || (idMassive == 4 && nFlavour == 4)
+ || idMassive == 5) return;
+ pT2 = (nFlavour == 4) ? m2c : m2b;
+ continue;
+ }
+
+ // Parton density of daughter at current scale.
+ xPDFdaughter = beam.xfISR(iSysNow, idDaughter, xDaughter, pT2);
+ if (xPDFdaughter < TINYPDF) {
+ xPDFdaughter = TINYPDF;
+ hasTinyPDFdau = true;
+ }
+
+ // Integrals of splitting kernels for gluons: g -> g, q -> g.
+ if (isGluon) {
+ g2gInt = 6. * log(zMaxAbs * (1.-zMinAbs)
+ / (zMinAbs * (1.-zMaxAbs)));
+ if (doMEcorrections) g2gInt *= calcMEmax(MEtype, 21, 21);
+ q2gInt = (16./3.) * (1./sqrt(zMinAbs) - 1./sqrt(zMaxAbs));
+ if (doMEcorrections) q2gInt *= calcMEmax(MEtype, 1, 21);
+
+ // Parton density of potential quark mothers to a g.
+ xPDFmotherSum = 0.;
+ for (int i = -nQuarkIn; i <= nQuarkIn; ++i) {
+ if (i == 0) {
+ xPDFmother[10] = 0.;
+ } else {
+ xPDFmother[i+10] = beam.xfISR(iSysNow, i, xDaughter, pT2);
+ xPDFmotherSum += xPDFmother[i+10];
+ }
+ }
+
+ // Total QCD evolution coefficient for a gluon.
+ kernelPDF = g2gInt + q2gInt * xPDFmotherSum / xPDFdaughter;
+
+ // For valence quark only need consider q -> q g branchings.
+ // Introduce an extra factor sqrt(z) to smooth bumps.
+ } else if (isValence) {
+ zRootMin = (1. + sqrt(zMinAbs)) / (1. - sqrt(zMinAbs));
+ zRootMax = (1. + sqrt(zMaxAbs)) / (1. - sqrt(zMaxAbs));
+ q2qInt = (8./3.) * log( zRootMax / zRootMin );
+ if (doMEcorrections) q2qInt *= calcMEmax(MEtype, 1, 1);
+ g2qInt = 0.;
+ kernelPDF = q2qInt;
+
+ // Integrals of splitting kernels for quarks: q -> q, g -> q.
+ } else {
+ q2qInt = (8./3.) * log( (1. - zMinAbs) / (1. - zMaxAbs) );
+ if (doMEcorrections) q2qInt *= calcMEmax(MEtype, 1, 1);
+ g2qInt = 0.5 * (zMaxAbs - zMinAbs);
+ if (doMEcorrections) g2qInt *= calcMEmax(MEtype, 21, 1);
+
+ // Increase estimated upper weight for g -> Q + Qbar.
+ if (isMassive) {
+ double m2log = log( m2Massive / Lambda2);
+ g2Qenhance = log( log(pT2/Lambda2) / m2log )
+ / log( log(m2Threshold/Lambda2) / m2log );
+ g2qInt *= g2Qenhance;
+ }
+
+ // Parton density of a potential gluon mother to a q.
+ xPDFgMother = beam.xfISR(iSysNow, 21, xDaughter, pT2);
+
+ // Total QCD evolution coefficient for a quark.
+ kernelPDF = q2qInt + g2qInt * xPDFgMother / xPDFdaughter;
+ }
+
+ // End evaluation of splitting kernels and parton densities.
+ needNewPDF = false;
+ }
+ if (kernelPDF < TINYKERNELPDF) return;
+
+ // Pick pT2 (in overestimated z range), for one of three different cases.
+ // Assume form alphas(pT0^2 + pT^2) * dpT^2/(pT0^2 + pT^2).
+ double Q2alphaS;
+
+ // Fixed alpha_strong.
+ if (alphaSorder == 0) {
+ pT2 = (pT2 + pT20) * pow( Rndm::flat(),
+ 1. / (alphaS2pi * kernelPDF)) - pT20;
+
+ // First-order alpha_strong.
+ } else if (alphaSorder == 1) {
+ pT2 = Lambda2 * pow( (pT2 + pT20) / Lambda2,
+ pow(Rndm::flat(), b0 / kernelPDF) ) - pT20;
+
+ // For second order reject by second term in alpha_strong expression.
+ } else {
+ do {
+ pT2 = Lambda2 * pow( (pT2 + pT20) / Lambda2,
+ pow(Rndm::flat(), b0 / kernelPDF) ) - pT20;
+ Q2alphaS = max(pT2 + pT20, pow2(LAMBDA3MARGIN) * Lambda3flav2);
+ } while (alphaS.alphaS2OrdCorr(Q2alphaS) < Rndm::flat()
+ && pT2 > pT2minNow);
+ }
+
+ // Check for pT2 values that prompt special action.
+
+ // If fallen into b threshold region, force g -> b + bbar.
+ if (idMassive == 5 && pT2 < m2Threshold) {
+ pT2nearQCDthreshold( beam, m2Massive, m2Threshold, zMinAbs,
+ zMaxMassive );
+ return;
+
+ // If crossed b threshold, continue evolution from this threshold.
+ } else if (nFlavour == 5 && pT2 < m2b) {
+ needNewPDF = true;
+ pT2 = m2b;
+ continue;
+
+ // If fallen into c threshold region, force g -> c + cbar.
+ } else if (idMassive == 4 && pT2 < m2Threshold) {
+ pT2nearQCDthreshold( beam, m2Massive, m2Threshold, zMinAbs,
+ zMaxMassive );
+ return;
+
+ // If crossed c threshold, continue evolution from this threshold.
+ } else if (nFlavour == 4 && pT2 < m2c) {
+ needNewPDF = true;
+ pT2 = m2c;
+ continue;
+
+ // Abort evolution if below cutoff scale, or below another branching.
+ } else if (pT2 < pT2endDip) return;
+
+ // Select z value of branching to g, and corrective weight.
+ if (isGluon) {
+ // g -> g (+ g).
+ if (Rndm::flat() * kernelPDF < g2gInt) {
+ idMother = 21;
+ idSister = 21;
+ z = 1. / ( 1. + ((1. - zMinAbs) / zMinAbs) * pow( (zMinAbs *
+ (1. - zMaxAbs)) / (zMaxAbs * (1. - zMinAbs)), Rndm::flat() ) );
+ wt = pow2( 1. - z * (1. - z));
+ } else {
+ // q -> g (+ q): also select flavour.
+ double temp = xPDFmotherSum * Rndm::flat();
+ idMother = -nQuarkIn - 1;
+ do { temp -= xPDFmother[(++idMother) + 10]; }
+ while (temp > 0. && idMother < nQuarkIn);
+ idSister = idMother;
+ z = (zMinAbs * zMaxAbs) / pow2( sqrt(zMinAbs) + Rndm::flat()
+ * ( sqrt(zMaxAbs)- sqrt(zMinAbs) ));
+ wt = 0.5 * (1. + pow2(1. - z)) * sqrt(z)
+ * xPDFdaughter / xPDFmother[idMother + 10];
+ }
+
+ // Select z value of branching to q, and corrective weight.
+ // Include massive kernel corrections for c and b quarks.
+ } else {
+ // q -> q (+ g).
+ if (isValence || Rndm::flat() * kernelPDF < q2qInt) {
+ idMother = idDaughter;
+ idSister = 21;
+ // Valence more peaked at large z.
+ if (isValence) {
+ double zTmp = zRootMin * pow(zRootMax / zRootMin, Rndm::flat() );
+ z = pow2( (1. - zTmp) / (1. + zTmp) );
+ } else {
+ z = 1. - (1. - zMinAbs) * pow( (1. - zMaxAbs) / (1. - zMinAbs),
+ Rndm::flat() );
+ }
+ if (!isMassive) {
+ wt = 0.5 * (1. + pow2(z));
+ } else {
+ wt = 0.5 * (1. + pow2(z) - z * pow2(1.-z) * m2Massive / pT2);
+ }
+ if (isValence) wt *= sqrt(z);
+ // g -> q (+ qbar).
+ } else {
+ idMother = 21;
+ idSister = - idDaughter;
+ z = zMinAbs + Rndm::flat() * (zMaxAbs - zMinAbs);
+ if (!isMassive) {
+ wt = (pow2(z) + pow2(1.-z)) * xPDFdaughter / xPDFgMother ;
+ } else {
+ wt = (pow2(z) + pow2(1.-z) + 2. * z * (1.-z) * m2Massive / pT2)
+ * xPDFdaughter / (xPDFgMother * g2Qenhance) ;
+ }
+ }
+ }
+
+ // Derive Q2 and x of mother from pT2 and z.
+ Q2 = pT2 / (1.- z);
+ xMother = xDaughter / z;
+
+ // Forbidden emission if outside allowed z range for given pT2.
+ mSister = ParticleDataTable::m0(idSister);
+ m2Sister = pow2(mSister);
+ pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
+ if(pT2corr < TINYPT2) { wt = 0.; continue; }
+
+ // Optionally veto emissions not ordered in rapidity (= angle).
+ if ( doRapidityOrder && dipEndNow->nBranch > 0
+ && pT2 > pow2( (1. - z) / (z * (1. - dipEndNow->zOld)) )
+ * dipEndNow->pT2Old ) { wt = 0.; continue; }
+
+ // If creating heavy quark by Q -> g + Q then next need g -> Q + Qbar.
+ // So minimum total mass2 is 4 * m2Sister, but use more to be safe.
+ if ( isGluon && ( abs(idMother) == 4 || abs(idMother) == 5 )) {
+ double m2QQsister = EXTRASPACEQ * 4. * m2Sister;
+ double pT2QQcorr = Q2 - z * (m2Dip + Q2) * (Q2 + m2QQsister) / m2Dip;
+ if(pT2QQcorr < TINYPT2) { wt = 0.; continue; }
+ }
+
+ // Select phi angle of branching at random.
+ phi = 2. * M_PI * Rndm::flat();
+
+ // Evaluation of ME correction.
+ if (doMEcorrections) wt *= calcMEcorr(MEtype, idMother, idDaughter,
+ m2Dip, z, Q2) / calcMEmax(MEtype, idMother, idDaughter);
+
+ // Optional dampening of large pT values in first radiation.
+ if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0)
+ wt *= pT2damp / (pT2 + pT2damp);
+
+ // Evaluation of new daughter and mother PDF's.
+ double xPDFdaughterNew = max ( TINYPDF,
+ beam.xfISR(iSysNow, idDaughter, xDaughter, pT2) );
+ double xPDFmotherNew = beam.xfISR(iSysNow, idMother, xMother, pT2);
+ wt *= xPDFmotherNew / xPDFdaughterNew;
+
+ // Check that valence step does not cause problem.
+ if (wt > 1.) infoPtr->errorMsg("Warning in SpaceShower::"
+ "pT2nextQCD: weight above unity");
+
+ // Iterate until acceptable pT (or have fallen below pTmin).
+ } while (wt < Rndm::flat()) ;
+
+ // Save values for (so far) acceptable branching.
+ dipEndNow->store( idDaughter,idMother, idSister, x1Now, x2Now, m2Dip,
+ pT2, z, Q2, mSister, m2Sister, pT2corr, phi);
+
+}
+
+//*********
+
+// Evolve a QCD dipole end near threshold, with g -> Q + Qbar enforced.
+// Note: No explicit Sudakov factor formalism here. Instead use that
+// df_Q(x, pT2) = (alpha_s/2pi) * (dT2/pT2) * ((gluon) * (splitting)).
+// This implies that effects of Q -> Q + g are neglected in this range.
+
+void SpaceShower::pT2nearQCDthreshold( BeamParticle& beam,
+ double m2Massive, double m2Threshold, double zMinAbs,
+ double zMaxMassive) {
+
+ // Initial values, to be used in kinematics and weighting.
+ double Lambda2 = (abs(idDaughter) == 4) ? Lambda4flav2 : Lambda5flav2;
+ double logM2Lambda2 = log( m2Massive / Lambda2 );
+ double xPDFmotherOld = beam.xfISR(iSysNow, 21, xDaughter, m2Threshold);
+
+ // Variables used inside evolution loop. (Mainly dummy start values.)
+ int loop = 0;
+ double wt = 0.;
+ double pT2 = 0.;
+ double z = 0.;
+ double Q2 = 0.;
+ double pT2corr = 0.;
+
+ // Begin loop over tries to find acceptable g -> Q + Qbar branching.
+ do {
+ wt = 0.;
+
+ // Check that not caught in infinite loop with impossible kinematics.
+ if (++loop > 100) {
+ infoPtr->errorMsg("Error in SpaceShower::pT2nearQCDthreshold: "
+ "stuck in loop");
+ return;
+ }
+
+ // Pick dpT2/pT2 in range [m2Massive,thresholdRatio * m2Massive].
+ pT2 = m2Massive * pow( m2Threshold / m2Massive, Rndm::flat() );
+
+ // Pick z flat in allowed range.
+ z = zMinAbs + Rndm::flat() * (zMaxMassive - zMinAbs);
+
+ // Check that kinematically possible choice.
+ Q2 = pT2 / (1.-z) - m2Massive;
+ pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Massive) / m2Dip;
+ if(pT2corr < TINYPT2) continue;
+
+ // Correction factor for running alpha_s. ??
+ wt = logM2Lambda2 / log( pT2 / Lambda2 );
+
+ // Correction factor for splitting kernel.
+ wt *= pow2(z) + pow2(1.-z) + 2. * z * (1.-z) * m2Massive / pT2;
+
+ // Correction factor for gluon density.
+ double xPDFmotherNew = beam.xfISR(iSysNow, 21, xDaughter/z, pT2);
+ wt *= xPDFmotherNew / xPDFmotherOld;
+
+ // Iterate until acceptable pT and z.
+ } while (wt < Rndm::flat()) ;
+
+ // Select phi angle of branching at random.
+ double phi = 2. * M_PI * Rndm::flat();
+
+ // Save values for (so far) acceptable branching.
+ double mSister = (abs(idDaughter) == 4) ? mc : mb;
+ dipEndNow->store( idDaughter, 21, -idDaughter, x1Now, x2Now, m2Dip,
+ pT2, z, Q2, mSister, pow2(mSister), pT2corr, phi);
+
+}
+
+//*********
+
+// Evolve a QED dipole end.
+
+void SpaceShower::pT2nextQED( double pT2begDip, double pT2endDip) {
+
+ // Type of dipole and starting values.
+ BeamParticle& beam = ( abs(dipEndNow->side) == 1 )
+ ? *beamAPtr : *beamBPtr;
+ bool isLeptonBeam = beam.isLepton();
+ int MEtype = dipEndNow->MEtype;
+ bool isPhoton = (idDaughter == 22);
+ double pT2 = pT2begDip;
+ double m2Lepton = (isLeptonBeam) ? pow2(beam.m()) : 0.;
+ if (isLeptonBeam && pT2begDip < m2Lepton) return;
+
+ // Currently no f -> gamma branching implemented. ??
+ if (isPhoton) return;
+
+ // alpha_em at maximum scale provides upper estimate.
+ double alphaEMmax = alphaEM.alphaEM(pT2begDip);
+ double alphaEM2pi = alphaEMmax / (2. * M_PI);
+
+ // Maximum x of mother implies minimum z = xDaughter / xMother.
+ double xMaxAbs = (isLeptonBeam) ? LEPTONXMAX : beam.xMax(iSysNow);
+ double zMinAbs = xDaughter / xMaxAbs;
+
+ // Maximum z from minimum pT and, for lepton, from minimum x_gamma.
+ double zMaxAbs = 1. - 0.5 * (pT2endDip / m2Dip) *
+ ( sqrt( 1. + 4. * m2Dip / pT2endDip ) - 1. );
+ if (isLeptonBeam) {
+ double zMaxLepton = xDaughter / (xDaughter + LEPTONXMIN);
+ if (zMaxLepton < zMaxAbs) zMaxAbs = zMaxLepton;
+ }
+ if (zMaxAbs < zMinAbs) return;
+
+ // Integrals of splitting kernels for fermions: f -> f. Use 1 + z^2 < 2.
+ // Ansatz f(z) = 2 / (1 - z), with + 2 / (z - xDaughter) for lepton.
+ double f2fInt = 0.;
+ double f2fIntA = 2. * log( (1. - zMinAbs) / (1. - zMaxAbs) );
+ double f2fIntB = 0.;
+ if (isLeptonBeam) {
+ f2fIntB = 2. * log( (zMaxAbs - xDaughter) / (zMinAbs - xDaughter) );
+ f2fInt = f2fIntA + f2fIntB;
+ } else f2fInt = pow2(dipEndNow->chgType / 3.) * f2fIntA;
+
+ // Upper estimate for evolution equation, including fudge factor.
+ if (doMEcorrections) f2fInt *= calcMEmax(MEtype, 1, 1);
+ double kernelPDF = alphaEM2pi * f2fInt;
+ double fudge = (isLeptonBeam) ? LEPTONFUDGE * log(m2Dip/m2Lepton) : 1.;
+ kernelPDF *= fudge;
+ if (kernelPDF < TINYKERNELPDF) return;
+
+ // Variables used inside evolution loop. (Mainly dummy start values.)
+ int idMother = 0;
+ double z = 0.;
+ double xMother = 0.;
+ double wt = 0.;
+ double Q2 = 0.;
+ double mSister = 0.;
+ double m2Sister = 0.;
+ double pT2corr = 0.;
+ double phi = 0.;
+
+ // Begin evolution loop towards smaller pT values.
+ do {
+ wt = 0.;
+
+ // Pick pT2 (in overestimated z range).
+ // For l -> l gamma include extrafactor 1 / ln(pT2 / m2l) in evolution.
+ double shift = pow(Rndm::flat(), 1. / kernelPDF);
+ if (isLeptonBeam) pT2 = m2Lepton * pow( pT2 / m2Lepton, shift);
+ else pT2 = pT2 * shift;
+
+ // Abort evolution if below cutoff scale, or below another branching.
+ if (pT2 < pT2endDip) return;
+ if (isLeptonBeam && pT2 < LEPTONPT2MIN * m2Lepton) return;
+
+ // Select z value of branching f -> f + gamma, and corrective weight.
+ idMother = idDaughter;
+ wt = 0.5 * (1. + pow2(z));
+ if (isLeptonBeam) {
+ if (f2fIntA > Rndm::flat() * (f2fIntA + f2fIntB))
+ z = 1. - (1. - zMinAbs)
+ * pow( (1. - zMaxAbs) / (1. - zMinAbs), Rndm::flat() );
+ else z = xDaughter + (zMinAbs - xDaughter)
+ * pow( (zMaxAbs - xDaughter) / (zMinAbs - xDaughter), Rndm::flat() );
+ wt *= (z - xDaughter) / (1. - xDaughter);
+ } else {
+ z = 1. - (1. - zMinAbs)
+ * pow( (1. - zMaxAbs) / (1. - zMinAbs), Rndm::flat() );
+ }
+
+ // Derive Q2 and x of mother from pT2 and z.
+ Q2 = pT2 / (1. - z);
+ xMother = xDaughter / z;
+
+ // Forbidden emission if outside allowed z range for given pT2.
+ mSister = 0.;
+ m2Sister = 0.;
+ pT2corr = Q2 - z * (m2Dip + Q2) * (Q2 + m2Sister) / m2Dip;
+ if(pT2corr < TINYPT2) { wt = 0.; continue; }
+
+ // Select phi angle of branching at random.
+ phi = 2. * M_PI * Rndm::flat();
+
+ // Correct by ln(pT2 / m2l) and fudge factor.
+ if (isLeptonBeam) wt *= log(pT2 / m2Lepton) / fudge;
+
+ // Evaluation of ME correction.
+ if (doMEcorrections) wt *= calcMEcorr(MEtype, idMother, idDaughter,
+ m2Dip, z, Q2) / calcMEmax(MEtype, idMother, idDaughter);
+
+ // Optional dampening of large pT values in first radiation.
+ if (dopTdamp && iSysNow == 0 && MEtype == 0 && nRad == 0)
+ wt *= pT2damp / (pT2 + pT2damp);
+
+ // Correct to current value of alpha_EM.
+ double alphaEMnow = alphaEM.alphaEM(pT2);
+ wt *= (alphaEMnow / alphaEMmax);
+
+ // Evaluation of new daughter and mother PDF's.
+ double xPDFdaughterNew = max ( TINYPDF,
+ beam.xfISR(iSysNow, idDaughter, xDaughter, pT2) );
+ double xPDFmotherNew = beam.xfISR(iSysNow, idMother, xMother, pT2);
+ wt *= xPDFmotherNew / xPDFdaughterNew;
+
+ // Iterate until acceptable pT (or have fallen below pTmin).
+ } while (wt < Rndm::flat()) ;
+
+ // Save values for (so far) acceptable branching.
+ dipEndNow->store( idDaughter,idMother, 22, x1Now, x2Now, m2Dip,
+ pT2, z, Q2, mSister, m2Sister, pT2corr, phi);
+
+}
+
+//*********
+
+// Kinematics of branching.
+// Construct mother -> daughter + sister, with recoiler on other side.
+
+bool SpaceShower::branch( Event& event) {
+
+ // Side on which branching occured.
+ int side = abs(dipEndSel->side);
+ double sideSign = (side == 1) ? 1. : -1.;
+
+ // Read in flavour and colour variables.
+ int iDaughter = event.getInSystem( iSysSel, side - 1);
+ int iRecoiler = event.getInSystem( iSysSel, 2 - side);
+ int idDaughterNow = dipEndSel->idDaughter;
+ int idMother = dipEndSel->idMother;
+ int idSister = dipEndSel->idSister;
+ int colDaughter = event[iDaughter].col();
+ int acolDaughter = event[iDaughter].acol();
+
+ // Read in kinematical variables.
+ double x1 = dipEndSel->x1;
+ double x2 = dipEndSel->x2;
+ double m2 = dipEndSel->m2Dip;
+ double m = sqrt(m2);
+ double pT2 = dipEndSel->pT2;
+ double z = dipEndSel->z;
+ double Q2 = dipEndSel->Q2;
+ double mSister = dipEndSel->mSister;
+ double m2Sister = dipEndSel->m2Sister;
+ double pT2corr = dipEndSel->pT2corr;
+ double phi = dipEndSel->phi;
+
+ // Take copy of existing system, to be given modified kinematics.
+ int eventSizeOld = event.size();
+ int systemSizeOld = event.sizeSystem(iSysSel);
+ for ( int iCopy = 0; iCopy < systemSizeOld; ++iCopy) {
+ int iOldCopy = event.getInSystem( iSysSel, iCopy);
+ int statusNew = (iOldCopy == iDaughter
+ || iOldCopy == iRecoiler) ? event[iOldCopy].status() : 44;
+ event.copy(iOldCopy, statusNew);
+ }
+
+ // Define colour flow in branching.
+ // Default corresponds to f -> f + gamma.
+ int colMother = colDaughter;
+ int acolMother = acolDaughter;
+ int colSister = 0;
+ int acolSister = 0;
+ if (idSister == 22) ;
+ // q -> q + g and 50% of g -> g + g; need new colour.
+ else if (idSister == 21 && ( (idMother > 0 && idMother < 9)
+ || (idMother == 21 && Rndm::flat() < 0.5) ) ) {
+ colMother = event.nextColTag();
+ colSister = colMother;
+ acolSister = colDaughter;
+ // qbar -> qbar + g and other 50% of g -> g + g; need new colour.
+ } else if (idSister == 21) {
+ acolMother = event.nextColTag();
+ acolSister = acolMother;
+ colSister = acolDaughter;
+ // q -> g + q.
+ } else if (idDaughterNow == 21 && idMother > 0) {
+ colMother = colDaughter;
+ acolMother = 0;
+ colSister = acolDaughter;
+ // qbar -> g + qbar
+ } else if (idDaughterNow == 21) {
+ acolMother = acolDaughter;
+ colMother = 0;
+ acolSister = colDaughter;
+ // g -> q + qbar.
+ } else if (idDaughterNow > 0 && idDaughterNow < 9) {
+ acolMother = event.nextColTag();
+ acolSister = acolMother;
+ // g -> qbar + q.
+ } else if (idDaughterNow < 0 && idDaughterNow > -9) {
+ colMother = event.nextColTag();
+ colSister = colMother;
+ // q -> gamma + q.
+ } else if (idDaughterNow == 22 && idMother > 0) {
+ colMother = event.nextColTag();
+ colSister = colMother;
+ // qbar -> gamma + qbar.
+ } else if (idDaughterNow == 22) {
+ acolMother = event.nextColTag();
+ acolSister = acolMother;
+ }
+
+ // Construct kinematics of mother, sister and recoiler in old rest frame.
+ double pTbranch = sqrt(pT2corr) * m2 / ( z * (m2 + Q2) );
+ double pzMother = sideSign * 0.5 * m * ( (m2 - Q2) / ( z * (m2 + Q2) )
+ + (Q2 + m2Sister) / m2 );
+ double eMother = sqrt( pow2(pTbranch) + pow2(pzMother) );
+ double pzSister = pzMother - sideSign * 0.5 * (m2 + Q2) / m;
+ double eSister = sqrt( pow2(pTbranch) + pow2(pzSister) + m2Sister );
+ double eNewRecoiler = 0.5 * (m2 + Q2) / m;
+ Vec4 pMother( pTbranch, 0., pzMother, eMother );
+ Vec4 pSister( pTbranch, 0., pzSister, eSister );
+ Vec4 pNewRecoiler( 0., 0., -sideSign * eNewRecoiler, eNewRecoiler);
+
+ // Indices of partons involved. Add new sister.
+ int iMother = eventSizeOld + side - 1;
+ int iNewRecoiler = eventSizeOld + 2 - side;
+ int iSister = event.append( idSister, 43, iMother, 0, 0, 0,
+ colSister, acolSister, pSister, mSister, sqrt(pT2) );
+
+ // References to the partons involved.
+ Particle& daughter = event[iDaughter];
+ Particle& mother = event[iMother];
+ Particle& newRecoiler = event[iNewRecoiler];
+ Particle& sister = event.back();
+
+ // Replace old by new mother; update new recoiler.
+ mother.id( idMother );
+ mother.status( -41);
+ mother.cols( colMother, acolMother);
+ mother.p( pMother);
+ newRecoiler.status( -42);
+ newRecoiler.p( pNewRecoiler);
+
+ // Update mother and daughter pointers; also for beams.
+ daughter.mothers( iMother, 0);
+ mother.daughters( iSister, iDaughter);
+ if (iSysSel == 0) {
+ event[1].daughter1( (side == 1) ? iMother : iNewRecoiler );
+ event[2].daughter1( (side == 2) ? iMother : iNewRecoiler );
+ }
+
+ // Find boost to old rest frame, and rotation -phi.
+ RotBstMatrix Mtot;
+ Mtot.bst(0., 0., (x2 - x1) / (x1 + x2) );
+ Mtot.rot(0., -phi);
+
+ // Find boost from old rest frame to event cm frame.
+ RotBstMatrix MfromRest;
+ // The boost to the new rest frame.
+ Vec4 sumNew = pMother + pNewRecoiler;
+ double betaX = sumNew.px() / sumNew.e();
+ double betaZ = sumNew.pz() / sumNew.e();
+ MfromRest.bst( -betaX, 0., -betaZ);
+ // Alignment of radiator + recoiler to +- z axis, and rotation +phi.
+ pMother.rotbst(MfromRest);
+ double theta = pMother.theta();
+ if (side == 2) theta += M_PI;
+ MfromRest.rot(-theta, phi);
+ // Longitudinal boost to radiator + recoiler in event cm frame.
+ double x1New = (side == 1) ? x1 / z : x1;
+ double x2New = (side == 2) ? x2 / z : x2;
+ MfromRest.bst(0., 0., (x1New - x2New) / (x1New + x2New) );
+ Mtot.rotbst(MfromRest);
+
+ // Perform cumulative rotation/boost operation.
+ // Mother, recoiler and sister from old rest frame to event cm frame.
+ mother.rotbst(MfromRest);
+ newRecoiler.rotbst(MfromRest);
+ sister.rotbst(MfromRest);
+ // The rest from (and to) event cm frame.
+ for ( int i = eventSizeOld + 2; i < eventSizeOld + systemSizeOld; ++i)
+ event[i].rotbst(Mtot);
+
+ // Update list of partons in system; adding newly produced one.
+ for ( int iCopy = 0; iCopy < systemSizeOld; ++iCopy)
+ event.setInSystem( iSysSel, iCopy, eventSizeOld + iCopy);
+ event.addToSystem( iSysSel, eventSizeOld + systemSizeOld);
+
+ // Update info on dipole ends (QCD or QED).
+ for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
+ if ( dipEnd[iDip].system == iSysSel && abs(dipEnd[iDip].side) == side ) {
+ dipEnd[iDip].iRadiator = iMother;
+ dipEnd[iDip].iRecoiler = iNewRecoiler;
+ if (dipEnd[iDip].side > 0)
+ dipEnd[iDip].colType = mother.colType();
+ else {
+ dipEnd[iDip].chgType = 0;
+ if ( (mother.isQuark() && doQEDshowerByQ)
+ || (mother.isLepton() && doQEDshowerByL) )
+ dipEnd[iDip].chgType = mother.chargeType();
+ }
+ // Kill ME corrections after first emission.
+ dipEnd[iDip].MEtype = 0;
+ }
+
+ // Update info on beam remnants.
+ BeamParticle& beamNow = (side == 1) ? *beamAPtr : *beamBPtr;
+ double xNew = (side == 1) ? x1New : x2New;
+ beamNow[iSysSel].update( iMother, idMother, xNew);
+ // Redo choice of companion kind whenever new flavour.
+ if (idMother != idDaughterNow) {
+ beamNow.xfISR( iSysSel, idMother, xNew, pT2);
+ beamNow.pickValSeaComp();
+ }
+ BeamParticle& beamRec = (side == 1) ? *beamBPtr : *beamAPtr;
+ beamRec[iSysSel].iPos( iNewRecoiler);
+
+ // Store branching values of current dipole. (For rapidity ordering.)
+ ++dipEndSel->nBranch;
+ dipEndSel->pT2Old = pT2;
+ dipEndSel->zOld = z;
+
+
+ // Done without any errors.
+ return true;
+
+}
+
+//*********
+
+// Find class of ME correction.
+
+int SpaceShower::findMEtype( int iSys, Event& event) {
+
+ // Default values and no action.
+ int MEtype = 0;
+ if (!doMEcorrections) ;
+
+ // Identify systems producing a single resonance.
+ else if (event.sizeSystem( iSys) == 3) {
+ int idIn1 = event[event.getInSystem( iSys, 0)].id();
+ int idIn2 = event[event.getInSystem( iSys, 1)].id();
+ int idRes = event[event.getInSystem( iSys, 2)].id();
+
+ // f + fbar -> vector boson.
+ if ( (idRes == 23 || abs(idRes) == 24 || idRes == 32
+ || idRes == 33 || abs(idRes) == 34 || abs(idRes) == 41)
+ && abs(idIn1) < 20 && abs(idIn2) < 20 ) MEtype = 1;
+
+ // g + g, gamma + gamma -> Higgs boson.
+ if ( (idRes == 25 || idRes == 35 || idRes == 36)
+ && ( ( idIn1 == 21 && idIn2 == 21 )
+ || ( idIn1 == 22 && idIn2 == 22 ) ) ) MEtype = 2;
+
+ // f + fbar -> Higgs boson.
+ if ( (idRes == 25 || idRes == 35 || idRes == 36)
+ && abs(idIn1) < 20 && abs(idIn2) < 20 ) MEtype = 3;
+ }
+
+ // Done.
+ return MEtype;
+
+}
+
+//*********
+
+// Provide maximum of expected ME weight; for preweighting of evolution.
+
+double SpaceShower::calcMEmax( int MEtype, int idMother, int idDaughterIn) {
+
+ // Currently only one non-unity case: g(gamma) f -> V f'.
+ if (MEtype == 1 && idMother > 20 && idDaughterIn < 20) return 3.;
+ return 1.;
+
+}
+
+//*********
+
+// Provide actual ME weight for current branching.
+// Note: currently ME corrections are only allowed for first branching
+// on each side, so idDaughter is essentially known and checks overkill.
+
+double SpaceShower::calcMEcorr(int MEtype, int idMother, int idDaughterIn,
+ double M2, double z, double Q2) {
+
+ // Convert to Mandelstam variables. Sometimes may need to swap later.
+ double sH = M2 / z;
+ double tH = -Q2;
+ double uH = Q2 - M2 * (1. - z) / z;
+ int idMabs = abs(idMother);
+ int idDabs = abs(idDaughterIn);
+
+ // Corrections for f + fbar -> s-channel vector boson.
+ if (MEtype == 1) {
+ if (idMabs < 20 && idDabs < 20) {
+ return (tH*tH + uH*uH + 2. * M2 * sH) / (sH*sH + M2*M2);
+ } else if (idDabs < 20) {
+ // g(gamma) f -> V f': -Q2 = (p_g - p_f')^2 in PS while
+ // tHat = (p_f - p_f')^2 in ME so need to swap tHat <-> uHat.
+ swap( tH, uH);
+ return (sH*sH + uH*uH + 2. * M2 * tH) / (pow2(sH - M2) + M2*M2);
+ }
+
+ // Corrections for g + g -> Higgs boson.
+ } else if (MEtype == 2) {
+ if (idMabs < 20 && idDabs > 20) {
+ return (sH*sH + uH*uH) / (sH*sH + pow2(sH - M2));
+ } else if (idDabs > 20) {
+ return 0.5 * (pow4(sH) + pow4(tH) + pow4(uH) + pow4(M2))
+ / pow2(sH*sH - M2 * (sH - M2));
+ }
+
+ // Corrections for f + fbar -> Higgs boson (f = b mainly).
+ } else if (MEtype == 3) {
+ if (idMabs < 20 && idDabs < 20) {
+ // The PS and ME answers agree for f fbar -> H g/gamma.
+ return 1.;
+ } else if (idDabs < 20) {
+ // Need to swap tHat <-> uHat, cf. vector-boson production above.
+ swap( tH, uH);
+ return (sH*sH + uH*uH + 2. * (M2 - uH) * (M2 - sH))
+ / (pow2(sH - M2) + M2*M2);
+ }
+ }
+
+ return 1.;
+
+}
+
+//*********
+
+// Print the list of dipoles.
+
+void SpaceShower::list(ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA SpaceShower Dipole Listing ---------- \n"
+ << "\n i syst side rad rec pTmax col chg type \n"
+ << fixed << setprecision(3);
+
+ // Loop over dipole list and print it.
+ for (int i = 0; i < int(dipEnd.size()); ++i)
+ os << setw(5) << i << setw(6) << dipEnd[i].system
+ << setw(6) << dipEnd[i].side << setw(6) << dipEnd[i].iRadiator
+ << setw(6) << dipEnd[i].iRecoiler << setw(12) << dipEnd[i].pTmax
+ << setw(5) << dipEnd[i].colType << setw(5) << dipEnd[i].chgType
+ << setw(5) << dipEnd[i].MEtype << "\n";
+
+ // Done.
+ os << "\n -------- End PYTHIA SpaceShower Dipole Listing ------"
+ << endl;
+
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// StandardModel.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the AlphaStrong class.
+
+#include "StandardModel.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The AlphaStrong class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Number of iterations to determine Lambda from given alpha_s.
+const int AlphaStrong::NITER = 10;
+
+// Always evaluate running alpha_s above Lambda3 to avoid disaster.
+// Safety margin picked to freeze roughly for alpha_s = 10.
+const double AlphaStrong::SAFETYMARGIN1 = 1.07;
+const double AlphaStrong::SAFETYMARGIN2 = 1.33;
+
+//*********
+
+// Initialize alpha_strong calculation by finding Lambda values etc.
+
+void AlphaStrong::init( double valueIn, int orderIn) {
+
+ // Order of alpha_s evaluation. Charm, bottom and Z0 masses.
+ // Pick defaults if ParticleDataTable not properly initialized.
+ valueRef = valueIn;
+ order = max( 0, min( 2, orderIn ) );
+ mc = ParticleDataTable::m0(4);
+ if (mc < 1. || mc > 2.) mc = 1.5;
+ mb = ParticleDataTable::m0(5);
+ if (mb < 3. || mb > 6.) mb = 4.8;
+ mZ = ParticleDataTable::m0(23);
+ if (mZ < 90. || mZ > 92.) mZ = 91.188;
+
+ // Fix alpha_s.
+ if (order == 0) {
+ Lambda3Save = Lambda4Save = Lambda5Save = scale2Min = 0.;
+
+ // First order alpha_s: match at flavour thresholds.
+ } else if (order == 1) {
+ Lambda5Save = mZ * exp( -6. * M_PI / (23. * valueRef) );
+ Lambda4Save = Lambda5Save * pow(mb/Lambda5Save, 2./25.);
+ Lambda3Save = Lambda4Save * pow(mc/Lambda4Save, 2./27.);
+ scale2Min = pow2(SAFETYMARGIN1 * Lambda3Save);
+
+ // Second order alpha_s: iterative match at flavour thresholds.
+ } else {
+ double b15 = 348. / 529.;
+ double b14 = 462. / 625.;
+ double b13 = 64. / 81.;
+ double b25 = 224687. / 242208.;
+ double b24 = 548575. / 426888.;
+ double b23 = 938709. / 663552.;
+ double logScale, loglogScale, correction, valueIter;
+
+ // Find Lambda_5 at m_Z.
+ Lambda5Save = mZ * exp( -6. * M_PI / (23. * valueRef) );
+ for (int iter = 0; iter < NITER; ++iter) {
+ logScale = 2. * log(mZ/Lambda5Save);
+ loglogScale = log(logScale);
+ correction = 1. - b15 * loglogScale / logScale
+ + pow2(b15 / logScale) * (pow2(loglogScale - 0.5) + b25 - 1.25);
+ valueIter = valueRef / correction;
+ Lambda5Save = mZ * exp( -6. * M_PI / (23. * valueIter) );
+ }
+
+ // Find Lambda_4 at m_b.
+ double logScaleB = 2. * log(mb/Lambda5Save);
+ double loglogScaleB = log(logScaleB);
+ double valueB = 12. * M_PI / (23. * logScaleB)
+ * (1. - b15 * loglogScaleB / logScaleB
+ + pow2(b15 / logScaleB) * (pow2(loglogScaleB - 0.5) + b25- 1.25) );
+ Lambda4Save = Lambda5Save;
+ for (int iter = 0; iter < NITER; ++iter) {
+ logScale = 2. * log(mb/Lambda4Save);
+ loglogScale = log(logScale);
+ correction = 1. - b14 * loglogScale / logScale
+ + pow2(b14 / logScale) * (pow2(loglogScale - 0.5) + b24 - 1.25);
+ valueIter = valueB / correction;
+ Lambda4Save = mb * exp( -6. * M_PI / (25. * valueIter) );
+ }
+
+ // Find Lambda_3 at m_c.
+ double logScaleC = 2. * log(mc/Lambda4Save);
+ double loglogScaleC = log(logScaleC);
+ double valueC = 12. * M_PI / (25. * logScaleC)
+ * (1. - b14 * loglogScaleC / logScaleC
+ + pow2(b14 / logScaleC) * (pow2(loglogScaleC - 0.5) + b24 - 1.25) );
+ Lambda3Save = Lambda4Save;
+ for (int iter = 0; iter < NITER; ++iter) {
+ logScale = 2. * log(mc/Lambda3Save);
+ loglogScale = log(logScale);
+ correction = 1. - b13 * loglogScale / logScale
+ + pow2(b13 / logScale) * (pow2(loglogScale - 0.5) + b23 - 1.25);
+ valueIter = valueC / correction;
+ Lambda3Save = mc * exp( -6. * M_PI / (27. * valueIter) );
+ }
+ scale2Min = pow2(SAFETYMARGIN2 * Lambda3Save);
+ }
+
+ // Save squares of mass and Lambda values as well.
+ mc2 = pow2(mc);
+ mb2 = pow2(mb);
+ Lambda3Save2 = pow2(Lambda3Save);
+ Lambda4Save2 = pow2(Lambda4Save);
+ Lambda5Save2 = pow2(Lambda5Save);
+ valueNow = valueIn;
+ scale2Now = mZ * mZ;
+ isInit = true;
+
+}
+
+//*********
+
+// Calculate alpha_s value
+
+double AlphaStrong::alphaS( double scale2) {
+
+ // Check for initialization and ensure minimal scale2 value.
+ if (!isInit) return 0.;
+ if (scale2 < scale2Min) scale2 = scale2Min;
+
+ // If equal to old scale then same answer.
+ if (scale2 == scale2Now && (order < 2 || lastCallToFull)) return valueNow;
+ scale2Now = scale2;
+ lastCallToFull = true;
+
+ // Fix alpha_s.
+ if (order == 0) {
+ valueNow = valueRef;
+
+ // First order alpha_s: differs by mass region.
+ } else if (order == 1) {
+ if (scale2 > mb2)
+ valueNow = 12. * M_PI / (23. * log(scale2/Lambda5Save2));
+ else if (scale2 > mc2)
+ valueNow = 12. * M_PI / (25. * log(scale2/Lambda4Save2));
+ else valueNow = 12. * M_PI / (27. * log(scale2/Lambda3Save2));
+
+ // Second order alpha_s: differs by mass region.
+ } else {
+ double Lambda2, b0, b1, b2;
+ if (scale2 > mb2) {
+ Lambda2 = Lambda5Save2;
+ b0 = 23.;
+ b1 = 348. / 529.;
+ b2 = 224687. / 242208.;
+ } else if (scale2 > mc2) {
+ Lambda2 = Lambda4Save2;
+ b0 = 25.;
+ b1 = 462. / 625.;
+ b2 = 548575. / 426888.;
+ } else {
+ Lambda2 = Lambda3Save2;
+ b0 = 27.;
+ b1 = 64. / 81.;
+ b2 = 938709. / 663552.;
+ }
+ double logScale = log(scale2/Lambda2);
+ double loglogScale = log(logScale);
+ valueNow = 12. * M_PI / (b0 * logScale)
+ * ( 1. - b1 * loglogScale / logScale
+ + pow2(b1 / logScale) * (pow2(loglogScale - 0.5) + b2 - 1.25) );
+ }
+
+ // Done.
+ return valueNow;
+
+}
+
+//*********
+
+// Calculate alpha_s value, but only use up to first-order piece.
+// (To be combined with alphaS2OrdCorr.)
+
+double AlphaStrong::alphaS1Ord( double scale2) {
+
+ // Check for initialization and ensure minimal scale2 value.
+ if (!isInit) return 0.;
+ if (scale2 < scale2Min) scale2 = scale2Min;
+
+ // If equal to old scale then same answer.
+ if (scale2 == scale2Now && (order < 2 || !lastCallToFull)) return valueNow;
+ scale2Now = scale2;
+ lastCallToFull = false;
+
+ // Fix alpha_S.
+ if (order == 0) {
+ valueNow = valueRef;
+
+ // First/second order alpha_s: differs by mass region.
+ } else {
+ if (scale2 > mb2)
+ valueNow = 12. * M_PI / (23. * log(scale2/Lambda5Save2));
+ else if (scale2 > mc2)
+ valueNow = 12. * M_PI / (25. * log(scale2/Lambda4Save2));
+ else valueNow = 12. * M_PI / (27. * log(scale2/Lambda3Save2));
+ }
+
+ // Done.
+ return valueNow;
+}
+
+//*********
+
+// Calculates the second-order extra factor in alpha_s.
+// (To be combined with alphaS1Ord.)
+
+double AlphaStrong::alphaS2OrdCorr( double scale2) {
+
+ // Check for initialization and ensure minimal scale2 value.
+ if (!isInit) return 1.;
+ if (scale2 < scale2Min) scale2 = scale2Min;
+
+ // Only meaningful for second order calculations.
+ if (order < 2) return 1.;
+
+ // Second order correction term: differs by mass region.
+ double Lambda2, b0, b1, b2;
+ if (scale2 > mb2) {
+ Lambda2 = Lambda5Save2;
+ b0 = 23.;
+ b1 = 348. / 529.;
+ b2 = 224687. / 242208.;
+ } else if (scale2 > mc2) {
+ Lambda2 = Lambda4Save2;
+ b0 = 25.;
+ b1 = 462. / 625.;
+ b2 = 548575. / 426888.;
+ } else {
+ Lambda2 = Lambda3Save2;
+ b0 = 27.;
+ b1 = 64. / 81.;
+ b2 = 938709. / 663552.;
+ }
+ double logScale = log(scale2/Lambda2);
+ double loglogScale = log(logScale);
+ return ( 1. - b1 * loglogScale / logScale
+ + pow2(b1 / logScale) * (pow2(loglogScale - 0.5) + b2 - 1.25) );
+
+}
+
+//**************************************************************************
+
+// The AlphaEM class.
+
+//*********
+
+// Definitions of static variables.
+double AlphaEM::alpEM0 = 0.00729735;
+double AlphaEM::alpEMmZ = 0.00781751;
+double AlphaEM::mZ2 = 8315.;
+// Effective thresholds for electron, muon, light quarks, tau+c, b.
+double AlphaEM::Q2step[5] = {0.26e-6, 0.011, 0.25, 3.5, 90.};
+// Running coefficients are sum charge2 / 3 pi in pure QED, here slightly
+// enhanced for quarks to approximately account for QCD corrections.
+double AlphaEM::bRun[5] = {0.1061, 0.2122, 0.460, 0.700, 0.725};
+double AlphaEM::alpEMstep[5] = {};
+
+//*********
+
+// Initialize alpha_EM calculation.
+
+void AlphaEM::initStatic() {
+
+ // Read in alpha_EM value at 0 and m_Z, and mass of Z.
+ alpEM0 = Settings::parm("StandardModel:alphaEM0");
+ alpEMmZ = Settings::parm("StandardModel:alphaEMmZ");
+ double mZ = ParticleDataTable::m0(23);
+ mZ2 = mZ * mZ;
+
+ // AlphaEM values at matching scales and matching b value.
+
+ // Step down from mZ to tau/charm threshold.
+ alpEMstep[4] = alpEMmZ / ( 1. + alpEMmZ * bRun[4]
+ * log(mZ2 / Q2step[4]) );
+ alpEMstep[3] = alpEMstep[4] / ( 1. - alpEMstep[4] * bRun[3]
+ * log(Q2step[3] / Q2step[4]) );
+
+ // Step up from me to light-quark threshold.
+ alpEMstep[0] = alpEM0;
+ alpEMstep[1] = alpEMstep[0] / ( 1. - alpEMstep[0] * bRun[0]
+ * log(Q2step[1] / Q2step[0]) );
+ alpEMstep[2] = alpEMstep[1] / ( 1. - alpEMstep[1] * bRun[1]
+ * log(Q2step[2] / Q2step[1]) );
+
+ // Fit b in range between light-quark and tau/charm to join smoothly.
+ bRun[2] = (1./alpEMstep[3] - 1./alpEMstep[2])
+ / log(Q2step[2] / Q2step[3]);
+
+}
+
+//*********
+
+// Calculate alpha_EM value
+
+double AlphaEM::alphaEM( double scale2) {
+
+ // Fix alphaEM; for order = -1 fixed at m_Z.
+ if (order == 0) return alpEM0;
+ if (order < 0) return alpEMmZ;
+
+ // Running alphaEM.
+ for (int i = 4; i >= 0; --i) if (scale2 > Q2step[i])
+ return alpEMstep[i] / (1. - bRun[i] * alpEMstep[i]
+ * log(scale2 / Q2step[i]) );
+ return alpEM0;
+
+}
+
+//**************************************************************************
+
+// The CoupEW class.
+
+//*********
+
+// Definitions of static variables.
+
+double CoupEW::s2tW = 0.232;
+double CoupEW::c2tW = 0.768;
+double CoupEW::s2tWbar = 0.232;
+double CoupEW::efSave[20] = { 0., -1./3., 2./3., -1./3., 2./3., -1./3.,
+ 2./3., -1./3., 2./3., 0., 0., -1., 0., -1., 0., -1., 0., -1., 0., 0.};
+double CoupEW::vfSave[20] = { };
+double CoupEW::afSave[20] = { 0., -1., 1., -1., 1., -1., 1., -1., 1.,
+ 0., 0., -1., 1., -1., 1., -1., 1., -1., 1., 0.};
+double CoupEW::lfSave[20] = { };
+double CoupEW::rfSave[20] = { };
+double CoupEW::ef2Save[20] = { };
+double CoupEW::vf2Save[20] = { };
+double CoupEW::af2Save[20] = { };
+double CoupEW::efvfSave[20] = { };
+double CoupEW::vf2af2Save[20] = { };
+
+//*********
+
+// Initialize electroweak mixing angle and couplings.
+
+void CoupEW::initStatic() {
+
+ // Read in electroweak mixing angle.
+ s2tW = Settings::parm("StandardModel:sin2thetaW");
+ c2tW = 1. - s2tW;
+ s2tWbar = Settings::parm("StandardModel:sin2thetaWbar");
+
+ // Initialize electroweak couplings.
+ for (int i = 0; i < 20; ++i) {
+ vfSave[i] = afSave[i] - 4. * s2tWbar * efSave[i];
+ lfSave[i] = afSave[i] - 2. * s2tWbar * efSave[i];
+ rfSave[i] = - 2. * s2tWbar * efSave[i];
+ ef2Save[i] = pow2(efSave[i]);
+ vf2Save[i] = pow2(vfSave[i]);
+ af2Save[i] = pow2(afSave[i]);
+ efvfSave[i] = efSave[i] * vfSave[i];
+ vf2af2Save[i] = vf2Save[i] + af2Save[i];
+ }
+
+}
+
+//**************************************************************************
+
+// The VCKM class.
+
+//*********
+
+// Definitions of static variables. Initialize to all elements zero.
+
+double VCKM::Vsave[5][5] = { };
+double VCKM::V2save[5][5] = { };
+double VCKM::V2out[20] = { };
+
+//*********
+
+// Prepare to handle CKM matrix elements.
+
+void VCKM::initStatic() {
+
+ // Read in matrix element values and store them.
+ Vsave[1][1] = Settings::parm("StandardModel:Vud");
+ Vsave[1][2] = Settings::parm("StandardModel:Vus");
+ Vsave[1][3] = Settings::parm("StandardModel:Vub");
+ Vsave[2][1] = Settings::parm("StandardModel:Vcd");
+ Vsave[2][2] = Settings::parm("StandardModel:Vcs");
+ Vsave[2][3] = Settings::parm("StandardModel:Vcb");
+ Vsave[3][1] = Settings::parm("StandardModel:Vtd");
+ Vsave[3][2] = Settings::parm("StandardModel:Vts");
+ Vsave[3][3] = Settings::parm("StandardModel:Vtb");
+
+ // Also allow for the potential existence of a fourth generation.
+ Vsave[1][4] = Settings::parm("FourthGeneration:VubPrime");
+ Vsave[2][4] = Settings::parm("FourthGeneration:VcbPrime");
+ Vsave[3][4] = Settings::parm("FourthGeneration:VtbPrime");
+ Vsave[4][1] = Settings::parm("FourthGeneration:VtPrimed");
+ Vsave[4][2] = Settings::parm("FourthGeneration:VtPrimes");
+ Vsave[4][3] = Settings::parm("FourthGeneration:VtPrimeb");
+ Vsave[4][4] = Settings::parm("FourthGeneration:VtPrimebPrime");
+
+ // Calculate squares of matrix elements.
+ for(int i = 1; i < 5; ++i) for(int j = 1; j < 5; ++j)
+ V2save[i][j] = pow2(Vsave[i][j]);
+
+ // Sum VCKM^2_out sum for given incoming flavour, excluding top as partner.
+ V2out[1] = V2save[1][1] + V2save[2][1];
+ V2out[2] = V2save[1][1] + V2save[1][2] + V2save[1][3];
+ V2out[3] = V2save[1][2] + V2save[2][2];
+ V2out[4] = V2save[2][1] + V2save[2][2] + V2save[2][3];
+ V2out[5] = V2save[1][3] + V2save[2][3];
+ V2out[6] = V2save[3][1] + V2save[3][2] + V2save[3][3];
+ V2out[7] = V2save[1][4] + V2save[2][4];
+ V2out[8] = V2save[4][1] + V2save[4][2] + V2save[4][3];
+ for (int i = 11; i <= 18; ++i) V2out[i] = 1.;
+
+}
+
+//*********
+
+// Return CKM value for incoming flavours (sign irrelevant).
+
+double VCKM::Vid(int id1, int id2) {
+
+ // Use absolute sign (want to cover both f -> f' W and f fbar' -> W).
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ if (id1Abs == 0 || id2Abs == 0 || (id1Abs + id2Abs)%2 != 1) return 0.;
+
+ // Ensure proper order before reading out from Vsave or lepton match.
+ if (id1Abs%2 == 1) swap(id1Abs, id2Abs);
+ if (id1Abs <= 8 && id2Abs <= 8) return Vsave[id1Abs/2][(id2Abs + 1)/2];
+ if ( (id1Abs == 12 || id1Abs == 14 || id1Abs == 16 || id1Abs == 18)
+ && id2Abs == id1Abs - 1 ) return 1.;
+
+ // No more valid cases.
+ return 0.;
+
+}
+
+//*********
+
+// Return squared CKM value for incoming flavours (sign irrelevant).
+
+double VCKM::V2id(int id1, int id2) {
+
+ // Use absolute sign (want to cover both f -> f' W and f fbar' -> W).
+ int id1Abs = abs(id1);
+ int id2Abs = abs(id2);
+ if (id1Abs == 0 || id2Abs == 0 || (id1Abs + id2Abs)%2 != 1) return 0.;
+
+ // Ensure proper order before reading out from V2save or lepton match.
+ if (id1Abs%2 == 1) swap(id1Abs, id2Abs);
+ if (id1Abs <= 8 && id2Abs <= 8) return V2save[id1Abs/2][(id2Abs + 1)/2];
+ if ( (id1Abs == 12 || id1Abs == 14 || id1Abs == 16 || id1Abs == 18)
+ && id2Abs == id1Abs - 1 ) return 1.;
+
+ // No more valid cases.
+ return 0.;
+
+}
+
+//*********
+
+// Pick an outgoing flavour for given incoming one, given CKM mixing.
+
+int VCKM::V2pick(int id) {
+
+ // Initial values.
+ int idIn = abs(id);
+ int idOut = 0;
+
+ // Quarks: need to make random choice.
+ if (idIn >= 1 && idIn <= 8) {
+ double V2rndm = Rndm::flat() * V2out[idIn];
+ if (idIn == 1) idOut = (V2rndm < V2save[1][1]) ? 2 : 4;
+ else if (idIn == 2) idOut = (V2rndm < V2save[1][1]) ? 1
+ : ( (V2rndm < V2save[1][1] + V2save[1][2]) ? 3 : 5 );
+ else if (idIn == 3) idOut = (V2rndm < V2save[1][2]) ? 2 : 4;
+ else if (idIn == 4) idOut = (V2rndm < V2save[2][1]) ? 1
+ : ( (V2rndm < V2save[2][1] + V2save[2][2]) ? 3 : 5 );
+ else if (idIn == 5) idOut = (V2rndm < V2save[1][3]) ? 2 : 4;
+ else if (idIn == 6) idOut = (V2rndm < V2save[3][1]) ? 1
+ : ( (V2rndm < V2save[3][1] + V2save[3][2]) ? 3 : 5 );
+ else if (idIn == 7) idOut = (V2rndm < V2save[1][4]) ? 2 : 4;
+ else if (idIn == 8) idOut = (V2rndm < V2save[4][1]) ? 1
+ : ( (V2rndm < V2save[4][1] + V2save[4][2]) ? 3 : 5 );
+
+ // Leptons: unambiguous.
+ } else if (idIn >= 11 && idIn <= 18) {
+ if (idIn%2 == 1) idOut = idIn + 1;
+ else idOut = idIn - 1;
+ }
+
+ // Done. Return with sign.
+ return ( (id > 0) ? idOut : -idOut );
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// StringFragmentation.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the StringEnd and
+// StringFragmentation classes.
+
+#include "StringFragmentation.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The StringEnd class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+
+// Avoid unphysical solutions to equation system.
+const double StringEnd::TINY = 1e-6;
+
+// Assume two (eX, eY) regions are related if pT2 differs by less.
+const double StringEnd::PT2SAME = 0.01;
+
+//*********
+
+// Set up initial endpoint values from input.
+
+void StringEnd::setUp(bool fromPosIn, int iEndIn, int idOldIn, int iMaxIn,
+ double pxIn, double pyIn, double GammaIn, double xPosIn, double xNegIn) {
+
+ // Simple transcription from input.
+ fromPos = fromPosIn;
+ iEnd = iEndIn;
+ iMax = iMaxIn;
+ flavOld = FlavContainer(idOldIn);
+ pxOld = pxIn;
+ pyOld = pyIn;
+ GammaOld = GammaIn;
+ iPosOld = (fromPos) ? 0 : iMax;
+ iNegOld = (fromPos) ? iMax : 0;
+ xPosOld = xPosIn;
+ xNegOld = xNegIn;
+
+}
+
+//*********
+
+// Fragment off one hadron from the string system, in flavour and pT.
+
+void StringEnd::newHadron() {
+
+ // Pick new flavour and form a new hadron.
+ do {
+ flavNew = flavSelPtr->pick( flavOld);
+ idHad = flavSelPtr->combine( flavOld, flavNew);
+ } while (idHad == 0);
+
+ // Pick its transverse momentum.
+ pxNew = pTSelPtr->px();
+ pyNew = pTSelPtr->py();
+ pxHad = pxOld + pxNew;
+ pyHad = pyOld + pyNew;
+
+ // Pick its mass and thereby define its transverse mass.
+ mHad = ParticleDataTable::mass(idHad);
+ mT2Had = pow2(mHad) + pow2(pxHad) + pow2(pyHad);
+
+}
+
+//*********
+
+// Fragment off one hadron from the string system, in momentum space,
+// by taking steps from positive end.
+
+Vec4 StringEnd::kinematicsHadron( StringSystem& system) {
+
+ // Pick fragmentation step z and calculate new Gamma.
+ zHad = zSelPtr->zFrag( flavOld.id, flavNew.id, mT2Had);
+ GammaNew = (1. - zHad) * (GammaOld + mT2Had / zHad);
+
+ // Set up references that are direction-neutral;
+ // ...Dir for direction of iteration and ...Inv for its inverse.
+ int& iDirOld = (fromPos) ? iPosOld : iNegOld;
+ int& iInvOld = (fromPos) ? iNegOld : iPosOld;
+ int& iDirNew = (fromPos) ? iPosNew : iNegNew;
+ int& iInvNew = (fromPos) ? iNegNew : iPosNew;
+ double& xDirOld = (fromPos) ? xPosOld : xNegOld;
+ double& xInvOld = (fromPos) ? xNegOld : xPosOld;
+ double& xDirNew = (fromPos) ? xPosNew : xNegNew;
+ double& xInvNew = (fromPos) ? xNegNew : xPosNew;
+ double& xDirHad = (fromPos) ? xPosHad : xNegHad;
+ double& xInvHad = (fromPos) ? xNegHad : xPosHad;
+
+ // Start search for new breakup in the old region.
+ iDirNew = iDirOld;
+ iInvNew = iInvOld;
+ Vec4 pTNew;
+
+ // Each step corresponds to trying a new string region.
+ for (int iStep = 0; ; ++iStep) {
+
+ // Referance to current string region.
+ StringRegion& region = system.region( iPosNew, iNegNew);
+
+ // Now begin special section for rapid processing of low region.
+ if (iStep == 0 && iPosOld + iNegOld == iMax) {
+
+ // A first step within a low region is easy.
+ if (mT2Had < zHad * xDirOld * (1. - xInvOld) * region.w2) {
+
+ // Translate into x coordinates.
+ xDirHad = zHad * xDirOld;
+ xInvHad = mT2Had / (xDirHad * region.w2);
+ xDirNew = xDirOld - xDirHad;
+ xInvNew = xInvOld + xInvHad;
+
+ // Find and return four-momentum of the produced particle.
+ return region.pHad( xPosHad, xNegHad, pxHad, pyHad);
+
+ // A first step out of a low region also OK, if there are more regions.
+ // Negative energy signals failure, i.e. in last region.
+ } else {
+ --iInvNew;
+ if (iInvNew < 0) return Vec4(0., 0., 0., -1.);
+
+ // Momentum taken by stepping out of region. Continue to next region.
+ xInvHad = 1. - xInvOld;
+ xDirHad = 0.;
+ pSoFar = region.pHad( xPosHad, xNegHad, pxOld, pyOld);
+ continue;
+ }
+
+ // Else, for first step, take into account starting pT.
+ } else if (iStep == 0) {
+ pSoFar = region.pHad( 0., 0., pxOld, pyOld);
+ pTNew = region.pHad( 0., 0., pxNew, pyNew);
+ }
+
+ // Now begin normal treatment of nontrivial regions.
+ // Set up four-vectors in a region not visited before.
+ if (!region.isSetUp) region.setUp(
+ system.regionLowPos(iPosNew).pPos,
+ system.regionLowNeg(iNegNew).pNeg, true);
+
+ // If new region is vanishingly small, continue immediately to next.
+ // Negative energy signals failure to do this, i.e. moved too low.
+ if (region.isEmpty) {
+ xDirHad = (iDirNew == iDirOld) ? xDirOld : 1.;
+ xInvHad = 0.;
+ pSoFar += region.pHad( xPosHad, xNegHad, 0., 0.);
+ ++iDirNew;
+ if (iDirNew + iInvNew > iMax) return Vec4(0., 0., 0., -1.);
+ continue;
+ }
+
+ // Reexpress pTNew w.r.t. base vectors in new region, if possible.
+ // Recall minus sign from normalization e_x^2 = e_y^2 = -1.
+ double pxNewTemp = -pTNew * region.eX;
+ double pyNewTemp = -pTNew * region.eY;
+ if (abs( pxNewTemp * pxNewTemp + pyNewTemp * pyNewTemp
+ - pxNew * pxNew - pyNew * pyNew) < PT2SAME) {
+ pxNew = pxNewTemp;
+ pyNew = pyNewTemp;
+ }
+
+ // Four-momentum taken so far, including new pT.
+ Vec4 pTemp = pSoFar + region.pHad( 0., 0., pxNew, pyNew);
+
+ // Derive coefficients for m2 expression.
+ // cM2 * x+ + cM3 * x- + cM4 * x+ * x- = m^2 - cM1;
+ double cM1 = pTemp.m2Calc();
+ double cM2 = 2. * (pTemp * region.pPos);
+ double cM3 = 2. * (pTemp * region.pNeg);
+ double cM4 = region.w2;
+ if (!fromPos) swap( cM2, cM3);
+
+ // Derive coefficients for Gamma expression.
+ // cGam2 * x+ + cGam3 * x- + cGam4 * x+ * x- = Gamma_new - cGam1;
+ double cGam1 = 0.;
+ double cGam2 = 0.;
+ double cGam3 = 0.;
+ double cGam4 = 0.;
+ for (int iInv = iInvNew; iInv <= iMax - iDirNew; ++iInv) {
+ double xInv = 1.;
+ if (iInv == iInvNew) xInv = (iInvNew == iInvOld) ? xInvOld : 0.;
+ for (int iDir = iDirNew; iDir <= iMax - iInv; ++iDir) {
+ double xDir = (iDir == iDirOld) ? xDirOld : 1.;
+ int iPos = (fromPos) ? iDir : iInv;
+ int iNeg = (fromPos) ? iInv : iDir;
+ StringRegion& regionGam = system.region( iPos, iNeg);
+ if (!regionGam.isSetUp) regionGam.setUp(
+ system.regionLowPos(iPos).pPos,
+ system.regionLowNeg(iNeg).pNeg, true);
+ double w2 = regionGam.w2;
+ cGam1 += xDir * xInv * w2;
+ if (iDir == iDirNew) cGam2 -= xInv * w2;
+ if (iInv == iInvNew) cGam3 += xDir * w2;
+ if (iDir == iDirNew && iInv == iInvNew) cGam4 -= w2;
+ }
+ }
+
+ // Solve (m2, Gamma) equation system => r2 * x-^2 + r1 * x- + r0 = 0.
+ double cM0 = pow2(mHad) - cM1;
+ double cGam0 = GammaNew - cGam1;
+ double r2 = cM3 * cGam4 - cM4 * cGam3;
+ double r1 = cM4 * cGam0 - cM0 * cGam4 + cM3 * cGam2 - cM2 * cGam3;
+ double r0 = cM2 * cGam0 - cM0 * cGam2;
+ double root = sqrtpos( r1*r1 - 4. * r2 * r0 );
+ if (abs(r2) < TINY || root < TINY) return Vec4(0., 0., 0., -1.);
+ xInvHad = 0.5 * (root / abs(r2) - r1 / r2);
+ xDirHad = (cM0 - cM3 * xInvHad) / (cM2 + cM4 * xInvHad);
+
+ // Define position of new trial vertex.
+ xDirNew = (iDirNew == iDirOld) ? xDirOld - xDirHad : 1. - xDirHad;
+ xInvNew = (iInvNew == iInvOld) ? xInvOld + xInvHad : xInvHad;
+
+ // Step up to new region if new x- > 1.
+ if (xInvNew > 1.) {
+ xInvHad = (iInvNew == iInvOld) ? 1. - xInvOld : 1.;
+ xDirHad = 0.;
+ pSoFar += region.pHad( xPosHad, xNegHad, 0., 0.);
+ --iInvNew;
+ if (iInvNew < 0) return Vec4(0., 0., 0., -1.);
+ continue;
+
+ // Step down to new region if new x+ < 0.
+ } else if (xDirNew < 0.) {
+ xDirHad = (iDirNew == iDirOld) ? xDirOld : 1.;
+ xInvHad = 0.;
+ pSoFar += region.pHad( xPosHad, xNegHad, 0., 0.);
+ ++iDirNew;
+ if (iDirNew + iInvNew > iMax) return Vec4(0., 0., 0., -1.);
+ continue;
+ }
+
+ // Else we have found the correct region, and can return four-momentum.
+ return pSoFar + region.pHad( xPosHad, xNegHad, pxNew, pyNew);
+
+ // End of "infinite" loop of stepping to new region.
+ }
+
+}
+
+//*********
+
+// Update string end information after a hadron has been removed.
+
+void StringEnd::update() {
+
+ flavOld.anti(flavNew);
+ iPosOld = iPosNew;
+ iNegOld = iNegNew;
+ pxOld = -pxNew;
+ pyOld = -pyNew;
+ GammaOld = GammaNew;
+ xPosOld = xPosNew;
+ xNegOld = xNegNew;
+
+}
+
+//**************************************************************************
+
+// The StringFragmentation class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// Maximum number of tries to (flavour-, energy) join the two string ends.
+const int StringFragmentation::NTRYFLAV = 10;
+const int StringFragmentation::NTRYJOIN = 25;
+
+// The last few times gradually increase the stop mass to make it easier.
+const int StringFragmentation::NSTOPMASS = 10;
+const double StringFragmentation::FACSTOPMASS = 1.05;
+
+// For closed string, pick a Gamma by taking a step with fictitious mass.
+const double StringFragmentation::CLOSEDM2MAX = 25.;
+const double StringFragmentation::CLOSEDM2FRAC = 0.1;
+
+// Do not allow too large argument to exp function.
+const double StringFragmentation::EXPMAX = 50.;
+
+// Matching criterion that p+ and p- not the same (can happen in gg loop).
+const double StringFragmentation::MATCHPOSNEG = 1e-6;
+
+// For pull on junction, do not trace too far down each leg.
+const double StringFragmentation::EJNWEIGHTMAX = 10.;
+
+// Iterate junction rest frame boost until convergence or too many tries.
+const double StringFragmentation::CONVJNREST = 1e-5;
+const int StringFragmentation::NTRYJNREST = 20;
+
+// Fail and try again when two legs combined to diquark (3 loops).
+const int StringFragmentation::NTRYJNMATCH = 20;
+
+// Consider junction-leg parton as massless if m2 tiny.
+const double StringFragmentation::M2MAXJRF = 1e-4;
+
+// Iterate junction rest frame equation until convergence or too many tries.
+const double StringFragmentation::CONVJRFEQ = 1e-12;
+const int StringFragmentation::NTRYJRFEQ = 40;
+
+//*********
+
+// Initialize and save pointers.
+
+void StringFragmentation::init(Info* infoPtrIn, StringFlav* flavSelPtrIn,
+ StringPT* pTSelPtrIn, StringZ* zSelPtrIn) {
+
+ // Save pointers.
+ infoPtr = infoPtrIn;
+ flavSelPtr = flavSelPtrIn;
+ pTSelPtr = pTSelPtrIn;
+ zSelPtr = zSelPtrIn;
+
+ // Initialize the StringFragmentation class.
+ stopMass = Settings::parm("StringFragmentation:stopMass");
+ stopNewFlav = Settings::parm("StringFragmentation:stopNewFlav");
+ stopSmear = Settings::parm("StringFragmentation:stopSmear");
+ eNormJunction = Settings::parm("StringFragmentation:eNormJunction");
+ eBothLeftJunction
+ = Settings::parm("StringFragmentation:eBothLeftJunction");
+ eMaxLeftJunction
+ = Settings::parm("StringFragmentation:eMaxLeftJunction");
+ eMinLeftJunction
+ = Settings::parm("StringFragmentation:eMinLeftJunction");
+
+ // Initialize the b parameter of the z spectrum, used when joining jets.
+ bLund = Settings::parm("StringZ:bLund");
+
+ // Send on pointers to the two StringEnd instances.
+ posEnd.init( flavSelPtr, pTSelPtr, zSelPtr);
+ negEnd.init( flavSelPtr, pTSelPtr, zSelPtr);
+
+}
+
+//*********
+
+// Perform the fragmentation.
+
+bool StringFragmentation::fragment( int iSub, ColConfig& colConfig,
+ Event& event) {
+
+ // Find partons and their total four-momentum.
+ iParton = colConfig[iSub].iParton;
+ iPos = iParton[0];
+ if (iPos < 0) iPos = iParton[1];
+ int idPos = event[iPos].id();
+ iNeg = iParton.back();
+ int idNeg = event[iNeg].id();
+ pSum = colConfig[iSub].pSum;
+
+ // Reset the local event record.
+ hadrons.clear();
+
+ // For closed gluon string: pick first breakup region.
+ isClosed = colConfig[iSub].isClosed;
+ if (isClosed) iParton = findFirstRegion(iParton, event);
+
+ // For junction topology: fragment off two of the string legs.
+ // Then iParton overwritten to remaining leg + leftover diquark.
+ pJunctionHadrons = 0.;
+ hasJunction = colConfig[iSub].hasJunction;
+ if (hasJunction && !fragmentToJunction(event)) return false;
+ int junctionHadrons = hadrons.size();
+ if (hasJunction) {
+ idPos = event[ iParton[0] ].id();
+ idNeg = event.back().id();
+ pSum -= pJunctionHadrons;
+ }
+
+ // Set up kinematics of string evolution ( = motion).
+ system.setUp(iParton, event);
+ stopMassNow = stopMass;
+
+ // Fallback loop, when joining in the middle fails. Bailout if stuck.
+ for ( int iTry = 0; ; ++iTry) {
+ if (iTry > NTRYJOIN) {
+ infoPtr->errorMsg("Error in StringFragmentation::fragment: "
+ "stuck in joining");
+ if (hasJunction) event.popBack(1);
+ return false;
+ }
+
+ // After several failed tries gradually allow larger stop mass.
+ if (iTry > NTRYJOIN - NSTOPMASS) stopMassNow *= FACSTOPMASS;
+
+ // Set up flavours of two string ends, and reset other info.
+ setStartEnds(idPos, idNeg, system);
+ pRem = pSum;
+
+ // Begin fragmentation loop, interleaved from the two ends.
+ bool fromPos;
+ for ( ; ; ) {
+
+ // Take a step either from the positive or the negative end.
+ fromPos = (Rndm::flat() < 0.5);
+ StringEnd& nowEnd = (fromPos) ? posEnd : negEnd;
+
+ // Construct trial hadron and check that energy remains.
+ nowEnd.newHadron();
+ if ( energyUsedUp(fromPos) ) break;
+
+ // Construct kinematics of the new hadron and store it.
+ Vec4 pHad = nowEnd.kinematicsHadron(system);
+ int statusHad = (fromPos) ? 83 : 84;
+ hadrons.append( nowEnd.idHad, statusHad, iPos, iNeg,
+ 0, 0, 0, 0, pHad, nowEnd.mHad);
+ if (pHad.e() < 0.) break;
+
+ // Update string end and remaining momentum.
+ nowEnd.update();
+ pRem -= pHad;
+
+ // End of fragmentation loop.
+ }
+
+ // When done, join in the middle. If this works, then really done.
+ if ( finalTwo(fromPos) ) break;
+
+ // Else remove produced particles (except from first two junction legs)
+ // and start all over.
+ int newHadrons = hadrons.size() - junctionHadrons;
+ hadrons.popBack(newHadrons);
+ }
+
+ // Junctions: remove fictitious end, restore original parton list
+ if (hasJunction) {
+ event.popBack(1);
+ iParton = colConfig[iSub].iParton;
+ }
+
+ // Store the hadrons in the normal event record, ordered from one end.
+ store(event);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Find region where to put first string break for closed gluon loop.
+
+vector<int> StringFragmentation::findFirstRegion(vector<int>& iPartonIn,
+ Event& event) {
+
+ // Evaluate mass-squared for all adjacent gluon pairs.
+ vector<double> m2Pair;
+ double m2Sum = 0.;
+ int size = iPartonIn.size();
+ for (int i = 0; i < size; ++i) {
+ double m2Now = 0.5 * event[ iPartonIn[i] ].p()
+ * event[ iPartonIn[(i + 1)%size] ].p();
+ m2Pair.push_back(m2Now);
+ m2Sum += m2Now;
+ }
+
+ // Pick breakup region with probability proportional to mass-squared.
+ double m2Reg = m2Sum * Rndm::flat();
+ int iReg = -1;
+ do m2Reg -= m2Pair[++iReg];
+ while (m2Reg > 0 && iReg < size - 1);
+
+ // Create reordered parton list, with breakup string region duplicated.
+ vector<int> iPartonOut;
+ for (int i = 0; i < size + 2; ++i)
+ iPartonOut.push_back( iPartonIn[(i + iReg)%size] );
+
+ // Done.
+ return iPartonOut;
+
+}
+
+//*********
+
+// Set flavours and momentum position for initial string endpoints.
+
+void StringFragmentation::setStartEnds( int idPos, int idNeg,
+ StringSystem systemNow) {
+
+ // Variables characterizing string endpoints: defaults for open string.
+ double px = 0.;
+ double py = 0.;
+ double Gamma = 0.;
+ double xPosFromPos = 1.;
+ double xNegFromPos = 0.;
+ double xPosFromNeg = 0.;
+ double xNegFromNeg = 1.;
+
+ // For closed gluon loop need to pick an initial flavour.
+ if (isClosed) {
+ do {
+ int idTry = flavSelPtr->pickLightQ();
+ FlavContainer flavTry(idTry, 1);
+ flavTry = flavSelPtr->pick( flavTry);
+ flavTry = flavSelPtr->pick( flavTry);
+ idPos = flavTry.id;
+ idNeg = -idPos;
+ } while (idPos == 0);
+
+ // Also need pT and breakup vertex position in region.
+ px = pTSelPtr->px();
+ py = pTSelPtr->py();
+ double m2Region = systemNow.regionLowPos(0).w2;
+ double m2Temp = min( CLOSEDM2MAX, CLOSEDM2FRAC * m2Region);
+ do {
+ double zTemp = zSelPtr->zFrag( idPos, idNeg, m2Temp);
+ xPosFromPos = 1. - zTemp;
+ xNegFromPos = m2Temp / (zTemp * m2Region);
+ } while (xNegFromPos > 1.);
+ Gamma = xPosFromPos * xNegFromPos * m2Region;
+ xPosFromNeg = xPosFromPos;
+ xNegFromNeg = xNegFromPos;
+ }
+
+ // Initialize two string endpoints.
+ posEnd.setUp( true, iPos, idPos, systemNow.iMax, px, py,
+ Gamma, xPosFromPos, xNegFromPos);
+ negEnd.setUp( false, iNeg, idNeg, systemNow.iMax, -px, -py,
+ Gamma, xPosFromNeg, xNegFromNeg);
+
+ // For closed gluon loop can allow popcorn on one side but not both.
+ if (isClosed) {
+ flavSelPtr->assignPopQ(posEnd.flavOld);
+ flavSelPtr->assignPopQ(negEnd.flavOld);
+ if (Rndm::flat() < 0.5) posEnd.flavOld.nPop = 0;
+ else negEnd.flavOld.nPop = 0;
+ posEnd.flavOld.rank = 1;
+ negEnd.flavOld.rank = 1;
+ }
+
+ // Done.
+
+}
+
+//*********
+
+// Check remaining energy-momentum whether it is OK to continue.
+
+bool StringFragmentation::energyUsedUp(bool fromPos) {
+
+ // If remaining negative energy then abort right away.
+ if (pRem.e() < 0.) return true;
+
+ // Calculate W2_minimum and done if remaining W2 is below it.
+ double wMin = stopMassNow
+ + ParticleDataTable::constituentMass(posEnd.flavOld.id)
+ + ParticleDataTable::constituentMass(negEnd.flavOld.id);
+ if (fromPos) wMin += stopNewFlav
+ * ParticleDataTable::constituentMass(posEnd.flavNew.id);
+ else wMin += stopNewFlav
+ * ParticleDataTable::constituentMass(negEnd.flavNew.id);
+ wMin *= 1. + (2. * Rndm::flat() - 1.) * stopSmear;
+ w2Rem = pRem.m2Calc();
+ if (w2Rem < pow2(wMin)) return true;
+
+ // Else still enough energy left to continue iteration.
+ return false;
+
+}
+
+//*********
+
+// Produce the final two partons to complete the system.
+
+bool StringFragmentation::finalTwo(bool fromPos) {
+
+ // Check whether we went too far in p+-.
+ if (pRem.e() < 0. || w2Rem < 0. || (hadrons.size() > 0
+ && hadrons.back().e() < 0.) ) return false;
+ if ( posEnd.iPosOld > negEnd.iPosOld || negEnd.iNegOld > posEnd.iNegOld)
+ return false;
+ if ( posEnd.iPosOld == negEnd.iPosOld && posEnd.xPosOld < negEnd.xPosOld)
+ return false;
+ if ( posEnd.iNegOld == negEnd.iNegOld && posEnd.xNegOld > negEnd.xNegOld)
+ return false;
+
+ // Construct the final hadron from the leftover flavours.
+ // Impossible to join two diquarks. Also break if stuck for other reason.
+ FlavContainer flav1 = (fromPos) ? posEnd.flavNew.anti() : posEnd.flavOld;
+ FlavContainer flav2 = (fromPos) ? negEnd.flavOld : negEnd.flavNew.anti();
+ if (abs(flav1.id) > 8 && abs(flav2.id) > 8) return false;
+ int idHad;
+ for (int iTry = 0; iTry < NTRYFLAV; ++iTry) {
+ idHad = flavSelPtr->combine( flav1, flav2);
+ if (idHad != 0) break;
+ }
+ if (idHad == 0) return false;
+
+ // Store the final particle and its new pT, and construct its mass.
+ if (fromPos) {
+ negEnd.idHad = idHad;
+ negEnd.pxNew = -posEnd.pxNew;
+ negEnd.pyNew = -posEnd.pyNew;
+ negEnd.mHad = ParticleDataTable::mass(idHad);
+ } else {
+ posEnd.idHad = idHad;
+ posEnd.pxNew = -negEnd.pxNew;
+ posEnd.pyNew = -negEnd.pyNew;
+ posEnd.mHad = ParticleDataTable::mass(idHad);
+ }
+
+ // String region in which to do the joining.
+ StringRegion region = finalRegion();
+ if (region.isEmpty) return false;
+
+ // Project remaining momentum along longitudinal and transverse directions.
+ region.project( pRem);
+ double pxRem = region.px() - posEnd.pxOld - negEnd.pxOld;
+ double pyRem = region.py() - posEnd.pyOld - negEnd.pyOld;
+ double xPosRem = region.xPos();
+ double xNegRem = region.xNeg();
+
+ // Share extra pT kick evenly between final two hadrons.
+ posEnd.pxOld += 0.5 * pxRem;
+ posEnd.pyOld += 0.5 * pyRem;
+ negEnd.pxOld += 0.5 * pxRem;
+ negEnd.pyOld += 0.5 * pyRem;
+
+ // Construct new pT and mT of the final two particles.
+ posEnd.pxHad = posEnd.pxOld + posEnd.pxNew;
+ posEnd.pyHad = posEnd.pyOld + posEnd.pyNew;
+ posEnd.mT2Had = pow2(posEnd.mHad) + pow2(posEnd.pxHad)
+ + pow2(posEnd.pyHad);
+ negEnd.pxHad = negEnd.pxOld + negEnd.pxNew;
+ negEnd.pyHad = negEnd.pyOld + negEnd.pyNew;
+ negEnd.mT2Had = pow2(negEnd.mHad) + pow2(negEnd.pxHad)
+ + pow2(negEnd.pyHad);
+
+ // Construct remaining system transverse mass.
+ double wT2Rem = w2Rem + pow2( posEnd.pxHad + negEnd.pxHad)
+ + pow2( posEnd.pyHad + negEnd.pyHad);
+
+ // Check that kinematics possible.
+ if ( sqrt(wT2Rem) < sqrt(posEnd.mT2Had) + sqrt(negEnd.mT2Had) )
+ return false;
+ double lambda2 = pow2( wT2Rem - posEnd.mT2Had - negEnd.mT2Had)
+ - 4. * posEnd.mT2Had * negEnd.mT2Had;
+ if (lambda2 <= 0.) return false;
+
+ // Construct kinematics, as viewed in the transverse rest frame.
+ double lambda = sqrt(lambda2);
+ double probReverse = 1. / (1. + exp( min( EXPMAX, bLund * lambda) ) );
+ double xpzPos = 0.5 * lambda/ wT2Rem;
+ if (probReverse > Rndm::flat()) xpzPos = -xpzPos;
+ double xmDiff = (posEnd.mT2Had - negEnd.mT2Had) / wT2Rem;
+ double xePos = 0.5 * (1. + xmDiff);
+ double xeNeg = 0.5 * (1. - xmDiff );
+
+ // Translate this into kinematics in the string frame.
+ Vec4 pHadPos = region.pHad( (xePos + xpzPos) * xPosRem,
+ (xePos - xpzPos) * xNegRem, posEnd.pxHad, posEnd.pyHad);
+ Vec4 pHadNeg = region.pHad( (xeNeg - xpzPos) * xPosRem,
+ (xeNeg + xpzPos) * xNegRem, negEnd.pxHad, negEnd.pyHad);
+
+ // Add produced particles to the event record.
+ hadrons.append( posEnd.idHad, 83, posEnd.iEnd, negEnd.iEnd,
+ 0, 0, 0, 0, pHadPos, posEnd.mHad);
+ hadrons.append( negEnd.idHad, 84, posEnd.iEnd, negEnd.iEnd,
+ 0, 0, 0, 0, pHadNeg, negEnd.mHad);
+
+ // It worked.
+ return true;
+
+}
+
+//*********
+
+// Construct a special joining region for the final two hadrons.
+
+StringRegion StringFragmentation::finalRegion() {
+
+ // Simple case when both string ends are in the same region.
+ if (posEnd.iPosOld == negEnd.iPosOld && posEnd.iNegOld == negEnd.iNegOld)
+ return system.region( posEnd.iPosOld, posEnd.iNegOld);
+
+ // Start out with empty region. (Empty used for error returns.)
+ StringRegion region;
+
+ // Add up all remaining p+.
+ Vec4 pPosJoin;
+ if ( posEnd.iPosOld == negEnd.iPosOld) {
+ double xPosJoin = posEnd.xPosOld - negEnd.xPosOld;
+ if (xPosJoin < 0.) return region;
+ pPosJoin = system.regionLowPos(posEnd.iPosOld).pHad( xPosJoin, 0., 0., 0.);
+ } else {
+ for (int iPosNow = posEnd.iPosOld; iPosNow <= negEnd.iPosOld; ++iPosNow) {
+ if (iPosNow == posEnd.iPosOld) pPosJoin
+ += system.regionLowPos(iPosNow).pHad( posEnd.xPosOld, 0., 0., 0.);
+ else if (iPosNow == negEnd.iPosOld) pPosJoin
+ += system.regionLowPos(iPosNow).pHad( 1. - negEnd.xPosOld, 0., 0., 0.);
+ else pPosJoin += system.regionLowPos(iPosNow).pHad( 1., 0., 0., 0.);
+ }
+ }
+
+ // Add up all remaining p-.
+ Vec4 pNegJoin;
+ if ( negEnd.iNegOld == posEnd.iNegOld) {
+ double xNegJoin = negEnd.xNegOld - posEnd.xNegOld;
+ if (xNegJoin < 0.) return region;
+ pNegJoin = system.regionLowNeg(negEnd.iNegOld).pHad( 0., xNegJoin, 0., 0.);
+ } else {
+ for (int iNegNow = negEnd.iNegOld; iNegNow <= posEnd.iNegOld; ++iNegNow) {
+ if (iNegNow == negEnd.iNegOld) pNegJoin
+ += system.regionLowNeg(iNegNow).pHad( 0., negEnd.xNegOld, 0., 0.);
+ else if (iNegNow == posEnd.iNegOld) pNegJoin
+ += system.regionLowNeg(iNegNow).pHad( 0., 1. - posEnd.xNegOld, 0., 0.);
+ else pNegJoin += system.regionLowNeg(iNegNow).pHad( 0., 1., 0., 0.);
+ }
+ }
+
+ // For a closed gluon loop pPosJoin == pNegJoin and the above does not work.
+ // So reshuffle; "perfect" for g g systems, OK in general.
+ Vec4 pTest = pPosJoin - pNegJoin;
+ if ( abs(pTest.px()) + abs(pTest.py()) + abs(pTest.pz()) + abs(pTest.e())
+ < MATCHPOSNEG * (pPosJoin.e() + pNegJoin.e()) ) {
+ Vec4 delta
+ = system.regionLowPos(posEnd.iPosOld + 1).pHad( 1., 0., 0., 0.)
+ - system.regionLowNeg(negEnd.iNegOld + 1).pHad( 0., 1., 0., 0.);
+ pPosJoin -= delta;
+ pNegJoin += delta;
+ }
+
+ // Construct a new region from remaining p+ and p-.
+ region.setUp( pPosJoin, pNegJoin);
+ if (region.isEmpty) return region;
+
+ // Project the existing pTold vectors onto the new directions.
+ Vec4 pTposOld = system.region( posEnd.iPosOld, posEnd.iNegOld).pHad(
+ 0., 0., posEnd.pxOld, posEnd.pyOld);
+ region.project( pTposOld);
+ posEnd.pxOld = region.px();
+ posEnd.pyOld = region.py();
+ Vec4 pTnegOld = system.region( negEnd.iPosOld, negEnd.iNegOld).pHad(
+ 0., 0., negEnd.pxOld, negEnd.pyOld);
+ region.project( pTnegOld);
+ negEnd.pxOld = region.px();
+ negEnd.pyOld = region.py();
+
+ // Done.
+ return region;
+
+}
+
+//*********
+
+// Store the hadrons in the normal event record, ordered from one end.
+
+void StringFragmentation::store(Event& event) {
+
+ // Starting position.
+ int iFirst = event.size();
+
+ // Copy straight over from first two junction legs.
+ if (hasJunction) {
+ for (int i = 0; i < hadrons.size(); ++i)
+ if (hadrons[i].status() == 85 || hadrons[i].status() == 86)
+ event.append( hadrons[i] );
+ }
+
+ // Loop downwards, copying all from the positive end.
+ for (int i = 0; i < hadrons.size(); ++i)
+ if (hadrons[i].status() == 83) event.append( hadrons[i] );
+
+ // Loop upwards, copying all from the negative end.
+ for (int i = hadrons.size() - 1; i >= 0 ; --i)
+ if (hadrons[i].status() == 84) event.append( hadrons[i] );
+ int iLast = event.size() - 1;
+
+ // Set decay vertex when this is displaced.
+ if (event[posEnd.iEnd].hasVertex()) {
+ Vec4 vDec = event[posEnd.iEnd].vDec();
+ for (int i = iFirst; i <= iLast; ++i) event[i].vProd( vDec );
+ }
+
+ // Set lifetime of hadrons.
+ for (int i = iFirst; i <= iLast; ++i)
+ event[i].tau( event[i].tau0() * Rndm::exp() );
+
+ // Mark original partons as hadronized and set their daughter range.
+ for (int i = 0; i < int(iParton.size()); ++i)
+ if (iParton[i] >= 0) {
+ event[ iParton[i] ].statusNeg();
+ event[ iParton[i] ].daughters(iFirst, iLast);
+ }
+
+}
+
+//*********
+
+// Fragment off two of the string legs in to a junction.
+
+bool StringFragmentation::fragmentToJunction(Event& event) {
+
+ // Identify range of partons on the three legs.
+ // (Each leg begins with an iParton[i] = -(10 + 10*junctionNuber + leg),
+ // and partons then appear ordered from the junction outwards.)
+ int legBeg[3], legEnd[3];
+ int leg = -1;
+ for (int i = 0; i < int(iParton.size()); ++i) {
+ if (iParton[i] < 0) legBeg[++leg] = i + 1;
+ else legEnd[leg] = i;
+ }
+
+ // Iterate from system rest frame towards the junction rest frame (JRF).
+ RotBstMatrix MtoJRF, Mstep;
+ MtoJRF.bstback(pSum);
+ Vec4 pWTinJRF[3];
+ int iter = 0;
+ double errInCM = 0.;
+ do {
+ ++iter;
+
+ // Find weighted sum of momenta on the three sides of the junction.
+ for (leg = 0; leg < 3; ++ leg) {
+ pWTinJRF[leg] = 0.;
+ double eWeight = 0.;
+ for (int i = legBeg[leg]; i <= legEnd[leg]; ++i) {
+ Vec4 pTemp = event[ iParton[i] ].p();
+ pTemp.rotbst(MtoJRF);
+ pWTinJRF[leg] += pTemp * exp(-eWeight);
+ eWeight += pTemp.e() / eNormJunction;
+ if (eWeight > EJNWEIGHTMAX) break;
+ }
+ }
+
+ // Store original deviation from 120 degree topology.
+ if (iter == 1) errInCM = pow2(costheta(pWTinJRF[0], pWTinJRF[1]) + 0.5)
+ + pow2(costheta(pWTinJRF[0], pWTinJRF[2]) + 0.5)
+ + pow2(costheta(pWTinJRF[1], pWTinJRF[2]) + 0.5);
+
+ // Find new JRF from the set of weighted momenta.
+ Mstep = junctionRestFrame( pWTinJRF[0], pWTinJRF[1], pWTinJRF[2]);
+ // Fortran code will not take full step after the first few
+ // iterations. How implement this in terms of an M matrix??
+ MtoJRF.rotbst( Mstep );
+ } while (iter < 3 || (Mstep.deviation() > CONVJNREST && iter < NTRYJNREST) );
+
+ // If final deviation from 120 degrees is bigger than in CM then revert.
+ double errInJRF = pow2(costheta(pWTinJRF[0], pWTinJRF[1]) + 0.5)
+ + pow2(costheta(pWTinJRF[0], pWTinJRF[2]) + 0.5)
+ + pow2(costheta(pWTinJRF[1], pWTinJRF[2]) + 0.5);
+ if (errInJRF > errInCM) {
+ infoPtr->errorMsg("Warning in StringFragmentation::fragmentTo"
+ "Junction: bad convergence junction rest frame");
+ MtoJRF.reset();
+ MtoJRF.bstback(pSum);
+ }
+
+ // Opposite operation: boost from JRF to original system.
+ RotBstMatrix MfromJRF = MtoJRF;
+ MfromJRF.invert();
+
+ // Sum leg four-momenta in original frame and in JRF.
+ Vec4 pInLeg[3], pInJRF[3];
+ for (leg = 0; leg < 3; ++leg) {
+ pInLeg[leg] = 0.;
+ for (int i = legBeg[leg]; i <= legEnd[leg]; ++i)
+ pInLeg[leg] += event[ iParton[i] ].p();
+ pInJRF[leg] = pInLeg[leg];
+ pInJRF[leg].rotbst(MtoJRF);
+ }
+
+ // Pick the two legs with lowest energy in JRF.
+ int legMin = (pInJRF[0].e() < pInJRF[1].e()) ? 0 : 1;
+ int legMax = 1 - legMin;
+ if (pInJRF[2].e() < min(pInJRF[0].e(), pInJRF[1].e()) ) legMin = 2;
+ else if (pInJRF[2].e() > max(pInJRF[0].e(), pInJRF[1].e()) ) legMax = 2;
+ int legMid = 3 - legMin - legMax;
+
+ // Save info on which status codes belong with the three legs.
+ int iJunction = (-iParton[0]) / 10 - 1;
+ event.statusJunction( iJunction, legMin, 85);
+ event.statusJunction( iJunction, legMid, 86);
+ event.statusJunction( iJunction, legMax, 83);
+
+ // Temporarily copy the partons on the low-energy legs, into the JRF,
+ // in reverse order, so (anti)quark leg end first.
+ vector<int> iPartonMin;
+ for (int i = legEnd[legMin]; i >= legBeg[legMin]; --i) {
+ int iNew = event.append( event[ iParton[i] ] );
+ event[iNew].rotbst(MtoJRF);
+ iPartonMin.push_back( iNew );
+ }
+ vector<int> iPartonMid;
+ for (int i = legEnd[legMid]; i >= legBeg[legMid]; --i) {
+ int iNew = event.append( event[ iParton[i] ] );
+ event[iNew].rotbst(MtoJRF);
+ iPartonMid.push_back( iNew );
+ }
+
+ // Find final weighted sum of momenta on each of the two legs.
+ double eWeight = 0.;
+ pWTinJRF[legMin] = 0.;
+ for (int i = iPartonMin.size() - 1; i >= 0; --i) {
+ pWTinJRF[legMin] += event[ iPartonMin[i] ].p() * exp(-eWeight);
+ eWeight += event[ iPartonMin[i] ].e() / eNormJunction;
+ if (eWeight > EJNWEIGHTMAX) break;
+ }
+ eWeight = 0.;
+ pWTinJRF[legMid] = 0.;
+ for (int i = iPartonMid.size() - 1; i >= 0; --i) {
+ pWTinJRF[legMid] += event[ iPartonMid[i] ].p() * exp(-eWeight);
+ eWeight += event[ iPartonMid[i] ].e() / eNormJunction;
+ if (eWeight > EJNWEIGHTMAX) break;
+ }
+
+ // Define fictitious opposing partons in JRF and store as string ends.
+ Vec4 pOppose = pWTinJRF[legMin];
+ pOppose.flip3();
+ int idOppose = (Rndm::flat() > 0.5) ? 2 : 1;
+ if (event[ iPartonMin[0] ].col() > 0) idOppose = -idOppose;
+ int iOppose = event.append( idOppose, 77, 0, 0, 0, 0, 0, 0,
+ pOppose, 0.);
+ iPartonMin.push_back( iOppose);
+ pOppose = pWTinJRF[legMid];
+ pOppose.flip3();
+ idOppose = (Rndm::flat() > 0.5) ? 2 : 1;
+ if (event[ iPartonMid[0] ].col() > 0) idOppose = -idOppose;
+ iOppose = event.append( idOppose, 77, 0, 0, 0, 0, 0, 0,
+ pOppose, 0.);
+ iPartonMid.push_back( iOppose);
+
+ // Set up kinematics of string evolution in low-energy temporary systems.
+ systemMin.setUp(iPartonMin, event);
+ systemMid.setUp(iPartonMid, event);
+
+ // Outer fallback loop, when too little energy left for third leg.
+ int idMin = 0;
+ int idMid = 0;
+ Vec4 pDiquark;
+ for ( int iTryOuter = 0; ; ++iTryOuter) {
+
+ // Middle fallback loop, when much unused energy in leg remnants.
+ double eLeftMin = 0.;
+ double eLeftMid = 0.;
+ for ( int iTryMiddle = 0; ; ++iTryMiddle) {
+
+ // Loop over the two lowest-energy legs.
+ for (int legLoop = 0; legLoop < 2; ++ legLoop) {
+ int legNow = (legLoop == 0) ? legMin : legMid;
+
+ // Read in properties specific to this leg.
+ StringSystem& systemNow = (legLoop == 0) ? systemMin : systemMid;
+ int idPos = (legLoop == 0) ? event[ iPartonMin[0] ].id()
+ : event[ iPartonMid[0] ].id();
+ idOppose = (legLoop == 0) ? event[ iPartonMin.back() ].id()
+ : event[ iPartonMid.back() ].id();
+ double eInJRF = pInJRF[legNow].e();
+ int statusHad = (legLoop == 0) ? 85 : 86;
+
+ // Inner fallback loop, when a diquark comes in to junction.
+ double eUsed = 0.;
+ for ( int iTryInner = 0; ; ++iTryInner) {
+ if (iTryInner > NTRYJNMATCH) {
+ infoPtr->errorMsg("Error in StringFragmentation::fragment"
+ "ToJunction: caught in junction flavour loop");
+ event.popBack( iPartonMin.size() + iPartonMid.size() );
+ return false;
+ }
+
+ // Set up two string ends, and begin fragmentation loop.
+ setStartEnds(idPos, idOppose, systemNow);
+ eUsed = 0.;
+ int nHadrons = 0;
+ bool noNegE = true;
+ for ( ; ; ++nHadrons) {
+
+ // Construct trial hadron from positive end.
+ posEnd.newHadron();
+ Vec4 pHad = posEnd.kinematicsHadron(systemNow);
+
+ // Negative energy signals failure in construction.
+ if (pHad.e() < 0. ) { noNegE = false; break; }
+
+ // Break if passed system midpoint ( = junction) in energy.
+ if (eUsed + pHad.e() > eInJRF) break;
+
+ // Else construct kinematics of the new hadron and store it.
+ hadrons.append( posEnd.idHad, statusHad, iPos, iNeg,
+ 0, 0, 0, 0, pHad, posEnd.mHad);
+
+ // Update string end and remaining momentum.
+ posEnd.update();
+ eUsed += pHad.e();
+ }
+
+ // End of fragmentation loop. Inner loopback if ends on a diquark.
+ if ( noNegE && abs(posEnd.flavOld.id) < 10 ) break;
+ hadrons.popBack(nHadrons);
+ }
+
+ // End of one-leg fragmentation. Store end quark and remnant energy.
+ if (legNow == legMin) {
+ idMin = posEnd.flavOld.id;
+ eLeftMin = eInJRF - eUsed;
+ } else {
+ idMid = posEnd.flavOld.id;
+ eLeftMid = eInJRF - eUsed;
+ }
+ }
+
+ // End of both-leg fragmentation. Middle loopback if too much energy left.
+ double eTrial = eBothLeftJunction + Rndm::flat() * eMaxLeftJunction;
+ if (iTryMiddle > NTRYJNMATCH
+ || ( min( eLeftMin, eLeftMid) < eBothLeftJunction
+ && max( eLeftMin, eLeftMid) < eTrial ) ) break;
+ hadrons.clear();
+ }
+
+ // Boost hadrons away from the JRF to the original frame.
+ for (int i = 0; i < hadrons.size(); ++i) {
+ hadrons[i].rotbst(MfromJRF);
+ pJunctionHadrons += hadrons[i].p();
+ }
+
+ // Outer loopback if too little energy left in third leg.
+ pDiquark = pInLeg[legMin] + pInLeg[legMid] - pJunctionHadrons;
+ double m2Left = m2( pInLeg[legMax], pDiquark);
+ if (iTryOuter > NTRYJNMATCH
+ || m2Left > eMinLeftJunction * pInLeg[legMax].e() ) break;
+ hadrons.clear();
+ pJunctionHadrons = 0.;
+ }
+
+ // Now found solution; no more loopback. Remove temporary parton copies.
+ event.popBack( iPartonMin.size() + iPartonMid.size() );
+
+ // Construct and store an effective diquark string end from the
+ // two remnant quark ends, for temporary usage.
+ int idDiquark = flavSelPtr->makeDiquark( idMin, idMid);
+ double mDiquark = pDiquark.mCalc();
+ int iDiquark = event.append( idDiquark, 78, 0, 0, 0, 0, 0, 0,
+ pDiquark, mDiquark);
+
+ // Find the partons on the last leg, again in reverse order.
+ vector<int> iPartonMax;
+ for (int i = legEnd[legMax]; i >= legBeg[legMax]; --i)
+ iPartonMax.push_back( iParton[i] );
+ iPartonMax.push_back( iDiquark );
+
+ // Modify parton list to remaining leg + remnant of the first two.
+ iParton = iPartonMax;
+
+ // Done.
+ return true;
+}
+
+//*********
+
+// Find the boost matrix to the rest frame of a junction,
+// given the three respective endpoint four-momenta.
+
+RotBstMatrix StringFragmentation::junctionRestFrame(Vec4& p0, Vec4& p1,
+ Vec4& p2) {
+
+ // Calculate masses and other invariants.
+ Vec4 pSumJun = p0 + p1 + p2;
+ double sHat = pSumJun.m2Calc();
+ double pp[3][3];
+ pp[0][0] = p0.m2Calc();
+ pp[1][1] = p1.m2Calc();
+ pp[2][2] = p2.m2Calc();
+ pp[0][1] = pp[1][0] = p0 * p1;
+ pp[0][2] = pp[2][0] = p0 * p2;
+ pp[1][2] = pp[2][1] = p1 * p2;
+
+ // Requirement (eiMax)_j = pi*pj/mj < (eiMax)_k = pi*pk/mk, used below,
+ // here rewritten as pi*pj * mk < pi*pk * mj and squared.
+ double eMax01 = pow2(pp[0][1]) * pp[2][2];
+ double eMax02 = pow2(pp[0][2]) * pp[1][1];
+ double eMax12 = pow2(pp[1][2]) * pp[0][0];
+
+ // Initially pick i to be the most massive parton. but allow other tries.
+ int i = (pp[1][1] > pp[0][0]) ? 1 : 0;
+ if (pp[2][2] > max(pp[0][0], pp[1][1])) i = 2;
+ int j, k;
+ double ei = 0.;
+ double ej = 0.;
+ double ek = 0.;
+ for (int iTry = 0; iTry < 3; ++iTry) {
+
+ // Pick j to give minimal eiMax, and k the third vector.
+ if (i == 0) j = (eMax02 < eMax01) ? 2 : 1;
+ else if (i == 1) j = (eMax12 < eMax01) ? 2 : 0;
+ else j = (eMax12 < eMax02) ? 1 : 0;
+ k = 3 - i - j;
+
+ // Alternative names according to i, j, k conventions.
+ double m2i = pp[i][i];
+ double m2j = pp[j][j];
+ double m2k = pp[k][k];
+ double pipj = pp[i][j];
+ double pipk = pp[i][k];
+ double pjpk = pp[j][k];
+
+ // Trivial to find new parton energies if all three partons are massless.
+ if (m2i < M2MAXJRF) {
+ ei = sqrt( 2. * pipk * pipj / (3. * pjpk) );
+ ej = sqrt( 2. * pjpk * pipj / (3. * pipk) );
+ ek = sqrt( 2. * pipk * pjpk / (3. * pipj) );
+
+ // Else find three-momentum range for parton i and values at extremes.
+ } else {
+ // Minimum when i is at rest.
+ double piMin = 0.;
+ double eiMin = sqrt(m2i);
+ double ejMin = pipj / eiMin;
+ double ekMin = pipk / eiMin;
+ double pjMin = sqrtpos( ejMin*ejMin - m2j );
+ double pkMin = sqrtpos( ekMin*ekMin - m2k );
+ double fMin = ejMin * ekMin + 0.5 * pjMin * pkMin - pjpk;
+ // Maximum estimated when j + k is at rest, alternatively j at rest.
+ double eiMax = (pipj + pipk) / sqrt(m2j + m2k + 2. * pjpk);
+ if (m2j > M2MAXJRF) eiMax = min( eiMax, pipj / sqrt(m2j) );
+ double piMax = sqrtpos( eiMax*eiMax - m2i );
+ double temp = eiMax*eiMax - 0.25 *piMax*piMax;
+ double pjMax = (eiMax * sqrtpos( pipj*pipj - m2j * temp )
+ - 0.5 * piMax * pipj) / temp;
+ double pkMax = (eiMax * sqrtpos( pipk*pipk - m2k * temp )
+ - 0.5 * piMax * pipk) / temp;
+ double ejMax = sqrt(pjMax*pjMax + m2j);
+ double ekMax = sqrt(pkMax*pkMax + m2k);
+ double fMax = ejMax * ekMax + 0.5 * pjMax * pkMax - pjpk;
+
+ // If unexpected values at upper endpoint then pick another parton.
+ if (fMax > 0.) {
+ int iPrel = (i + 1)%3;
+ if (pp[iPrel][iPrel] > M2MAXJRF) {i = iPrel; continue;}
+ ++iTry;
+ iPrel = (i + 2)%3;
+ if (iTry < 3 && pp[iPrel][iPrel] > M2MAXJRF) {i = iPrel; continue;}
+ }
+
+ // Start binary + linear search to find solution inside range.
+ int iterMin = 0;
+ int iterMax = 0;
+ double pi = 0.5 * (piMin + piMax);
+ for (int iter = 0; iter < NTRYJRFEQ; ++iter) {
+
+ // Derive momentum of other two partons and distance to root.
+ ei = sqrt(pi*pi + m2i);
+ temp = ei*ei - 0.25 * pi*pi;
+ double pj = (ei * sqrtpos( pipj*pipj - m2j * temp )
+ - 0.5 * pi * pipj) / temp;
+ double pk = (ei * sqrtpos( pipk*pipk - m2k * temp )
+ - 0.5 * pi * pipk) / temp;
+ ej = sqrt(pj*pj + m2j);
+ ek = sqrt(pk*pk + m2k);
+ double fNow = ej * ek + 0.5 * pj * pk - pjpk;
+
+ // Replace lower or upper bound by new value.
+ if (fNow > 0.) { ++iterMin; piMin = pi; fMin = fNow;}
+ else {++iterMax; piMax = pi; fMax = fNow;}
+
+ // Pick next i momentum to explore, hopefully closer to root.
+ if (2 * iter < NTRYJRFEQ
+ && (iterMin < 2 || iterMax < 2 || 4 * iter < NTRYJRFEQ))
+ { pi = 0.5 * (piMin + piMax); continue;}
+ if (fMin < 0. || fMax > 0. || abs(fNow) < CONVJRFEQ * sHat) break;
+ pi = piMin + (piMax - piMin) * fMin / (fMin - fMax);
+ }
+
+ // If arrived here then either succeeded or exhausted possibilities.
+ } break;
+ }
+
+ // Now we know the energies in the junction rest frame.
+ double eNew[3]; eNew[i] = ei; eNew[j] = ej; eNew[k] = ek;
+
+ // Boost (copy of) partons to their rest frame.
+ RotBstMatrix Mmove;
+ Vec4 p0cm = p0;
+ Vec4 p1cm = p1;
+ Vec4 p2cm = p2;
+ Mmove.bstback(pSumJun);
+ p0cm.rotbst(Mmove);
+ p1cm.rotbst(Mmove);
+ p2cm.rotbst(Mmove);
+
+ // Construct difference vectors and the boost to junction rest frame.
+ Vec4 pDir01 = p0cm / p0cm.e() - p1cm / p1cm.e();
+ Vec4 pDir02 = p0cm / p0cm.e() - p2cm / p2cm.e();
+ double pDiff01 = pDir01.pAbs2();
+ double pDiff02 = pDir02.pAbs2();
+ double pDiff0102 = dot3(pDir01, pDir02);
+ double eDiff01 = eNew[0] / p0cm.e() - eNew[1] / p1cm.e();
+ double eDiff02 = eNew[0] / p0cm.e() - eNew[2] / p2cm.e();
+ double denom = pDiff01 * pDiff02 - pDiff0102*pDiff0102;
+ double coef01 = (eDiff01 * pDiff02 - eDiff02 * pDiff0102) / denom;
+ double coef02 = (eDiff02 * pDiff01 - eDiff01 * pDiff0102) / denom;
+ Vec4 vJunction = coef01 * pDir01 + coef02 * pDir02;
+ vJunction.e( sqrt(1. + vJunction.pAbs2()) );
+
+ // Add two boosts, giving final result.
+ Mmove.bst(vJunction);
+ return Mmove;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// SusyLesHouches.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Peter Skands, Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+#include "SusyLesHouches.h"
+
+
+//*********
+
+// Main routine to read in SLHA and LHEF+SLHA files
+
+int SusyLesHouches::readFile(string slhaFile) {
+
+ // Check that input file is OK.
+ int iFailFile=0;
+ spectrumFile=slhaFile;
+ const char* cstring = slhaFile.c_str();
+ ifstream file(cstring);
+ if (!file) {
+ message(2,"readFile","SLHA file "+slhaFile+" not found",0);
+ return -1;
+ slhaRead=false;
+ }
+
+ //Print header if not already done
+ if (! headerPrinted) printHeader();
+
+ if (verbose >= 2) message(0,"readFile","parsing "+slhaFile,0);
+
+ //Initial values for read-in variables.
+ slhaRead=true;
+ lhefRead=false;
+ lhefSlha=false;
+ string line="";
+ string blockIn="";
+ string decay="";
+ string comment="";
+ string blockName="";
+ string pdgName="";
+ int pdgCode=0;
+ double width=0.0;
+
+ //Initialize line counter
+ int iLine=0;
+
+ // Read in one line at a time.
+ while ( getline(file, line) ) {
+ iLine++;
+
+ //Rewrite string in lowercase
+ for (unsigned int i=0;i<line.length();i++) line[i]=tolower(line[i]);
+
+ //Detect whether read-in is from a Les Houches Event File (LHEF).
+ if (line.find("<leshouches") != string::npos
+ || line.find("<slha") != string::npos) {
+ lhefRead=true;
+ }
+ if (lhefRead) {
+ //If LHEF, detect when <slha> tag reached.
+ if (line.find("<slha")) lhefSlha=true;
+ //If LHEF but <slha> tag not yet reached, skip
+ if (lhefRead && ! lhefSlha) continue;
+ }
+
+ //Ignore comment lines with # as first character
+ if (line.find("#") == 0) continue;
+
+ //Move comment to separate string
+ if (line.find("#") != string::npos) {
+ comment=line.substr(line.find("#")+1,line.length()-line.find("#")-1);
+ line.erase(line.find("#"),line.length()-line.find("#"));
+ }
+
+ // Remove extra blanks, also remove before and after an = sign.
+ while (line.find(" ") != string::npos) line.erase( line.find(" "), 1);
+ while (line.find(" =") != string::npos) line.erase( line.find(" ="), 1);
+ while (line.find("= ") != string::npos) line.erase( line.find("= ")+1, 1);
+
+ //New block.
+ if (line.find("block") <= 1) {
+ blockIn=line ;
+ decay="";
+ int nameBegin=6 ;
+ int nameEnd=blockIn.find(" ",7);
+ blockName=line.substr(nameBegin,nameEnd-nameBegin);
+
+ //Find Q=... for DRbar running blocks
+ if (blockIn.find("q=") != string::npos) {
+ int qbegin=blockIn.find("q=")+2;
+ istringstream qstream(blockIn.substr(qbegin,blockIn.length()));
+ double q=0.0;
+ qstream >> q;
+ if (qstream) {
+ // SLHA1 running blocks
+ if (blockName=="hmix") hmix.setq(q);
+ if (blockName=="yu") yu.setq(q);
+ if (blockName=="yd") yd.setq(q);
+ if (blockName=="ye") ye.setq(q);
+ if (blockName=="au") au.setq(q);
+ if (blockName=="ad") ad.setq(q);
+ if (blockName=="ae") ae.setq(q);
+ if (blockName=="msoft") msoft.setq(q);
+ if (blockName=="gauge") gauge.setq(q);
+ // SLHA2 running blocks
+ if (blockName=="vckm") vckm.setq(q);
+ if (blockName=="upmns") upmns.setq(q);
+ if (blockName=="msq2") msq2.setq(q);
+ if (blockName=="msu2") msu2.setq(q);
+ if (blockName=="msd2") msd2.setq(q);
+ if (blockName=="msl2") msl2.setq(q);
+ if (blockName=="mse2") mse2.setq(q);
+ if (blockName=="tu") tu.setq(q);
+ if (blockName=="td") td.setq(q);
+ if (blockName=="te") te.setq(q);
+ if (blockName=="rvlamlle") rvlamlle.setq(q);
+ if (blockName=="rvlamlqd") rvlamlqd.setq(q);
+ if (blockName=="rvlamudd") rvlamudd.setq(q);
+ if (blockName=="rvtlle") rvtlle.setq(q);
+ if (blockName=="rvtlqd") rvtlqd.setq(q);
+ if (blockName=="rvtudd") rvtudd.setq(q);
+ if (blockName=="rvkappa") rvkappa.setq(q);
+ if (blockName=="rvd") rvd.setq(q);
+ if (blockName=="rvm2lh1") rvm2lh1.setq(q);
+ if (blockName=="rvsnvev") rvsnvev.setq(q);
+ if (blockName=="imau") imau.setq(q);
+ if (blockName=="imad") imad.setq(q);
+ if (blockName=="imae") imae.setq(q);
+ if (blockName=="imtu") imtu.setq(q);
+ if (blockName=="imtd") imtd.setq(q);
+ if (blockName=="imte") imte.setq(q);
+ if (blockName=="imvckm") imvckm.setq(q);
+ if (blockName=="imupmns") imupmns.setq(q);
+ if (blockName=="immsq2") immsq2.setq(q);
+ if (blockName=="immsu2") immsu2.setq(q);
+ if (blockName=="immsd2") immsd2.setq(q);
+ if (blockName=="immsl2") immsl2.setq(q);
+ if (blockName=="immse2") immse2.setq(q);
+ };
+ };
+
+ //Skip to next line.
+ continue ;
+
+ }
+
+ //New decay table
+ else if (line.find("decay") <= 1) {
+
+ //Set decay block name
+ decay=line;
+ blockIn="";
+ int nameBegin=6 ;
+ int nameEnd=decay.find(" ",7);
+ pdgName=decay.substr(nameBegin,nameEnd-nameBegin);
+
+ //Extract PDG code and width
+ istringstream dstream(pdgName);
+ dstream >> pdgCode;
+ if (dstream) {
+ string widthName=decay.substr(nameEnd+1,decay.length());
+ istringstream wstream(widthName);
+ wstream >> width;
+ if (wstream) {
+ //Set PDG code and width
+ if (width <= 0.0) {
+ message(0,"readFile","skipping stable particle "+pdgName,0);
+ width=0.0;
+ decay="";
+ } else {
+ message(0,"readFile","skipping DECAY table for "+pdgName,0);
+ }
+ } else {
+ message(2,"readFile","WIDTH unreadable for "+pdgName,iLine);
+ message(0,"readFile","skipping stable particle "+pdgName,0);
+ width=0.0;
+ decay="";
+ continue;
+ }
+ }
+ else {
+ message(2,"readFile","PDG Code unreadable. Ignoring this DECAY block",iLine);
+ decay="";
+ continue;
+ }
+
+ //Read in PDG code and width
+ //...
+ //Set stable if width = 0d0
+ //...
+ //don't read in decay channels if width=0.0
+ //if (width <= 0.0) decay="";
+
+ //Skip to next line
+ continue ;
+ }
+
+ //Switch off SLHA read-in via LHEF if outside <slha> tag.
+ else if (line.find("</slha>") != string::npos) {
+ lhefSlha=false;
+ blockIn="";
+ decay="";
+ continue;
+ }
+
+ //End of SLHA read-in (via LHEF)
+ else if (line.find("</header>") != string::npos ||
+ line.find("<init") != string::npos) {
+ break;
+ }
+
+ //Skip not currently reading block data lines.
+ if (blockIn != "") {
+
+ // Replace an equal sign by a blank to make parsing simpler.
+ while (line.find("=") != string::npos) {
+ int firstEqual = line.find_first_of("=");
+ line.replace(firstEqual, 1, " ");
+ };
+
+ //Parse data lines within given block
+ //Constructed explicitly so that each block can have its own types and
+ //own rules defined. For extra user blocks, just add more recognized
+ //blockNames at the end and implement user defined rules accordingly.
+ //string comment = line.substr(line.find("#"),line.length());
+ int ifail=-2;
+ istringstream linestream(line);
+ //MODEL
+ if (blockName == "modsel") {
+ int i;
+ linestream >> i;
+ if (linestream) {
+ if (i == 12) {ifail=modsel12.set(0,linestream);}
+ else if (i == 21) {ifail=modsel21.set(0,linestream);}
+ else {ifail=modsel.set(i,linestream);};}
+ else {
+ ifail = -1;}
+ };
+ if (blockName == "minpar") ifail=minpar.set(linestream);
+ if (blockName == "sminputs") ifail=sminputs.set(linestream);
+ if (blockName == "extpar") ifail=extpar.set(linestream);
+ if (blockName == "qextpar") ifail=qextpar.set(linestream);
+ //FLV
+ if (blockName == "vckmin") ifail=vckmin.set(linestream);
+ if (blockName == "upmnsin") ifail=upmnsin.set(linestream);
+ if (blockName == "msq2in") ifail=msq2in.set(linestream);
+ if (blockName == "msu2in") ifail=msu2in.set(linestream);
+ if (blockName == "msd2in") ifail=msd2in.set(linestream);
+ if (blockName == "msl2in") ifail=msl2in.set(linestream);
+ if (blockName == "mse2in") ifail=mse2in.set(linestream);
+ if (blockName == "tuin") ifail=tuin.set(linestream);
+ if (blockName == "tdin") ifail=tdin.set(linestream);
+ if (blockName == "tein") ifail=tein.set(linestream);
+ //RPV
+ if (blockName == "rvlamllein") ifail=rvlamllein.set(linestream);
+ if (blockName == "rvlamlqdin") ifail=rvlamlqdin.set(linestream);
+ if (blockName == "rvlamuddin") ifail=rvlamuddin.set(linestream);
+ if (blockName == "rvtllein") ifail=rvtllein.set(linestream);
+ if (blockName == "rvtlqdin") ifail=rvtlqdin.set(linestream);
+ if (blockName == "rvtuddin") ifail=rvtuddin.set(linestream);
+ if (blockName == "rvkappain") ifail=rvkappain.set(linestream);
+ if (blockName == "rvdin") ifail=rvdin.set(linestream);
+ if (blockName == "rvm2lh1in") ifail=rvm2lh1in.set(linestream);
+ if (blockName == "rvsnvevin") ifail=rvsnvevin.set(linestream);
+ //CPV
+ if (blockName == "imminpar") ifail=imminpar.set(linestream);
+ if (blockName == "imextpar") ifail=imextpar.set(linestream);
+ //CPV +FLV
+ if (blockName == "immsq2in") ifail=immsq2in.set(linestream);
+ if (blockName == "immsu2in") ifail=immsu2in.set(linestream);
+ if (blockName == "immsd2in") ifail=immsd2in.set(linestream);
+ if (blockName == "immsl2in") ifail=immsl2in.set(linestream);
+ if (blockName == "immse2in") ifail=immse2in.set(linestream);
+ if (blockName == "imtuin") ifail=imtuin.set(linestream);
+ if (blockName == "imtdin") ifail=imtdin.set(linestream);
+ if (blockName == "imtein") ifail=imtein.set(linestream);
+ //Info:
+ if (blockName == "spinfo" || blockName=="dcinfo") {
+ int i;
+ string entry;
+ linestream >> i >> entry;
+ string blockStr="RGE";
+ if (blockName=="dcinfo") blockStr="DCY";
+
+ if (linestream) {
+ if ( i == 3 ) {
+ string warning=line.substr(line.find("3")+1,line.length());
+ message(1,"readFile","(from "+blockStr+" program): "+warning,0);
+ if (blockName == "spinfo") spinfo3.set(warning);
+ else dcinfo3.set(warning);
+ } else if ( i == 4 ) {
+ string error=line.substr(line.find("4")+1,line.length());
+ message(2,"readFile","(from "+blockStr+" program): "+error,0);
+ if (blockName == "spinfo") spinfo4.set(error);
+ else dcinfo4.set(error);
+ } else {
+ //Rewrite string in uppercase
+ for (unsigned int j=0;j<entry.length();j++)
+ entry[j]=toupper(entry[j]);
+ ifail=(blockName=="spinfo") ? spinfo.set(i,entry)
+ : dcinfo.set(i,entry);
+ };
+ } else {
+ ifail=-1;
+ };
+ };
+ //SPECTRUM
+ //Pole masses
+ if (blockName == "mass") ifail=mass.set(linestream);
+
+ //Mixing
+ if (blockName == "alpha") ifail=alpha.set(linestream);
+ if (blockName == "stopmix") ifail=stopmix.set(linestream);
+ if (blockName == "sbotmix") ifail=sbotmix.set(linestream);
+ if (blockName == "staumix") ifail=staumix.set(linestream);
+ if (blockName == "nmix") ifail=nmix.set(linestream);
+ if (blockName == "umix") ifail=umix.set(linestream);
+ if (blockName == "vmix") ifail=vmix.set(linestream);
+ //FLV
+ if (blockName == "usqmix") ifail=usqmix.set(linestream);
+ if (blockName == "dsqmix") ifail=dsqmix.set(linestream);
+ if (blockName == "selmix") ifail=selmix.set(linestream);
+ if (blockName == "snumix") ifail=snumix.set(linestream);
+ if (blockName == "snsmix") ifail=snsmix.set(linestream);
+ if (blockName == "snamix") ifail=snamix.set(linestream);
+ //RPV
+ if (blockName == "rvnmix") ifail=rvnmix.set(linestream);
+ if (blockName == "rvumix") ifail=rvumix.set(linestream);
+ if (blockName == "rvvmix") ifail=rvvmix.set(linestream);
+ if (blockName == "rvhmix") ifail=rvhmix.set(linestream);
+ if (blockName == "rvamix") ifail=rvamix.set(linestream);
+ if (blockName == "rvlmix") ifail=rvlmix.set(linestream);
+ //CPV
+ if (blockName == "cvhmix") ifail=cvhmix.set(linestream);
+ if (blockName == "imcvhmix") ifail=imcvhmix.set(linestream);
+ //CPV + FLV
+ if (blockName == "imusqmix") ifail=imusqmix.set(linestream);
+ if (blockName == "imdsqmix") ifail=imdsqmix.set(linestream);
+ if (blockName == "imselmix") ifail=imselmix.set(linestream);
+ if (blockName == "imsnumix") ifail=imsnumix.set(linestream);
+ if (blockName == "imnmix") ifail=imnmix.set(linestream);
+ if (blockName == "imumix") ifail=imumix.set(linestream);
+ if (blockName == "imvmix") ifail=imvmix.set(linestream);
+ //NMSSM
+ if (blockName == "nmhmix") ifail=nmhmix.set(linestream);
+ if (blockName == "nmamix") ifail=nmamix.set(linestream);
+ if (blockName == "nmnmix") ifail=nmnmix.set(linestream);
+
+ //DRbar Lagrangian parameters
+ if (blockName == "gauge") ifail=gauge.set(linestream);
+ if (blockName == "yu") ifail=yu.set(linestream);
+ if (blockName == "yd") ifail=yd.set(linestream);
+ if (blockName == "ye") ifail=ye.set(linestream);
+ if (blockName == "au") ifail=au.set(linestream);
+ if (blockName == "ad") ifail=ad.set(linestream);
+ if (blockName == "ae") ifail=ae.set(linestream);
+ if (blockName == "hmix") ifail=hmix.set(linestream);
+ if (blockName == "msoft") ifail=msoft.set(linestream);
+ //FLV
+ if (blockName == "vckm") ifail=vckm.set(linestream);
+ if (blockName == "upmns") ifail=upmns.set(linestream);
+ if (blockName == "msq2") ifail=msq2.set(linestream);
+ if (blockName == "msu2") ifail=msu2.set(linestream);
+ if (blockName == "msd2") ifail=msd2.set(linestream);
+ if (blockName == "msl2") ifail=msl2.set(linestream);
+ if (blockName == "mse2") ifail=mse2.set(linestream);
+ if (blockName == "tu") ifail=tu.set(linestream);
+ if (blockName == "td") ifail=td.set(linestream);
+ if (blockName == "te") ifail=te.set(linestream);
+ //RPV
+ if (blockName == "rvlamlle") ifail=rvlamlle.set(linestream);
+ if (blockName == "rvlamlqd") ifail=rvlamlqd.set(linestream);
+ if (blockName == "rvlamudd") ifail=rvlamudd.set(linestream);
+ if (blockName == "rvtlle") ifail=rvtlle.set(linestream);
+ if (blockName == "rvtlqd") ifail=rvtlqd.set(linestream);
+ if (blockName == "rvtudd") ifail=rvtudd.set(linestream);
+ if (blockName == "rvkappa") ifail=rvkappa.set(linestream);
+ if (blockName == "rvd") ifail=rvd.set(linestream);
+ if (blockName == "rvm2lh1") ifail=rvm2lh1.set(linestream);
+ if (blockName == "rvsnvev") ifail=rvsnvev.set(linestream);
+ //CPV
+ if (blockName == "imau") ifail=imau.set(linestream);
+ if (blockName == "imad") ifail=imad.set(linestream);
+ if (blockName == "imae") ifail=imae.set(linestream);
+ //CPV+FLV
+ if (blockName == "imvckm") ifail=imvckm.set(linestream);
+ if (blockName == "imupmns") ifail=imupmns.set(linestream);
+ if (blockName == "immsq2") ifail=immsq2.set(linestream);
+ if (blockName == "immsu2") ifail=immsu2.set(linestream);
+ if (blockName == "immsd2") ifail=immsd2.set(linestream);
+ if (blockName == "immsl2") ifail=immsl2.set(linestream);
+ if (blockName == "immse2") ifail=immse2.set(linestream);
+ if (blockName == "imtu") ifail=imtu.set(linestream);
+ if (blockName == "imtd") ifail=imtd.set(linestream);
+ if (blockName == "imte") ifail=imte.set(linestream);
+ //NMSSM
+ if (blockName == "nmssmrun") ifail=nmssmrun.set(linestream);
+
+ //Diagnostics
+ if (ifail != 0) {
+ if (ifail == -2) {
+ message(1,"readFile","Ignoring unknown block: "+blockName,iLine);
+ blockIn="";
+ };
+ if (ifail == -1) {
+ message(2,"readFile","Error on line.",iLine);
+ };
+ if (ifail == 1) {
+ message(0,"readFile",blockName+" existing entry overwritten.",iLine);
+ };
+ };
+
+ }
+
+ // Decay table read-in
+ // Not yet implemented
+ else if (decay != "") {
+ // cout << " found decay mode "<<line<<endl;
+ }
+ };
+
+ //Print footer
+ printFooter();
+
+ //Return 0 if read-in successful
+ return iFailFile;
+
+}
+
+//*********
+
+// Print a header with information on version, last date of change, etc.
+
+void SusyLesHouches::printHeader() {
+ setprecision(3);
+ if (! headerPrinted) {
+ cout <<" *-------------------- SusyLesHouches v0.03 SUSY/BSM Interface ---------------------*\n";
+ message(0,"","Last Change 06 Mar 2008 - P.Z. Skands",0);
+ headerPrinted=true;
+ }
+}
+
+//*********
+
+// Print a footer
+
+void SusyLesHouches::printFooter() {
+ if (! footerPrinted) {
+ // cout << " *"<<endl;
+ cout <<" *------------------------------------------------------------------------------------*\n";
+ footerPrinted=true;
+ // headerPrinted=false;
+ }
+}
+
+//*********
+
+// Print the current spectrum on stdout.
+// Not yet fully implemented.
+
+void SusyLesHouches::printSpectrum() {
+ // Print header if not already done
+ if (! headerPrinted) printHeader();
+ message(0,"","");
+
+ // Print Calculator and File name
+ if (slhaRead) {
+ message(0,""," Spectrum Calculator was: "+spinfo(1)+" version "+spinfo(2));
+ if (lhefRead) message(0,""," Read <slha> spectrum from: "+spectrumFile);
+ else message(0,""," Read SLHA spectrum from: "+spectrumFile);
+ }
+
+ // gluino
+ message(0,"","");
+ cout<<" | ~g m"<<endl;
+ cout<<setprecision(3)<<" | 1000021 "<<setw(10)<<
+ ( (mass(2000003) > 1e7) ? scientific : fixed)<<mass(1000021)<<endl;
+
+ // d squarks
+ message(0,"","");
+ cout<<" | ~d m ~dL ~sL ~bL ~dR ~sR ~bR"<<endl;
+
+ cout<<setprecision(3) <<" | 1000001 "<<setw(10)<<
+ ( (mass(1000001) > 1e7) ? scientific : fixed)<<mass(1000001)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<dsqmix(1,icur)<<" ";
+
+ cout<<endl<<" | 1000003 "<<setw(10)<<
+ ( (mass(1000003) > 1e7) ? scientific : fixed)<<mass(1000003)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<dsqmix(2,icur)<<" ";
+
+ cout<<endl<<" | 1000005 "<<setw(10)<<
+ ( (mass(1000005) > 1e7) ? scientific : fixed)<<mass(1000005)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<dsqmix(3,icur)<<" ";
+
+ cout<<endl<<" | 2000001 "<<setw(10)<<
+ ( (mass(2000001) > 1e7) ? scientific : fixed)<<mass(2000001)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<dsqmix(4,icur)<<" ";
+
+ cout<<endl<<" | 2000003 "<<setw(10)<<
+ ( (mass(2000003) > 1e7) ? scientific : fixed)<<mass(2000003)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<dsqmix(5,icur)<<" ";
+
+ cout<<endl<<" | 2000005 "<<setw(10)<<
+ ( (mass(2000005) > 1e7) ? scientific : fixed)<<mass(2000005)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<dsqmix(6,icur)<<" ";
+
+ cout<<endl;
+
+ // u squarks
+ message(0,"","");
+ cout<<" | ~u m ~uL ~cL ~tL ~uR ~cR ~tR"<<endl;
+
+ cout<<setprecision(3)<<" | 1000002 "<<setw(10)<<
+ ( (mass(1000002) > 1e7) ? scientific : fixed)<<mass(1000002)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<usqmix(1,icur)<<" ";
+
+ cout<<endl<<" | 1000004 "<<setw(10)<<
+ ( (mass(1000004) > 1e7) ? scientific : fixed)<<mass(1000004)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<usqmix(2,icur)<<" ";
+
+ cout<<endl<<" | 1000006 "<<setw(10)<<
+ ( (mass(1000006) > 1e7) ? scientific : fixed)<<mass(1000006)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<usqmix(3,icur)<<" ";
+
+ cout<<endl<<" | 2000002 "<<setw(10)<<
+ ( (mass(2000002) > 1e7) ? scientific : fixed)<<mass(2000002)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<usqmix(4,icur)<<" ";
+
+ cout<<endl<<" | 2000004 "<<setw(10)<<
+ ( (mass(2000004) > 1e7) ? scientific : fixed)<<mass(2000004)<<fixed<<" " ;
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<usqmix(5,icur)<<" ";
+
+ cout<<endl<<" | 2000006 "<<setw(10)<<
+ ( (mass(2000006) > 1e7) ? scientific : fixed)<<mass(2000006)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<usqmix(6,icur)<<" ";
+
+ cout<<endl;
+
+ // sleptons
+ // (NB: should be an if/then/else for RPV case here)
+ message(0,"","");
+ cout<<" | ~e m ~eL ~muL ~tauL ~eR ~muR ~tauR"<<endl;
+
+ cout<<setprecision(3)<<" | 1000011 "<<setw(10)<<
+ ( (mass(1000011) > 1e7) ? scientific : fixed)<<mass(1000011)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<selmix(1,icur)<<" ";
+
+ cout<<endl<<" | 1000013 "<<setw(10)<<
+ ( (mass(1000013) > 1e7) ? scientific : fixed)<<mass(1000013)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<selmix(2,icur)<<" ";
+
+ cout<<endl<<" | 1000015 "<<setw(10)<<
+ ( (mass(1000015) > 1e7) ? scientific : fixed)<<mass(1000015)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<selmix(3,icur)<<" ";
+
+ cout<<endl<<" | 2000011 "<<setw(10)<<
+ ( (mass(2000011) > 1e7) ? scientific : fixed)<<mass(2000011)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<selmix(4,icur)<<" ";
+
+ cout<<endl<<" | 2000013 "<<setw(10)<<
+ ( (mass(2000013) > 1e7) ? scientific : fixed)<<mass(2000013)<<fixed<<" " ;
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<selmix(5,icur)<<" ";
+
+ cout<<endl<<" | 2000015 "<<setw(10)<<
+ ( (mass(2000015) > 1e7) ? scientific : fixed)<<mass(2000015)<<fixed<<" ";
+ for (int icur=1;icur<=6;icur++) cout<<setw(6)<<selmix(6,icur)<<" ";
+
+ cout<<endl;
+
+ // sneutrinos
+ // (NB: should be an if/then/else for RPV case here)
+ message(0,"","");
+ cout<<" | ~nu m";
+ if (snumix.exists()) cout<<" ~nu_e ~nu_mu ~nu_tau";
+ cout<<endl;
+
+ cout<<setprecision(3)<<" | 1000012 "<<setw(10)<<
+ ( (mass(1000012) > 1e7) ? scientific : fixed)<<mass(1000012)<<fixed<<" ";
+ if (snumix.exists()) for (int icur=1;icur<=3;icur++)
+ cout<<setw(6)<<snumix(1,icur)<<" ";
+
+ cout<<endl<<" | 1000014 "<<setw(10)<<
+ ( (mass(1000014) > 1e7) ? scientific : fixed)<<mass(1000014)<<fixed<<" ";
+ if (snumix.exists()) for (int icur=1;icur<=3;icur++)
+ cout<<setw(6)<<snumix(2,icur)<<" ";
+
+ cout<<endl<<" | 1000016 "<<setw(10)<<
+ ( (mass(1000016) > 1e7) ? scientific : fixed)<<mass(1000016)<<fixed<<" ";
+ if (snumix.exists()) for (int icur=1;icur<=3;icur++)
+ cout<<setw(6)<<snumix(3,icur)<<" ";
+
+ cout<<endl;
+
+ // neutralinos
+ // (NB: should be an if/then/else for RPV case here)
+ message(0,"","");
+ cout<<" | ~chi0 m ~B ~W_3 ~H_1 ~H_2"<<endl;
+
+ cout<<setprecision(3)<<" | 1000022 "<<setw(10)<<
+ ( (mass(1000022) > 1e7) ? scientific : fixed)<<mass(1000022)<<fixed<<" ";
+ for (int icur=1;icur<=4;icur++) cout<<setw(6)<<nmix(1,icur)<<" ";
+
+ cout<<endl<<" | 1000023 "<<setw(10)<<
+ ( (mass(1000023) > 1e7) ? scientific : fixed)<<mass(1000023)<<fixed<<" ";
+ for (int icur=1;icur<=4;icur++) cout<<setw(6)<<nmix(2,icur)<<" ";
+
+ cout<<endl<<" | 1000025 "<<setw(10)<<
+ ( (mass(1000025) > 1e7) ? scientific : fixed)<<mass(1000025)<<fixed<<" ";
+ for (int icur=1;icur<=4;icur++) cout<<setw(6)<<nmix(3,icur)<<" ";
+
+ cout<<endl<<" | 1000035 "<<setw(10)<<
+ ( (mass(1000035) > 1e7) ? scientific : fixed)<<mass(1000035)<<fixed<<" ";
+ for (int icur=1;icur<=4;icur++) cout<<setw(6)<<nmix(4,icur)<<" ";
+
+ cout<<endl;
+
+ // charginos
+ // (NB: should be an if/then/else for RPV case here)
+ message(0,"","");
+ cout<<" | ~chi+ m U: ~W ~H | V: ~W ~H"
+ <<endl;
+
+ cout<<setprecision(3)<<" | 1000024 "<<setw(10)<<
+ ((mass(1000024) > 1e7) ? scientific : fixed)<<mass(1000024)<<fixed<<" ";
+ for (int icur=1;icur<=2;icur++) cout<<setw(6)<<umix(1,icur)<<" ";
+ cout<<"| ";
+ for (int icur=1;icur<=2;icur++) cout<<setw(6)<<vmix(1,icur)<<" ";
+
+ cout<<endl<<" | 1000037 "<<setw(10)<<
+ ((mass(1000037) > 1e7) ? scientific : fixed)<<mass(1000037)<<fixed<<" ";
+ for (int icur=1;icur<=2;icur++) cout<<setw(6)<<umix(2,icur)<<" ";
+ cout<<"| " ;
+ for (int icur=1;icur<=2;icur++) cout<<setw(6)<<vmix(2,icur)<<" ";
+
+ cout<<endl;
+
+ // Higgs bosons
+ // (NB: should be an if/then/else for RPV case here)
+ // ...
+
+ // Print footer
+ footerPrinted=false;
+ message(0,"","");
+ printFooter();
+}
+
+//*********
+
+// Check consistency of spectrum, unitarity of matrices, etc.
+
+int SusyLesHouches::checkSpectrum() {
+
+ if (! headerPrinted) printHeader();
+ int ifail=0;
+
+ //-----------------------------------------------------------------
+ //1) Check MODSEL. Assign default values where applicable.
+ if (!modsel.exists(1)) {
+ message(1,"checkSpectrum","MODSEL(1) undefined. Assuming =0.",0);
+ modsel.set(1,0);
+ ifail=max(ifail,1);
+ }
+ if (!modsel.exists(3)) modsel.set(3,0);
+ if (!modsel.exists(4)) modsel.set(4,0);
+ if (!modsel.exists(5)) modsel.set(5,0);
+ if (!modsel.exists(6)) modsel.set(6,0);
+ if (!modsel.exists(11)) modsel.set(11,1);
+
+ //-----------------------------------------------------------------
+ //2) Check for existence / duplication of blocks
+
+ //Global
+ if (!modsel.exists()) {
+ message(1,"checkSpectrum","MODSEL not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!minpar.exists()) {
+ message(1,"checkSpectrum","MINPAR not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!mass.exists()) {
+ message(1,"checkSpectrum","MASS not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!sminputs.exists()) {
+ message(1,"checkSpectrum","SMINPUTS not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!gauge.exists()) {
+ message(1,"checkSpectrum","GAUGE not found",0);
+ ifail=max(ifail,1);
+ }
+
+ //SLHA1
+ if (modsel(3) == 0 && modsel(4) == 0 && modsel(5) == 0 && modsel(6) == 0) {
+ // Check for required SLHA1 blocks
+ if (!staumix.exists()) {
+ message(1,"checkSpectrum","STAUMIX not found",0);
+ ifail=max(ifail,1);
+ };
+ if (!sbotmix.exists()) {
+ message(1,"checkSpectrum","SBOTMIX not found",0);
+ ifail=max(ifail,1);
+ };
+ if (!stopmix.exists()) {
+ message(1,"checkSpectrum","STOPMIX not found",0);
+ ifail=max(ifail,1);
+ };
+ if (!nmix.exists()) {
+ message(1,"checkSpectrum","NMIX not found",0);
+ ifail=max(ifail,1);
+ };
+ if (!umix.exists()) {
+ message(1,"checkSpectrum","UMIX not found",0);
+ ifail=max(ifail,1);
+ };
+ if (!vmix.exists()) {
+ message(1,"checkSpectrum","VMIX not found",0);
+ ifail=max(ifail,1);
+ };
+ if (!alpha.exists()) {
+ message(1,"checkSpectrum","ALPHA not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!hmix.exists()) {
+ message(1,"checkSpectrum","HMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!msoft.exists()) {
+ message(1,"checkSpectrum","MSOFT not found",0);
+ ifail=max(ifail,1);
+ }
+ }
+
+ //RPV (+ FLV)
+ else if (modsel(4) != 0) {
+ // Check for required SLHA2 blocks
+ if (!rvnmix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but RVNMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!rvumix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but RVUMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!rvvmix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but RVVMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!rvhmix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but RVHMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!rvamix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but RVAMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!rvlmix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but RVLMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!usqmix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but USQMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!dsqmix.exists()) {
+ message(1,"checkSpectrum","MODSEL 4 != 0 but DSQMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ }
+
+ // FLV but not RPV (see above for FLV+RPV, below for FLV regardless of RPV)
+ else if (modsel(6) != 0) {
+ // Quark FLV
+ if (modsel(6) != 2) {
+ if (!usqmix.exists()) {
+ message(1,"checkSpectrum","quark FLV on but USQMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!dsqmix.exists()) {
+ message(1,"checkSpectrum","quark FLV on but DSQMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ }
+ // Lepton FLV
+ if (modsel(6) != 1) {
+ if (!upmns.exists()) {
+ message(1,"checkSpectrum","lepton FLV on but UPMNSIN not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!selmix.exists()) {
+ message(1,"checkSpectrum","lepton FLV on but SELMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!snumix.exists() && !snsmix.exists()) {
+ message(1,"checkSpectrum","lepton FLV on but SNUMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ }
+ }
+
+ // CPV
+ if (modsel(5) != 0) {
+ if (!cvhmix.exists()) {
+ message(1,"checkSpectrum","MODSEL 5 != 0 but CVHMIX not found",0);
+ ifail=max(ifail,1);
+ }
+ }
+
+ // FLV (regardless of whether RPV or not)
+ if (modsel(6) != 0) {
+ // Quark FLV
+ if (modsel(6) != 2) {
+ if (!vckmin.exists()) {
+ message(1,"checkSpectrum","quark FLV on but VCKMIN not found",0);
+ ifail=max(ifail,1);
+ }
+ if (!msq2in.exists()) {
+ message(0,"checkSpectrum","note: quark FLV on but MSQ2IN not found",0);
+ ifail=max(ifail,0);
+ }
+ if (!msu2in.exists()) {
+ message(0,"checkSpectrum","note: quark FLV on but MSU2IN not found",0);
+ ifail=max(ifail,0);
+ }
+ if (!msd2in.exists()) {
+ message(0,"checkSpectrum","note: quark FLV on but MSD2IN not found",0);
+ ifail=max(ifail,0);
+ }
+ if (!tuin.exists()) {
+ message(0,"checkSpectrum","note: quark FLV on but TUIN not found",0);
+ ifail=max(ifail,0);
+ }
+ if (!tdin.exists()) {
+ message(0,"checkSpectrum","note: quark FLV on but TDIN not found",0);
+ ifail=max(ifail,0);
+ }
+ }
+ // Lepton FLV
+ if (modsel(6) != 1) {
+ if (!msl2in.exists()) {
+ message(0,"checkSpectrum","note: lepton FLV on but MSL2IN not found",0);
+ ifail=max(ifail,0);
+ }
+ if (!mse2in.exists()) {
+ message(0,"checkSpectrum","note: lepton FLV on but MSE2IN not found",0);
+ ifail=max(ifail,0);
+ }
+ if (!tein.exists()) {
+ message(0,"checkSpectrum","note: lepton FLV on but TEIN not found",0);
+ ifail=max(ifail,0);
+ }
+ }
+ }
+
+ //-----------------------------------------------------------------
+ //3) SLHA1 --> SLHA2 interoperability
+ //Note: the mass basis is NOT mass-ordered in SLHA1, so be careful!
+ //Here, the mass basis is hence by PDG code, not by mass-ordered value.
+
+ if (stopmix.exists() && ! usqmix.exists() ) {
+ //1000002 = ~uL, 1000004 = ~cL, 2000002 = ~uR, 2000004 = ~cR
+ usqmix.set(1,1, 1.0);
+ usqmix.set(2,2, 1.0);
+ usqmix.set(4,4, 1.0);
+ usqmix.set(5,5, 1.0);
+ //Fill (1000006,2000006) sector from stopmix
+ usqmix.set(3,3, stopmix(1,1));
+ usqmix.set(3,6, stopmix(1,2));
+ usqmix.set(6,3, stopmix(2,1));
+ usqmix.set(6,6, stopmix(2,2));
+ };
+ if (sbotmix.exists() && ! dsqmix.exists() ) {
+ //1000001 = ~dL, 1000003 = ~sL, 2000001 = ~dR, 2000003 = ~sR
+ dsqmix.set(1,1, 1.0);
+ dsqmix.set(2,2, 1.0);
+ dsqmix.set(4,4, 1.0);
+ dsqmix.set(5,5, 1.0);
+ //Fill (1000005,2000005) sector from sbotmix
+ dsqmix.set(3,3, sbotmix(1,1));
+ dsqmix.set(3,6, sbotmix(1,2));
+ dsqmix.set(6,3, sbotmix(2,1));
+ dsqmix.set(6,6, sbotmix(2,2));
+ };
+ if (staumix.exists() && ! selmix.exists() ) {
+ //1000011 = ~eL, 1000013 = ~muL, 2000011 = ~eR, 2000013 = ~muR
+ selmix.set(1,1, 1.0);
+ selmix.set(2,2, 1.0);
+ selmix.set(4,4, 1.0);
+ selmix.set(5,5, 1.0);
+ //Fill (1000015,2000015) sector from staumix
+ selmix.set(3,3, staumix(1,1));
+ selmix.set(3,6, staumix(1,2));
+ selmix.set(6,3, staumix(2,1));
+ selmix.set(6,6, staumix(2,2));
+ };
+ if (! snumix.exists() && ! snsmix.exists()) {
+ //1000012 = ~nu_e, 1000014 = ~nu_mu, 1000016 = ~nu_tau
+ snumix.set(1,1, 1.0);
+ snumix.set(2,2, 1.0);
+ snumix.set(3,3, 1.0);
+ };
+
+ //-----------------------------------------------------------------
+ //4) Check unitarity/orthogonality of mixing matrices
+
+ //NMIX
+ if (nmix.exists()) {
+ for (int i=1;i<=4;i++) {
+ double cn1=0.0;
+ double cn2=0.0;
+ for (int j=1;j<=4;j++) {
+ cn1 += pow(nmix(i,j),2);
+ cn2 += pow(nmix(j,i),2);
+ }
+ if (abs(1.0-cn1) > 1e-3 || abs(1.0-cn2) > 1e-3) {
+ ifail=2;
+ message(2,"checkSpectrum","inconsistent normalization of NMIX",0);
+ }
+ }
+ }
+
+ //VMIX, UMIX
+ if (vmix.exists() && umix.exists()) {
+ for (int i=1;i<=2;i++) {
+ double cu1=0.0;
+ double cu2=0.0;
+ double cv1=0.0;
+ double cv2=0.0;
+ for (int j=1;j<=2;j++) {
+ cu1 += pow(umix(i,j),2);
+ cu2 += pow(umix(j,i),2);
+ cv1 += pow(vmix(i,j),2);
+ cv2 += pow(vmix(j,i),2);
+ }
+ if (abs(1.0-cu1) > 1e-3 || abs(1.0-cu2) > 1e-3) {
+ ifail=2;
+ message(2,"checkSpectrum","inconsistent normalization of UMIX",0);
+ }
+ if (abs(1.0-cv1) > 1e-3 || abs(1.0-cv2) > 1e-3) {
+ ifail=2;
+ message(2,"checkSpectrum","inconsistent normalization of VMIX",0);
+ }
+ }
+
+ }
+
+ //STOPMIX, SBOTMIX
+ if (stopmix.exists() && sbotmix.exists()) {
+ for (int i=1;i<=2;i++) {
+ double ct1=0.0;
+ double ct2=0.0;
+ double cb1=0.0;
+ double cb2=0.0;
+ for (int j=1;j<=2;j++) {
+ ct1 += pow(stopmix(i,j),2);
+ ct2 += pow(stopmix(j,i),2);
+ cb1 += pow(sbotmix(i,j),2);
+ cb2 += pow(sbotmix(j,i),2);
+ }
+ if (abs(1.0-ct1) > 1e-3 || abs(1.0-ct2) > 1e-3) {
+ ifail=2;
+ message(2,"checkSpectrum","inconsistent normalization of STOPMIX",0);
+ }
+ if (abs(1.0-cb1) > 1e-3 || abs(1.0-cb2) > 1e-3) {
+ ifail=2;
+ message(2,"checkSpectrum","inconsistent normalization of SBOTMIX",0);
+ }
+ }
+ }
+
+ //STAUMIX
+ if (staumix.exists()) {
+ for (int i=1;i<=2;i++) {
+ double ct1=0.0;
+ double ct2=0.0;
+ for (int j=1;j<=2;j++) {
+ ct1 += pow(staumix(i,j),2);
+ ct2 += pow(staumix(j,i),2);
+ }
+ if (abs(1.0-ct1) > 1e-3 || abs(1.0-ct2) > 1e-3) {
+ ifail=2;
+ message(2,"checkSpectrum","inconsistent normalization of STAUMIX",0);
+ }
+ }
+ }
+
+ //NMSSM:
+ if (modsel(3) == 1) {
+ //NMNMIX
+ if ( nmnmix.exists() ) {
+ for (int i=1;i<=5;i++) {
+ double cn1=0.0;
+ double cn2=0.0;
+ for (int j=1;j<=4;j++) {
+ cn1 += pow(nmnmix(i,j),2);
+ cn2 += pow(nmnmix(j,i),2);
+ }
+ if (abs(1.0-cn1) > 1e-3 || abs(1.0-cn2) > 1e-3) {
+ ifail=max(ifail,2);
+ message(2,"checkSpectrum","inconsistent normalization of NMNMIX",0);
+ }
+ }
+ }
+ else {
+ ifail=max(ifail,1);
+ message(1,"checkSpectrum","MODSEL 3 = 1 (NMSSM) but no NMNMIX found",0);
+ }
+ //NMAMIX
+ if ( nmamix.exists() ) {
+ for (int i=1;i<=2;i++) {
+ double cn1=0.0;
+ for (int j=1;j<=3;j++) {
+ cn1 += pow(nmamix(i,j),2);
+ }
+ if (abs(1.0-cn1) > 1e-3) {
+ ifail=max(ifail,2);
+ message(2,"checkSpectrum","inconsistent normalization of NMAMIX",0);
+ }
+ }
+ }
+ else {
+ ifail=max(ifail,1);
+ message(1,"checkSpectrum","MODSEL 3 = 1 (NMSSM) but no NMAMIX found",0);
+ }
+ //NMHMIX
+ if ( nmhmix.exists() ) {
+ for (int i=1;i<=3;i++) {
+ double cn1=0.0;
+ double cn2=0.0;
+ for (int j=1;j<=3;j++) {
+ cn1 += pow(nmhmix(i,j),2);
+ cn2 += pow(nmhmix(j,i),2);
+ }
+ if (abs(1.0-cn1) > 1e-3 || abs(1.0-cn2) > 1e-3) {
+ ifail=max(ifail,2);
+ message(2,"checkSpectrum","inconsistent normalization of NMHMIX",0);
+ }
+ }
+ }
+ else {
+ ifail=max(ifail,1);
+ message(1,"checkSpectrum","MODSEL 3 = 1 (NMSSM) but no NMHMIX found",0);
+ }
+ //NMSSMRUN
+ if (! nmssmrun.exists() ) {
+ ifail=max(ifail,1);
+ message(2,"checkSpectrum","MODSEL 3 = 1 (NMSSM) but no NMSSMRUN found",
+ 0);
+ }
+ }
+
+ //Check for documentation
+ if (slhaRead && ! spinfo.exists(1)) spinfo.set(1,"unknown");
+ if (slhaRead && ! spinfo.exists(2)) spinfo.set(2,"unknown");
+ if (! slhaRead && ! spinfo.exists(1)) {
+ spinfo.set(1,"DEFAULT");
+ spinfo.set(2,"n/a");
+ }
+
+ //Give status
+ if (ifail >= 2)
+ message(0,"checkSpectrum","one or more serious problems were found");
+
+ //Print Footer
+ printFooter();
+
+ //Return
+ return ifail;
+}
+
+//*********
+
+// Simple utility to print messages, warnings, and errors
+
+void SusyLesHouches::message(int level, string place,string themessage,int line) {
+ //Send normal messages and warnings to stdout, errors to stderr.
+ ostream* outstream = &cerr;
+ if (level <= 1) outstream = &cout;
+ // if (level == 2) { *outstream<<endl; }
+ if (place != "") *outstream << " | (SLHA::"+place+") ";
+ else *outstream << " | ";
+ if (level == 1) *outstream<< "warning: ";
+ if (level == 2) { *outstream <<"ERROR: "; }
+ if (line != 0) *outstream<< "line "<<line<<" - ";
+ *outstream << themessage << endl;
+ // if (level == 2) *outstream <<endl;
+ footerPrinted=false;
+ return;
+}
+
+
+
+
--- /dev/null
+// TimeShower.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the TimeShower class.
+
+#include "TimeShower.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The TimeShower class.
+
+//*********
+
+// Constants: could be changed here if desired, but normally should not.
+// These are of technical nature, as described for each.
+
+// For small x approximate 1 - sqrt(1 - x) by x/2.
+const double TimeShower::SIMPLIFYROOT = 1e-8;
+
+// Do not allow x too close to 0 or 1 in matrix element expressions.
+// Warning: cuts into phase space for E_CM > 2 * pTmin * sqrt(1/XMARGIN),
+// i.e. will become problem roughly for E_CM > 10^6 GeV.
+const double TimeShower::XMARGIN = 1e-12;
+const double TimeShower::XMARGINCOMB = 1e-4;
+
+// Lower limit on PDF value in order to avoid division by zero.
+const double TimeShower::TINYPDF = 1e-10;
+
+// Big starting value in search for smallest invariant-mass pair.
+const double TimeShower::LARGEM2 = 1e20;
+
+// In g -> q qbar or gamma -> f fbar require m2_pair > this * m2_q/f.
+const double TimeShower::THRESHM2 = 4.004;
+
+// Never pick pT so low that alphaS is evaluated too close to Lambda_3.
+const double TimeShower::LAMBDA3MARGIN = 1.1;
+
+//*********
+
+// Initialize alphaStrong, alphaEM and related pTmin parameters.
+
+void TimeShower::init( BeamParticle* beamAPtrIn,
+ BeamParticle* beamBPtrIn) {
+
+ // Store input pointers for future use.
+ beamAPtr = beamAPtrIn;
+ beamBPtr = beamBPtrIn;
+
+ // Main flags.
+ doQCDshower = Settings::flag("TimeShower:QCDshower");
+ doQEDshowerByQ = Settings::flag("TimeShower:QEDshowerByQ");
+ doQEDshowerByL = Settings::flag("TimeShower:QEDshowerByL");
+ doQEDshowerByGamma = Settings::flag("TimeShower:QEDshowerByGamma");
+ doMEcorrections = Settings::flag("TimeShower:MEcorrections");
+ doPhiPolAsym = Settings::flag("TimeShower:phiPolAsym");
+ allowBeamRecoil = Settings::flag("TimeShower:allowBeamRecoil");
+
+ // Matching in pT of hard interaction to shower evolution.
+ pTmaxFudge = Settings::parm("TimeShower:pTmaxFudge");
+
+ // Charm and bottom mass thresholds.
+ mc = ParticleDataTable::m0(4);
+ mb = ParticleDataTable::m0(5);
+ m2c = mc * mc;
+ m2b = mb * mb;
+
+ // Parameters of alphaStrong generation .
+ alphaSvalue = Settings::parm("TimeShower:alphaSvalue");
+ alphaSorder = Settings::mode("TimeShower:alphaSorder");
+ alphaS2pi = 0.5 * alphaSvalue / M_PI;
+
+ // Initialize alphaStrong generation.
+ alphaS.init( alphaSvalue, alphaSorder);
+
+ // Lambda for 5, 4 and 3 flavours.
+ Lambda3flav = alphaS.Lambda3();
+ Lambda4flav = alphaS.Lambda4();
+ Lambda5flav = alphaS.Lambda5();
+ Lambda5flav2 = pow2(Lambda5flav);
+ Lambda4flav2 = pow2(Lambda4flav);
+ Lambda3flav2 = pow2(Lambda3flav);
+
+ // Parameters of QCD evolution.
+ nGluonToQuark = Settings::mode("TimeShower:nGluonToQuark");
+ pTcolCutMin = Settings::parm("TimeShower:pTmin");
+ pTcolCut = max( pTcolCutMin, LAMBDA3MARGIN * Lambda3flav );
+ pT2colCut = pow2(pTcolCut);
+
+ // Parameters of alphaEM generation .
+ alphaEMorder = Settings::mode("TimeShower:alphaEMorder");
+
+ // Initialize alphaEM generation.
+ alphaEM.init( alphaEMorder);
+
+ // Parameters of QED evolution.
+ nGammaToQuark = Settings::mode("TimeShower:nGammaToQuark");
+ nGammaToLepton = Settings::mode("TimeShower:nGammaToLepton");
+ pTchgQCut = Settings::parm("TimeShower:pTminChgQ");
+ pT2chgQCut = pow2(pTchgQCut);
+ pTchgLCut = Settings::parm("TimeShower:pTminChgL");
+ pT2chgLCut = pow2(pTchgLCut);
+ mMaxGamma = Settings::parm("TimeShower:mMaxGamma");
+ m2MaxGamma = pow2(mMaxGamma);
+
+ // Consisteny check for gamma -> f fbar variables.
+ if (nGammaToQuark <= 0 && nGammaToLepton <= 0) doQEDshowerByGamma = false;
+
+ // Fraction and colorr factor of gluon emission off onium octat state.
+ octetOniumFraction = Settings::parm("TimeShower:octetOniumFraction");
+ octetOniumColFac = Settings::parm("TimeShower:octetOniumColFac");
+
+ // Z0 properties needed for gamma/Z0 mixing.
+ mZ = ParticleDataTable::m0(23);
+ gammaZ = ParticleDataTable::mWidth(23);
+ thetaWRat = 1. / (16. * CoupEW::sin2thetaW() * CoupEW::cos2thetaW());
+
+}
+
+//*********
+
+// Top-level routine to do a full time-like shower in resonance decay.
+
+int TimeShower::shower( int iBeg, int iEnd, Event& event, double pTmax) {
+
+ // Add new system, with two empty beam slots.
+ int iSys = event.newSystem();
+ event.addToSystem( iSys, 0);
+ event.addToSystem( iSys, 0);
+
+ // Loop over allowed range to find all final-state particles.
+ for (int i = iBeg; i <= iEnd; ++i)
+ if (event[i].isFinal()) event.addToSystem( iSys, i);
+
+ // Let prepare routine do the setup.
+ prepare( iSys, event);
+
+ // Begin evolution down in pT from hard pT scale.
+ int nBranch = 0;
+ do {
+ double pTtimes = pTnext( event, pTmax, 0.);
+
+ // Do a final-state emission (if allowed).
+ if (pTtimes > 0.) {
+ if (branch( event)) ++nBranch;
+ pTmax = pTtimes;
+ }
+
+ // Keep on evolving until nothing is left to be done.
+ else pTmax = 0.;
+ } while (pTmax > 0.);
+
+ // Return number of emissions that were performed.
+ return nBranch;
+
+}
+
+//*********
+
+// Prepare system for evolution; identify ME.
+
+void TimeShower::prepare( int iSys, Event& event) {
+
+ // Reset dipole-ends list for first interaction and for resonance decays.
+ if (iSys == 0 || event.getInSystem( iSys, 0) == 0) dipEnd.resize(0);
+ int dipEndSizeBeg = dipEnd.size();
+
+ // Loop through final state of system to find possible dipole ends.
+ for (int i = 2; i < event.sizeSystem( iSys); ++i) {
+ int iRad = event.getInSystem( iSys, i);
+ if (event[iRad].isFinal() && event[iRad].scale() > 0.) {
+
+ // Identify colour octet onium state. Check whether QCD shower allowed.
+ int idRad = event[iRad].id();
+ bool isOctetOnium
+ = ( idRad == 9900441 || idRad == 9900443 || idRad == 9910441
+ || idRad == 9900551 || idRad == 9900553 || idRad == 9910551 );
+ bool doQCD = doQCDshower;
+ if (doQCD && isOctetOnium) doQCD = (Rndm::flat() < octetOniumFraction);
+
+ // Find dipole end formed by colour index.
+ int colTag = event[iRad].col();
+ if (doQCD && colTag > 0)
+ setupQCDdip( iSys, i, colTag, 1, event, isOctetOnium);
+
+ // Find dipole end formed by anticolour index.
+ int acolTag = event[iRad].acol();
+ if (doQCD && acolTag > 0)
+ setupQCDdip( iSys, i, acolTag, -1, event, isOctetOnium);
+
+ // Find "charge-dipole" and "photon-dipole" ends.
+ int chgType = event[iRad].chargeType();
+ bool doChgDip = (chgType != 0)
+ && ( ( doQEDshowerByQ && event[iRad].isQuark() )
+ || ( doQEDshowerByL && event[iRad].isLepton() ) );
+ int gamType = (event[iRad].id() == 22) ? 1 : 0;
+ bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
+ if (doChgDip || doGamDip) setupQEDdip( iSys, i, chgType, gamType, event);
+
+ // End loop over system final state. Have now found the dipole ends.
+ }
+ }
+
+ // Loop through dipole ends to find matrix element corrections.
+ for (int iDip = dipEndSizeBeg; iDip < int(dipEnd.size()); ++iDip)
+ findMEtype( event, dipEnd[iDip]);
+
+}
+
+//*********
+
+// Update dipole list after each ISR emission (so not used for resonances).
+
+void TimeShower::update( int iSys, Event& event) {
+
+ // Find new and old positions of partons in the system.
+ vector<int> iNew, iOld;
+ int size = event.sizeSystem( iSys) - 1;
+ for (int i = 0; i < size; ++i) {
+ iNew.push_back( event.getInSystem( iSys, i) );
+ if (i < 2) iOld.push_back( event[iNew[i]].daughter2() );
+ else iOld.push_back( event[iNew[i]].mother1() );
+ }
+ int iNewNew = event.getInSystem( iSys, size);
+
+ // Swap beams to let 0 be side on which branching occured.
+ if (event[iNew[0]].status() != -41) {
+ swap( iNew[0], iNew[1]);
+ swap( iOld[0], iOld[1]);
+ }
+
+ // Loop over all dipole ends belonging to the system.
+ for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip)
+ if (dipEnd[iDip].system == iSys) {
+ TimeDipoleEnd& dipNow = dipEnd[iDip];
+
+ // Replace radiator (always in final state so simple).
+ for (int i = 2; i < size; ++i)
+ if (dipNow.iRadiator == iOld[i]) {
+ dipNow.iRadiator = iNew[i];
+ break;
+ }
+
+ // Replace ME partner (always in final state, if exists, so simple).
+ for (int i = 2; i < size; ++i)
+ if (dipNow.iMEpartner == iOld[i]) {
+ dipNow.iMEpartner = iNew[i];
+ break;
+ }
+
+ // Recoiler: by default pick old one, only moved. Note excluded beam.
+ int iRec = 0;
+ for (int i = 1; i < size; ++i)
+ if (dipNow.iRecoiler == iOld[i]) {
+ iRec = iNew[i];
+ break;
+ }
+
+ // QCD recoiler: check if colour hooks up with new final parton.
+ if ( dipNow.colType > 0
+ && event[dipNow.iRadiator].col() == event[iNewNew].acol() ) {
+ iRec = iNewNew;
+ dipNow.isrType = 0;
+ }
+ if ( dipNow.colType < 0
+ && event[dipNow.iRadiator].acol() == event[iNewNew].col() ) {
+ iRec = iNewNew;
+ dipNow.isrType = 0;
+ }
+
+ // QCD recoiler: check if colour hooks up with new beam parton.
+ if ( iRec == 0 && dipNow.colType > 0
+ && event[dipNow.iRadiator].col() == event[iNew[0]].col() )
+ iRec = iNew[0];
+ if ( iRec == 0 && dipNow.colType < 0
+ && event[dipNow.iRadiator].acol() == event[iNew[0]].acol() )
+ iRec = iNew[0];
+
+ // QED/photon recoiler: either to new particle or remains to beam.
+ if ( iRec == 0 && (dipNow.chgType != 0 || dipNow.gamType != 0) ) {
+ if ( event[iNew[0]].chargeType() == 0 ) {
+ iRec = iNewNew;
+ dipNow.isrType = 0;
+ } else {
+ iRec = iNew[0];
+ }
+ }
+
+ // Done. Kill dipole if failed to find new recoiler.
+ dipNow.iRecoiler = iRec;
+ if (iRec == 0) {
+ dipNow.colType = 0;
+ dipNow.chgType = 0;
+ dipNow.gamType = 0;
+ infoPtr->errorMsg("Error in TimeShower::update: "
+ "failed to locate new recoiling partner");
+ }
+ }
+
+ // Find new dipole end formed by colour index.
+ int colTag = event[iNewNew].col();
+ if (doQCDshower && colTag > 0) setupQCDdip( iSys, size, colTag, 1, event);
+
+ // Find new dipole end formed by anticolour index.
+ int acolTag = event[iNewNew].acol();
+ if (doQCDshower && acolTag > 0) setupQCDdip( iSys, size, acolTag, -1, event);
+
+ // Find new "charge-dipole" and "photon-dipole" ends.
+ int chgType = event[iNewNew].chargeType();
+ bool doChgDip = (chgType != 0)
+ && ( ( doQEDshowerByQ && event[iNewNew].isQuark() )
+ || ( doQEDshowerByL && event[iNewNew].isLepton() ) );
+ int gamType = (event[iNewNew].id() == 22) ? 1 : 0;
+ bool doGamDip = (gamType == 1) && doQEDshowerByGamma;
+ if (doChgDip || doGamDip) setupQEDdip( iSys, size, chgType, gamType, event);
+
+}
+
+//*********
+
+// Setup a dipole end for a QCD colour charge.
+
+void TimeShower::setupQCDdip( int iSys, int i, int colTag, int colSign,
+ Event& event, bool isOctetOnium) {
+
+ // Initial values. Find if allowed to hook up beams.
+ int iRad = event.getInSystem( iSys, i);
+ int iRec = 0;
+ int size = event.sizeSystem( iSys);
+ int jMin = ( allowBeamRecoil && (event.getInSystem( iSys, 0) > 0)
+ && (event.getInSystem( iSys, 1) > 0) ) ? 0 : 2;
+
+ // Colour: other end by same index in beam or opposite in final state.
+ if (colSign > 0)
+ for (int j = jMin; j < size; ++j) if (j != i) {
+ int iRecNow = event.getInSystem( iSys, j);
+ if ( (j < 2 && event[iRecNow].col() == colTag)
+ || (i > 1 && event[iRecNow].acol() == colTag) ) {
+ iRec = iRecNow;
+ break;
+ }
+ }
+
+ // Anticolour: other end by same index in beam or opposite in final state.
+ if (colSign < 0)
+ for (int j = jMin; j < size; ++j) if (j != i) {
+ int iRecNow = event.getInSystem( iSys, j);
+ if ( (j < 2 && event[iRecNow].acol() == colTag)
+ || (i > 1 && event[iRecNow].col() == colTag) ) {
+ iRec = iRecNow;
+ break;
+ }
+ }
+
+ // If fail, then other end to nearest recoiler in final state,
+ // by (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
+ if (iRec == 0) {
+ double ppMin = LARGEM2;
+ for (int j = 2; j < size; ++j) if (j != i) {
+ int iRecNow = event.getInSystem( iSys, j);
+ double ppNow = event[iRecNow].p() * event[iRad].p()
+ - event[iRecNow].m() * event[iRad].m();
+ if (ppNow < ppMin) {
+ iRec = iRecNow;
+ ppMin = ppNow;
+ }
+ }
+ }
+
+ // Store dipole colour end.
+ if (iRec > 0) {
+ double pTmax = event[iRad].scale();
+ if (iSys == 0) pTmax *= pTmaxFudge;
+ int colType = (event[iRad].id() == 21) ? 2 * colSign : colSign;
+ int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
+ dipEnd.push_back( TimeDipoleEnd( iRad, iRec, pTmax,
+ colType, 0, 0, isrType, iSys, -1, -1, isOctetOnium) );
+ }
+
+}
+
+//*********
+
+// Setup a dipole end for a QED colour charge or a photon.
+
+void TimeShower::setupQEDdip( int iSys, int i, int chgType, int gamType,
+ Event& event) {
+
+ // Initial values. Find if allowed to hook up beams.
+ int iRad = event.getInSystem( iSys, i);
+ int iRec = 0;
+ int size = event.sizeSystem( iSys);
+ int jMin = ( allowBeamRecoil && (event.getInSystem( iSys, 0) > 0)
+ && (event.getInSystem( iSys, 1) > 0) ) ? 0 : 2;
+
+ // Find nearest recoiler, charge-squared-weighted
+ // (p_i + p_j)^2 - (m_i + m_j)^2 = 2 (p_i p_j - m_i m_j).
+ double ppMin = LARGEM2;
+ for (int j = jMin; j < size; ++j) if (j != i) {
+ int iRecNow = event.getInSystem( iSys, j);
+ int chgTypeRecNow = event[iRecNow].chargeType();
+ if (chgTypeRecNow != 0) {
+ double ppNow = (event[iRecNow].p() * event[iRad].p()
+ - event[iRecNow].m() * event[iRad].m())
+ / pow2(chgTypeRecNow);
+ if (ppNow < ppMin) {
+ iRec = iRecNow;
+ ppMin = ppNow;
+ }
+ }
+ }
+
+ // If fail find any nearest recoiler in final state.
+ if (iRec == 0)
+ for (int j = 2; j < size; ++j) if (j != i) {
+ int iRecNow = event.getInSystem( iSys, j);
+ double ppNow = event[iRecNow].p() * event[iRad].p()
+ - event[iRecNow].m() * event[iRad].m();
+ if (ppNow < ppMin) {
+ iRec = iRecNow;
+ ppMin = ppNow;
+ }
+ }
+
+ // Fill charge-dipole or photon-dipole end.
+ if (iRec > 0) {
+ double pTmax = event[iRad].scale();
+ if (iSys == 0) pTmax *= pTmaxFudge;
+ int isrType = (event[iRec].isFinal()) ? 0 : event[iRec].mother1();
+ dipEnd.push_back( TimeDipoleEnd(iRad, iRec, pTmax,
+ 0, chgType, gamType, isrType, iSys, -1) );
+ }
+
+}
+
+//*********
+
+// Select next pT in downwards evolution of the existing dipoles.
+
+double TimeShower::pTnext( Event& event, double pTbegAll, double pTendAll) {
+
+ // Begin loop over all possible radiating dipole ends.
+ dipSel = 0;
+ double pT2sel = pTendAll * pTendAll;
+ for (int iDip = 0; iDip < int(dipEnd.size()); ++iDip) {
+ TimeDipoleEnd& dip = dipEnd[iDip];
+
+ // Dipole properties. (Could partly be moved up to prepare??)
+ dip.mRad = event[dip.iRadiator].m();
+ dip.m2Rad = pow2(dip.mRad);
+ dip.mRec = event[dip.iRecoiler].m();
+ dip.m2Rec = pow2(dip.mRec);
+ dip.mDip = m( event[dip.iRadiator], event[dip.iRecoiler] );
+ dip.m2Dip = pow2(dip.mDip);
+
+ // Find maximum evolution scale for dipole.
+ dip.m2DipCorr = pow2(dip.mDip - dip.mRec) - dip.m2Rad;
+ double pTbegDip = min( pTbegAll, dip.pTmax );
+ double pT2begDip = min( pow2(pTbegDip), 0.25 * dip.m2DipCorr);
+
+ // Do QCD or QED evolution if it makes sense.
+ dip.pT2 = 0.;
+ if (pT2begDip > pT2sel) {
+ if (dip.colType != 0)
+ pT2nextQCD(pT2begDip, pT2sel, dip, event);
+ else if (dip.chgType != 0 || dip.gamType != 0)
+ pT2nextQED(pT2begDip, pT2sel, dip, event);
+
+ // Update if found larger pT than current maximum.
+ if (dip.pT2 > pT2sel) {
+ pT2sel = dip.pT2;
+ dipSel = &dip;
+ }
+ }
+ }
+
+ // Return nonvanishing value if found pT bigger than already found.
+ return (dipSel == 0) ? 0. : sqrt(pT2sel);
+
+}
+
+//*********
+
+// Evolve a QCD dipole end.
+
+void TimeShower::pT2nextQCD(double pT2begDip, double pT2sel,
+ TimeDipoleEnd& dip, Event& event) {
+
+ // Lower cut for evolution. Return if no evolution range.
+ double pT2endDip = max( pT2sel, pT2colCut );
+ if (pT2begDip < pT2endDip) return;
+
+ // Upper estimate for matrix element weighting and colour factor.
+ // Special cases for triplet recoiling against gluino and octet onia.
+ // Note that g -> g g and g -> q qbar are split on two sides.
+ int colTypeAbs = abs(dip.colType);
+ double wtPSglue = 2.;
+ double colFac = (colTypeAbs == 1) ? 4./3. : 3./2.;
+ if (dip.MEgluinoRec) colFac = 3.;
+ if (dip.isOctetOnium) colFac *= 0.5 * octetOniumColFac;
+ double wtPSqqbar = (colTypeAbs == 2) ? 0.25 * nGluonToQuark : 0.;
+
+ // Variables used inside evolution loop. (Mainly dummy start values.)
+ dip.pT2 = pT2begDip;
+ int nFlavour = 3;
+ double zMinAbs = 0.5;
+ double pT2min = pT2endDip;
+ double b0 = 4.5;
+ double Lambda2 = Lambda3flav2;
+ double emitCoefGlue = 0.;
+ double emitCoefQqbar = 0.;
+ double emitCoefTot = 0.;
+ double wt = 0.;
+ bool mustFindRange = true;
+
+ // Begin evolution loop towards smaller pT values.
+ do {
+
+ // Initialize evolution coefficients at the beginning and
+ // reinitialize when crossing c and b flavour thresholds.
+ if (mustFindRange) {
+
+ // Determine overestimated z range; switch at c and b masses.
+ if (dip.pT2 > m2b) {
+ nFlavour = 5;
+ pT2min = m2b;
+ b0 = 23./6.;
+ Lambda2 = Lambda5flav2;
+ } else if (dip.pT2 > m2c) {
+ nFlavour = 4;
+ pT2min = m2c;
+ b0 = 25./6.;
+ Lambda2 = Lambda4flav2;
+ } else {
+ nFlavour = 3;
+ pT2min = pT2endDip;
+ b0 = 27./6.;
+ Lambda2 = Lambda3flav2;
+ }
+ zMinAbs = 0.5 - sqrtpos( 0.25 - pT2min / dip.m2DipCorr );
+ if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2min / dip.m2DipCorr;
+
+ // Find emission coefficients for X -> X g and g -> q qbar.
+ emitCoefGlue = wtPSglue * colFac * log(1. / zMinAbs - 1.);
+ emitCoefTot = emitCoefGlue;
+ if (colTypeAbs == 2 && event[dip.iRadiator].id() == 21) {
+ emitCoefQqbar = wtPSqqbar * (1. - 2. * zMinAbs);
+ emitCoefTot += emitCoefQqbar;
+ }
+
+ // Initialization done for current range.
+ mustFindRange = false;
+ }
+
+ // Pick pT2 (in overestimated z range) for fixed alpha_strong.
+ if (alphaSorder == 0) {
+ dip.pT2 = dip.pT2 * pow( Rndm::flat(),
+ 1. / (alphaS2pi * emitCoefTot) );
+
+ // Ditto for first-order alpha_strong.
+ } else if (alphaSorder == 1) {
+ dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
+ pow( Rndm::flat(), b0 / emitCoefTot) );
+
+ // For second order reject by second term in alpha_strong expression.
+ } else {
+ do dip.pT2 = Lambda2 * pow( dip.pT2 / Lambda2,
+ pow( Rndm::flat(), b0 / emitCoefTot) );
+ while (alphaS.alphaS2OrdCorr(dip.pT2) < Rndm::flat()
+ && dip.pT2 > pT2min);
+ }
+ wt = 0.;
+
+ // If crossed c or b thresholds: continue evolution from threshold.
+ if (nFlavour == 5 && dip.pT2 < m2b) {
+ mustFindRange = true;
+ dip.pT2 = m2b;
+ } else if ( nFlavour == 4 && dip.pT2 < m2c) {
+ mustFindRange = true;
+ dip.pT2 = m2c;
+
+ // Abort evolution if below cutoff scale, or below another branching.
+ } else {
+ if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
+
+ // Pick kind of branching: X -> X g or g -> q qbar.
+ dip.flavour = 21;
+ dip.mFlavour = 0.;
+ if (colTypeAbs == 2 && emitCoefQqbar > Rndm::flat()
+ * emitCoefTot) dip.flavour = 0;
+
+ // Pick z: either dz/(1-z) or flat dz.
+ if (dip.flavour == 21) {
+ dip.z = 1. - zMinAbs * pow( 1. / zMinAbs - 1., Rndm::flat() );
+ } else {
+ dip.z = zMinAbs + (1. - 2. * zMinAbs) * Rndm::flat();
+ }
+
+ // Do not accept branching if outside allowed z range.
+ double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
+ if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
+ dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
+ if (dip.z > zMin && dip.z < 1. - zMin
+ && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
+ * pow2(dip.m2Dip + dip.m2 - dip.m2Rec) ) {
+
+ // Flavour choice for g -> q qbar.
+ if (dip.flavour == 0) {
+ dip.flavour = min(5, 1 + int(nGluonToQuark * Rndm::flat()));
+ dip.mFlavour = ParticleDataTable::m0(dip.flavour);
+ }
+
+ // No z weight, except threshold, if to do ME corrections later on.
+ if (dip.MEtype > 0) {
+ wt = 1.;
+ if (dip.flavour < 10 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
+ wt = 0.;
+
+ // z weight for X -> X g.
+ } else if (dip.flavour == 21 && colTypeAbs == 1) {
+ wt = (1. + pow2(dip.z)) / wtPSglue;
+ } else if (dip.flavour == 21) {
+ wt = (1. + pow3(dip.z)) / wtPSglue;
+
+ // z weight for g -> q qbar.
+ } else {
+ double beta = sqrtpos( 1. - 4. * pow2(dip.mFlavour) / dip.m2 );
+ wt = beta * ( pow2(dip.z) + pow2(1. - dip.z) );
+ }
+
+ // For dipole to beam remnant reduce by PDF ratio (approximate!??).
+ if (dip.isrType != 0) {
+ BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
+ int iSys = dip.system;
+ double xOld = beam[iSys].x();
+ double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
+ (dip.m2Dip - dip.m2Rad));
+ if (xNew > beam.xMax(iSys)) wt = 0.;
+ else {
+ int idRec = event[dip.iRecoiler].id();
+ double pdfOld = max ( TINYPDF,
+ beam.xfISR( iSys, idRec, xOld, dip.pT2) );
+ double pdfNew = beam.xfISR( iSys, idRec, xNew, dip.pT2);
+ wt *= min( 1., pdfNew / pdfOld);
+ }
+ }
+ }
+ }
+
+ // Iterate until acceptable pT (or have fallen below pTmin).
+ } while (wt < Rndm::flat());
+
+}
+
+//*********
+
+// Evolve a QED dipole end, either charged or photon.
+
+void TimeShower::pT2nextQED(double pT2begDip, double pT2sel,
+ TimeDipoleEnd& dip, Event& event) {
+
+ // Lower cut for evolution. Return if no evolution range.
+ double pT2chgCut = (dip.chgType != 0 && abs(dip.chgType) != 3)
+ ? pT2chgQCut : pT2chgLCut;
+ double pT2endDip = max( pT2sel, pT2chgCut );
+ if (pT2begDip < pT2endDip) return;
+
+ // Emission of photon or photon branching.
+ bool hasCharge = (dip.chgType != 0);
+
+ // Default values.
+ double wtPSgam = 0.;
+ double chg2Sum = 0.;
+ double chg2SumL = 0.;
+ double chg2SumQ = 0.;
+ double zMinAbs = 0.;
+ double emitCoefTot = 0.;
+
+ // alpha_em at maximum scale provides upper estimate.
+ double alphaEMmax = alphaEM.alphaEM(pT2begDip);
+ double alphaEM2pi = alphaEMmax / (2. * M_PI);
+
+ // Emission: upper estimate for matrix element weighting; charge factor.
+ if (hasCharge) {
+ wtPSgam = 2.;
+ double chg2 = pow2(dip.chgType / 3.);
+
+ // Determine overestimated z range. Find evolution coefficient.
+ zMinAbs = 0.5 - sqrtpos( 0.25 - pT2endDip / dip.m2DipCorr );
+ if (zMinAbs < SIMPLIFYROOT) zMinAbs = pT2endDip / dip.m2DipCorr;
+ emitCoefTot = alphaEM2pi * chg2 * wtPSgam * log(1. / zMinAbs - 1.);
+
+ // Branching: sum of squared charge factors for lepton and quark daughters.
+ } else {
+ chg2SumL = max(0, min(3, nGammaToLepton));
+ if (nGammaToQuark > 4) chg2SumQ = 11. / 9.;
+ else if (nGammaToQuark > 3) chg2SumQ = 10. / 9.;
+ else if (nGammaToQuark > 2) chg2SumQ = 6. / 9.;
+ else if (nGammaToQuark > 1) chg2SumQ = 5. / 9.;
+ else if (nGammaToQuark > 0) chg2SumQ = 1. / 9.;
+
+ // Total sum of squared charge factors. Find evolution coefficient.
+ chg2Sum = chg2SumL + 3. * chg2SumQ;
+ emitCoefTot = alphaEM2pi * chg2Sum;
+ }
+
+ // Variables used inside evolution loop.
+ dip.pT2 = pT2begDip;
+ double wt;
+
+ // Begin evolution loop towards smaller pT values.
+ do {
+
+ // Pick pT2 (in overestimated z range).
+ dip.pT2 = dip.pT2 * pow(Rndm::flat(), 1. / emitCoefTot);
+ wt = 0.;
+
+ // Abort evolution if below cutoff scale, or below another branching.
+ if ( dip.pT2 < pT2endDip) { dip.pT2 = 0.; return; }
+
+ // Pick z according to dz/(1-z) or flat.
+ if (hasCharge) dip.z = 1. - zMinAbs
+ * pow( 1. / zMinAbs - 1., Rndm::flat() );
+ else dip.z = Rndm::flat();
+
+ // Do not accept branching if outside allowed z range.
+ double zMin = 0.5 - sqrtpos( 0.25 - dip.pT2 / dip.m2DipCorr );
+ if (zMin < SIMPLIFYROOT) zMin = dip.pT2 / dip.m2DipCorr;
+ dip.m2 = dip.m2Rad + dip.pT2 / (dip.z * (1. - dip.z));
+ if (dip.z > zMin && dip.z < 1. - zMin
+ && dip.m2 * dip.m2Dip < dip.z * (1. - dip.z)
+ * pow2(dip.m2Dip + dip.m2 - dip.m2Rec)
+ // For gamma -> f fbar also impose maximum mass.
+ && (hasCharge || dip.m2 < m2MaxGamma) ) {
+
+ // Photon emission: unique flavour choice.
+ if (hasCharge) {
+ dip.flavour = 22;
+ dip.mFlavour = 0.;
+
+ // Photon branching: either lepton or quark flavour choice.
+ } else {
+ if (Rndm::flat() * chg2Sum < chg2SumL)
+ dip.flavour = 9 + 2 * min(3, 1 + int(chg2SumL * Rndm::flat()));
+ else {
+ double rndmQ = 9. * chg2SumQ * Rndm::flat();
+ if (rndmQ < 1.) dip.flavour = 1;
+ else if (rndmQ < 5.) dip.flavour = 2;
+ else if (rndmQ < 6.) dip.flavour = 3;
+ else if (rndmQ < 10.) dip.flavour = 4;
+ else dip.flavour = 5;
+ }
+ dip.mFlavour = ParticleDataTable::m0(dip.flavour);
+ }
+
+
+ // No z weight, except threshold, if to do ME corrections later on.
+ if (dip.MEtype > 0) {
+ wt = 1.;
+ if (dip.flavour < 20 && dip.m2 < THRESHM2 * pow2(dip.mFlavour))
+ wt = 0.;
+
+ // z weight for X -> X gamma.
+ } else if (hasCharge) {
+ wt = (1. + pow2(dip.z)) / wtPSgam;
+
+ // z weight for gamma -> f fbar.
+ } else {
+ double beta = sqrtpos( 1. - 4. * pow2(dip.mFlavour) / dip.m2 );
+ wt = beta * ( pow2(dip.z) + pow2(1. - dip.z) );
+ }
+
+ // Correct to current value of alpha_EM.
+ double alphaEMnow = alphaEM.alphaEM(dip.pT2);
+ wt *= (alphaEMnow / alphaEMmax);
+
+ // For dipole to beam remnant reduce by PDF ratio (approximate!??).
+ if (dip.isrType != 0) {
+ BeamParticle& beam = (dip.isrType == 1) ? *beamAPtr : *beamBPtr;
+ int iSys = dip.system;
+ double xOld = beam[iSys].x();
+ double xNew = xOld * (1. + (dip.m2 - dip.m2Rad) /
+ (dip.m2Dip - dip.m2Rad));
+ if (xNew > beam.xMax(iSys)) wt = 0.;
+ else {
+ int idRec = event[dip.iRecoiler].id();
+ double pdfOld = max ( TINYPDF,
+ beam.xfISR( iSys, idRec, xOld, dip.pT2) );
+ double pdfNew = beam.xfISR( iSys, idRec, xNew, dip.pT2);
+ wt *= min( 1., pdfNew / pdfOld);
+ }
+ }
+ }
+
+ // Iterate until acceptable pT (or have fallen below pTmin).
+ } while (wt < Rndm::flat());
+
+}
+
+//*********
+
+// ME corrections and kinematics that may give failure.
+// Notation: radBef, recBef = radiator, recoiler before emission,
+// rad, rec, emt = radiator, recoiler, emitted efter emission.
+// (rad, emt distinguished by colour flow for g -> q qbar.)
+
+bool TimeShower::branch( Event& event) {
+
+ // Find initial particles in dipole branching.
+ int iRadBef = dipSel->iRadiator;
+ int iRecBef = dipSel->iRecoiler;
+ Particle& radBef = event[iRadBef];
+ Particle& recBef = event[iRecBef];
+
+ // Default flavours and colour tags for new particles in dipole branching.
+ int idRad = radBef.id();
+ int idEmt = dipSel->flavour;
+ int colRad = radBef.col();
+ int acolRad = radBef.acol();
+ int colEmt = 0;
+ int acolEmt = 0;
+ iSysSel = dipSel->system;
+
+ // Default OK for photon emission.
+ if (dipSel->flavour == 22) {
+ // New colour tag required for gluon emission.
+ } else if (dipSel->flavour == 21 && dipSel->colType > 0) {
+ colEmt = colRad;
+ colRad = event.nextColTag();
+ acolEmt = colRad;
+ } else if (dipSel->flavour == 21) {
+ acolEmt = acolRad;
+ acolRad = event.nextColTag();
+ colEmt = acolRad;
+ // New flavours for g -> q qbar; split colours.
+ } else if (dipSel->colType > 0) {
+ idEmt = dipSel->flavour ;
+ idRad = -idEmt;
+ colEmt = colRad;
+ colRad = 0;
+ } else if (dipSel->colType < 0) {
+ idEmt = -dipSel->flavour ;
+ idRad = -idEmt;
+ acolEmt = acolRad;
+ acolRad = 0;
+ // New flavours for gamma -> f fbar, and maybe also colours.
+ } else if (dipSel->gamType == 1 && Rndm::flat() > 0.5) {
+ idEmt = -dipSel->flavour ;
+ idRad = -idEmt;
+ if (idRad < 10) colRad = event.nextColTag();
+ acolEmt = colRad;
+ } else if (dipSel->gamType == 1) {
+ idEmt = dipSel->flavour ;
+ idRad = -idEmt;
+ if (idEmt < 10) colEmt = event.nextColTag();
+ acolRad = colEmt;
+ }
+
+ // Construct kinematics in dipole rest frame:
+ // begin simple (like g -> g g).
+ double eRadPlusEmt = 0.5 * (dipSel->m2Dip + dipSel->m2 - dipSel->m2Rec)
+ / dipSel->mDip;
+ double e2RadPlusEmt = pow2(eRadPlusEmt);
+ double pzRadPlusEmt = 0.5 * sqrtpos( pow2(dipSel->m2Dip - dipSel->m2
+ - dipSel->m2Rec) - 4. * dipSel->m2 * dipSel->m2Rec ) / dipSel->mDip;
+ double pT2corr = dipSel->m2 * (e2RadPlusEmt * dipSel->z * (1. - dipSel->z)
+ - 0.25 * dipSel->m2) / pow2(pzRadPlusEmt);
+ double pTcorr = sqrtpos( pT2corr );
+ double pzRad = (e2RadPlusEmt * dipSel->z - 0.5 * dipSel->m2)
+ / pzRadPlusEmt;
+ double pzEmt = (e2RadPlusEmt * (1. - dipSel->z) - 0.5 * dipSel->m2)
+ / pzRadPlusEmt;
+ double mRad = dipSel->mRad;
+ double mEmt = 0.;
+
+ // Kinematics reduction for q -> q g or q -> q gamma when m_q > 0.
+ if (abs(dipSel->colType) == 1 || dipSel->chgType != 0) {
+ pTcorr *= 1. - dipSel->m2Rad / dipSel->m2;
+ pzRad += pzEmt * dipSel->m2Rad / dipSel->m2;
+ pzEmt *= 1. - dipSel->m2Rad / dipSel->m2;
+ // Kinematics reduction for g -> q qbar or gamma -> f fbar when m_f > 0;
+ } else if (abs(dipSel->flavour) < 20) {
+ mEmt = dipSel->mFlavour;
+ mRad = mEmt;
+ double beta = sqrtpos( 1. - 4. * pow2(mEmt) / dipSel->m2 );
+ pTcorr *= beta;
+ pzRad = 0.5 * ( (1. + beta) * pzRad + (1. - beta) * pzEmt );
+ pzEmt = pzRadPlusEmt - pzRad;
+ }
+
+ // Find rest frame and angles of original dipole.
+ RotBstMatrix M;
+ M.fromCMframe(radBef.p(), recBef.p());
+
+ // Evaluate coefficient of azimuthal asymmetry from gluon polarization.
+ findAsymPol( event, dipSel);
+
+ // Begin construction of new dipole kinematics: pick azimuthal angle.
+ Vec4 pRad, pEmt, pRec;
+ double wtPhi = 1.;
+ do {
+ double phi = 2. * M_PI * Rndm::flat();
+
+ // Define kinematics of branching in dipole rest frame.
+ pRad = Vec4( pTcorr * cos(phi), pTcorr * sin(phi), pzRad,
+ sqrt( pow2(pTcorr) + pow2(pzRad) + pow2(mRad) ) );
+ pEmt = Vec4( -pRad.px(), -pRad.py(), pzEmt,
+ sqrt( pow2(pTcorr) + pow2(pzEmt) + pow2(mEmt) ) );
+ pRec = Vec4( 0., 0., -pzRadPlusEmt, sqrt( pow2(pzRadPlusEmt)
+ + dipSel->m2Rec ) );
+
+ // Rotate and boost dipole products to the event frame.
+ pRad.rotbst(M);
+ pEmt.rotbst(M);
+ pRec.rotbst(M);
+
+ // Azimuthal phi weighting: loop to new phi value if required.
+ if (dipSel->asymPol != 0.) {
+ Vec4 pRadBef = event[iRadBef].p();
+ Vec4 pAunt = event[dipSel->iAunt].p();
+ double cosPhi = cosphi( pRad, pAunt, pRadBef );
+ wtPhi = ( 1. + dipSel->asymPol * (2. * pow2(cosPhi) - 1.) )
+ / ( 1. + abs(dipSel->asymPol) );
+ }
+ } while (wtPhi < Rndm::flat()) ;
+
+ // Kinematics when recoiler is initial-state parton.
+ int isrTypeNow = dipSel->isrType;
+ if (isrTypeNow != 0) pRec = 2. * recBef.p() - pRec;
+
+ // Define new particles from dipole branching.
+ double pTsel = sqrt(dipSel->pT2);
+ Particle rad = Particle(idRad, 51, iRadBef, 0, 0, 0,
+ colRad, acolRad, pRad, mRad, pTsel);
+ Particle emt = Particle(idEmt, 51, iRadBef, 0, 0, 0,
+ colEmt, acolEmt, pEmt, mEmt, pTsel);
+
+ // Recoiler either in final or in initial state
+ Particle rec = (isrTypeNow == 0)
+ ? Particle(recBef.id(), 52, iRecBef, iRecBef, 0, 0,
+ recBef.col(), recBef.acol(), pRec, dipSel->mRec, pTsel)
+ : Particle(recBef.id(), -53, 0, 0, iRecBef, iRecBef,
+ recBef.col(), recBef.acol(), pRec, 0., 0.);
+
+ // ME corrections can lead to branching being rejected.
+ if (dipSel->MEtype > 0) {
+ Particle& partner = (dipSel->iMEpartner == iRecBef)
+ ? rec : event[dipSel->iMEpartner];
+ if ( findMEcorr( dipSel, rad, partner, emt) < Rndm::flat() )
+ return false;
+ }
+
+ // Put new particles into the event record.
+ int iRad = event.append(rad);
+ int iEmt = event.append(emt);
+ int iRec = event.append(rec);
+
+ // Mark original dipole partons as branched and set daughters/mothers.
+ event[dipSel->iRadiator].statusNeg();
+ event[dipSel->iRadiator].daughters( iRad, iEmt);
+ if (isrTypeNow == 0) {
+ event[dipSel->iRecoiler].statusNeg();
+ event[dipSel->iRecoiler].daughters( iRec, iRec);
+ } else {
+ int mother1 = event[dipSel->iRecoiler].mother1();
+ int mother2 = event[dipSel->iRecoiler].mother2();
+ event[dipSel->iRecoiler].mothers( iRec, iRec);
+ event[iRec].mothers( mother1, mother2);
+ if (mother1 == 1) event[1].daughter1( iRec);
+ if (mother1 == 2) event[2].daughter1( iRec);
+ // For initial-state recoiler also update beam info.
+ BeamParticle& beamRec = (mother1 == 1) ? *beamAPtr : *beamBPtr;
+ double xRec = pRec.e() / beamRec.e();
+ beamRec[iSysSel].iPos( iRec);
+ beamRec[iSysSel].x( xRec);
+ }
+
+ // Photon emission: update to new dipole ends; add new photon "dipole".
+ if (dipSel->flavour == 22) {
+ dipSel->iRadiator = iRad;
+ dipSel->iRecoiler = iRec;
+ dipSel->pTmax = pTsel;
+ if (doQEDshowerByGamma) dipEnd.push_back( TimeDipoleEnd(iEmt, iRad,
+ pTsel, 0, 0, 1, 0, iSysSel, 0));
+
+ // Gluon emission: update both dipole ends and add two new ones.
+ } else if (dipSel->flavour == 21) {
+ dipSel->iRadiator = iRad;
+ dipSel->iRecoiler = iEmt;
+ dipSel->isrType = 0;
+ dipSel->pTmax = pTsel;
+ for (int i = 0; i < int(dipEnd.size()); ++i) {
+ if (dipEnd[i].iRadiator == iRecBef && dipEnd[i].iRecoiler == iRadBef
+ && dipEnd[i].colType != 0) {
+ dipEnd[i].iRadiator = iRec;
+ dipEnd[i].iRecoiler = iEmt;
+ // Strive to match colour to anticolour inside closed system.
+ if (dipEnd[i].colType * dipSel->colType > 0)
+ dipEnd[i].iRecoiler = iRad;
+ dipEnd[i].pTmax = pTsel;
+ }
+ }
+ int colType = (dipSel->colType > 0) ? 2 : -2 ;
+ dipEnd.push_back( TimeDipoleEnd(iEmt, iRec, pTsel,
+ colType, 0, 0, isrTypeNow, iSysSel, 0));
+ dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
+ -colType, 0, 0, 0, iSysSel, 0));
+
+ // Gluon branching to q qbar: update current dipole and other of gluon.
+ } else if (dipSel->colType != 0) {
+ for (int i = 0; i < int(dipEnd.size()); ++i) {
+ if (dipEnd[i].iRadiator == iRadBef && abs(dipEnd[i].colType) == 2) {
+ dipEnd[i].colType /= 2;
+ // Note: gluino -> quark + squark gives a deeper radiation dip than
+ // the more obvious alternative photon decay, so is more realistic.
+ dipEnd[i].MEtype = 66;
+ if (&dipEnd[i] == dipSel) dipEnd[i].iMEpartner = iRad;
+ else dipEnd[i].iMEpartner = iEmt;
+ }
+ // Strive to match colour to anticolour inside closed system.
+ if ( dipEnd[i].iRecoiler == iRadBef
+ && dipEnd[i].colType * dipSel->colType < 0 )
+ dipEnd[i].iRecoiler = iEmt;
+ }
+ dipSel->iRadiator = iEmt;
+ dipSel->iRecoiler = iRec;
+ dipSel->pTmax = pTsel;
+
+ // Gluon branching to q qbar: also add two charge dipole ends.
+ // Note: gluino -> quark + squark gives a deeper radiation dip than
+ // the more obvious alternative photon decay, so is more realistic.
+ if (doQEDshowerByQ) {
+ int chgType = event[iRad].chargeType();
+ dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
+ 0, chgType, 0, 0, iSysSel, 66, iEmt));
+ dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
+ 0, -chgType, 0, 0, iSysSel, 66, iRad));
+ }
+
+ // Photon branching to f fbar: inactivate photon "dipole";
+ // optionally add new charge and colour dipole ends.
+ } else if (dipSel->gamType != 0) {
+ dipSel->gamType = 0;
+ int chgType = event[iRad].chargeType();
+ int colType = event[iRad].colType();
+ // MEtype = 102 for charge in vector decay.
+ if ( chgType != 0 && ( ( doQEDshowerByQ && colType != 0 )
+ || ( doQEDshowerByL && colType == 0 ) ) ) {
+ dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
+ 0, chgType, 0, 0, iSysSel, 102, iEmt));
+ dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
+ 0, -chgType, 0, 0, iSysSel, 102, iRad));
+ }
+ // MEtype = 11 for colour in vector decay.
+ if (colType != 0 && doQCDshower) {
+ dipEnd.push_back( TimeDipoleEnd(iRad, iEmt, pTsel,
+ colType, 0, 0, 0, iSysSel, 11, iEmt));
+ dipEnd.push_back( TimeDipoleEnd(iEmt, iRad, pTsel,
+ -colType, 0, 0, 0, iSysSel, 11, iRad));
+ }
+ }
+
+ // Now update other dipoles that also involved the radiator or recoiler.
+ for (int i = 0; i < int(dipEnd.size()); ++i) {
+ if (dipEnd[i].iRadiator == iRadBef) dipEnd[i].iRadiator = iRad;
+ if (dipEnd[i].iRadiator == iRecBef) dipEnd[i].iRadiator = iRec;
+ if (dipEnd[i].iRecoiler == iRadBef) dipEnd[i].iRecoiler = iRad;
+ if (dipEnd[i].iRecoiler == iRecBef) dipEnd[i].iRecoiler = iRec;
+ if (dipEnd[i].iMEpartner == iRadBef) dipEnd[i].iMEpartner = iRad;
+ if (dipEnd[i].iMEpartner == iRecBef) dipEnd[i].iMEpartner = iRec;
+ }
+
+ // Finally update the list of all partons in all systems.
+ event.replaceInSystem(iSysSel, iRadBef, iRad);
+ event.addToSystem(iSysSel, iEmt);
+ event.replaceInSystem(iSysSel, iRecBef, iRec);
+
+ // Done.
+ return true;
+
+}
+
+//*********
+
+// Find class of QCD ME correction.
+// MEtype classification follow codes in Norrbin article,
+// additionally -1 = try to find type, 0 = no ME corrections.
+// Warning: not yet tried out to do a correct assignment in
+// arbitrary multiparton configurations! ??
+
+void TimeShower::findMEtype( Event& event, TimeDipoleEnd& dip) {
+
+ // Initial value. Mark if no ME corrections to be applied.
+ bool setME = true;
+ if (!doMEcorrections) setME = false;
+
+ // No ME corrections in 2 -> n processes.
+ int iMother = event[dip.iRadiator].mother1();
+ int iMother2 = event[dip.iRadiator].mother2();
+ if (iMother2 != iMother && iMother2 != 0) setME = false;
+ if (event[dip.iRecoiler].mother1() != iMother) setME = false;
+ if (event[dip.iRecoiler].mother2() != iMother2) setME = false;
+
+ // No ME corrections for recoiler in initial state.
+ if (event[dip.iRecoiler].status() < 0) setME = false;
+
+ // Done if no ME to be set.
+ if (!setME) {
+ dip.MEtype = 0;
+ return;
+ }
+
+ // If no ME partner set, assume it is the recoiler.
+ if (dip.iMEpartner < 0) dip.iMEpartner = dip.iRecoiler;
+
+ // Now begin processing of colour dipole.
+ if (dip.colType != 0) {
+
+ // Find daughter types (may or may not be used later on).
+ int idDau1 = event[dip.iRadiator].id();
+ int idDau2 = event[dip.iMEpartner].id();
+ int dau1Type = findMEparticle(idDau1);
+ int dau2Type = findMEparticle(idDau2);
+ int minDauType = min(dau1Type, dau2Type);
+ int maxDauType = max(dau1Type, dau2Type);
+
+ // Reorder dipole ends in kinematics. Split ME expression in two sides.
+ dip.MEorder = (dau2Type >= dau1Type);
+ dip.MEsplit = (maxDauType <= 6);
+ dip.MEgluinoRec = false;
+
+ // If type already set (or set not to have) then done.
+ if (minDauType == 0 && dip.MEtype < 0) dip.MEtype = 0;
+ if (dip.MEtype >= 0) return;
+ dip.MEtype = 0;
+
+ // For H -> gg -> ggg we found that DGLAP kernels do better than eikonal.
+ if (dau1Type == 4 && dau2Type == 4) return;
+
+ // Find mother type.
+ int idMother = 0;
+ if ( event[dip.iRecoiler].mother1() == iMother && iMother >= 0)
+ idMother = event[iMother].id();
+ int motherType = (idMother != 0) ? findMEparticle(idMother) : 0;
+
+ // When a mother if not known then use colour and spin content to guess.
+ if (motherType == 0) {
+ int col1 = event[dip.iRadiator].col();
+ int acol1 = event[dip.iRadiator].acol();
+ int col2 = event[dip.iMEpartner].col();
+ int acol2 = event[dip.iMEpartner].acol();
+ // spinT = 0/1 = integer or half-integer.
+ int spinT = ( event[dip.iRadiator].spinType()
+ + event[dip.iMEpartner].spinType() )%2;
+ // Colour singlet mother.
+ if ( col1 == acol2 && acol1 == col2 )
+ motherType = (spinT == 0) ? 7 : 9;
+ // Colour octet mother.
+ else if ( (col1 == acol2 && acol1 != 0 && col2 != 0)
+ || (acol1 == col2 && col1 != 0 && acol2 != 0) )
+ motherType = (spinT == 0) ? 4 : 5;
+ // Colour triplet mother.
+ else if ( (col1 == acol2 && acol1 != col2)
+ || (acol1 == col2 && col1 != acol2) )
+ motherType = (spinT == 0) ? 2 : 1;
+ // If no colours are matched then cannot have common mother, so done.
+ else return;
+ }
+
+ // Now start from default, which is eikonal ME corrections,
+ // and try to find matching ME cases below.
+ int MEkind = 0;
+ int MEcombi = 4;
+ dip.MEmix = 0.5;
+
+ // Triplet recoiling against gluino needs enhanced radiation
+ // to match to matrix elements.
+ dip.MEgluinoRec = (dau1Type >= 1 && dau1Type <= 3 && dau2Type == 5);
+
+ // Vector/axial vector -> q + qbar.
+ if (minDauType == 1 && maxDauType == 1 &&
+ (motherType == 4 || motherType == 7) ) {
+ MEkind = 2;
+ if (idMother == 21 || idMother == 22) MEcombi = 1;
+ else if (idMother == 23 || idDau1 + idDau2 == 0) {
+ MEcombi = 3;
+ dip.MEmix = gammaZmix( event, iMother, dip.iRadiator, dip.iRecoiler );
+ }
+ else if (idMother == 24) MEcombi = 4;
+ }
+ // For chi -> chi q qbar, use V/A -> q qbar as first approximation.
+ else if (minDauType == 1 && maxDauType == 1 && motherType == 9)
+ MEkind = 2;
+
+ // q -> q + V.
+ else if (minDauType == 1 && maxDauType == 7 && motherType == 1)
+ MEkind = 3;
+ if (idDau1 == 22 || idDau2 == 22) MEcombi = 1;
+
+ // Scalar/pseudoscalar -> q + qbar; q -> q + S.
+ else if (minDauType == 1 && maxDauType == 1 && motherType == 8) {
+ MEkind = 4;
+ if (idMother == 25 || idMother == 35 || idMother == 37) MEcombi = 1;
+ else if (idMother == 36) MEcombi = 2;
+ }
+ else if (minDauType == 1 && maxDauType == 8 && motherType == 1)
+ MEkind = 5;
+
+ // V -> ~q + ~qbar; ~q -> ~q + V; S -> ~q + ~qbar; ~q -> ~q + S.
+ else if (minDauType == 2 && maxDauType == 2 && (motherType == 4
+ || motherType == 7) ) MEkind = 6;
+ else if (minDauType == 2 && (maxDauType == 4 || maxDauType == 7)
+ && motherType == 2) MEkind = 7;
+ else if (minDauType == 2 && maxDauType == 2 && motherType == 8)
+ MEkind = 8;
+ else if (minDauType == 2 && maxDauType == 8 && motherType == 2)
+ MEkind = 9;
+
+ // chi -> q + ~qbar; ~q -> q + chi; q -> ~q + chi.
+ else if (minDauType == 1 && maxDauType == 2 && motherType == 9)
+ MEkind = 10;
+ else if (minDauType == 1 && maxDauType == 9 && motherType == 2)
+ MEkind = 11;
+ else if (minDauType == 2 && maxDauType == 9 && motherType == 1)
+ MEkind = 12;
+
+ // ~g -> q + ~qbar; ~q -> q + ~g; q -> ~q + ~g.
+ else if (minDauType == 1 && maxDauType == 2 && motherType == 5)
+ MEkind = 13;
+ else if (minDauType == 1 && maxDauType == 5 && motherType == 2)
+ MEkind = 14;
+ else if (minDauType == 2 && maxDauType == 5 && motherType == 1)
+ MEkind = 15;
+
+ // g (+V, S) -> ~g + ~g (eikonal approximation).
+ else if (minDauType == 5 && maxDauType == 5) MEkind = 16;
+
+ // Save ME type and gamma_5 admixture.
+ dip.MEtype = 5 * MEkind + MEcombi;
+
+ // Now begin processing of charge dipole - still primitive.
+ } else if (dip.chgType != 0) {
+
+ // Set defaults for QED case; then possibly done.
+ dip.MEorder = true;
+ dip.MEsplit = true;
+ if (dip.MEtype >= 0) return;
+
+ // So far only ME corrections for q qbar or l lbar.
+ int idDau1 = event[dip.iRadiator].id();
+ int idDau2 = event[dip.iMEpartner].id();
+ if (abs(idDau1) < 9 && abs(idDau2) < 9 && idDau1 * idDau2 < 0) ;
+ else if (abs(idDau1) > 10 && abs(idDau1) < 19 && abs(idDau2) > 10
+ && abs(idDau2) < 19 && idDau1 * idDau2 < 0) ;
+ else { dip.MEtype = 0; return; }
+
+ // Distinguish charge sum != 0 or = 0; in latter assume vector source.
+ dip.MEtype = 101;
+ if (idDau1 + idDau2 == 0) dip.MEtype = 102;
+ dip.MEmix = 1.;
+ }
+
+}
+
+//*********
+
+// Find type of particle for ME type: 0 = unknown, 1 = quark, 2 = squark,
+// 3 = spare triplet, 4 = gluon, 5 = gluino, 6 = spare octet,
+// 7 = vector boson, 8 = colourless scalar, 9 = colourless spin 1/2.
+
+int TimeShower::findMEparticle( int id) {
+
+ // find colour and spin of particle.
+ int type = 0;
+ int colType = abs(ParticleDataTable::colType(id));
+ int spinType = ParticleDataTable::spinType(id);
+
+ // Find particle type from colour and spin.
+ if (colType == 1 && spinType == 2) type = 1;
+ else if (colType == 1 && spinType == 1) type = 2;
+ else if (colType == 1) type = 3;
+ else if (colType == 2 && spinType == 3) type = 4;
+ else if (colType == 2 && spinType == 2) type = 5;
+ else if (colType == 2) type = 6;
+ else if (colType == 0 && spinType == 3) type = 7;
+ else if (colType == 0 && spinType == 1) type = 8;
+ else if (colType == 0 && spinType == 2) type = 9;
+
+ // Done.
+ return type;
+
+}
+
+//*********
+
+// Find mixture of V and A in gamma/Z: energy- and flavour-dependent.
+
+double TimeShower::gammaZmix( Event& event, int iRes, int iDau1, int iDau2) {
+
+ // Try to identify initial flavours; use e+e- as default.
+ int idIn1 = -11;
+ int idIn2 = 11;
+ int iIn1 = (iRes >= 0) ? event[iRes].mother1() : -1;
+ int iIn2 = (iRes >= 0) ? event[iRes].mother2() : -1;
+ if (iIn1 >=0) idIn1 = event[iIn1].id();
+ if (iIn2 >=0) idIn2 = event[iIn1].id();
+
+ // In processes f + g/gamma -> f + Z only need find one fermion.
+ if (idIn1 == 21 || idIn1 == 22) idIn1 = -idIn2;
+ if (idIn2 == 21 || idIn2 == 22) idIn2 = -idIn1;
+
+ // Initial flavours and couplings; return if don't make sense.
+ if (idIn1 + idIn2 != 0 ) return 0.5;
+ int idInAbs = abs(idIn1);
+ if (idInAbs == 0 || idInAbs > 18 ) return 0.5;
+ double ei = CoupEW::ef(idInAbs);
+ double vi = CoupEW::vf(idInAbs);
+ double ai = CoupEW::af(idInAbs);
+
+ // Final flavours and couplings; return if don't make sense.
+ if (event[iDau1].id() + event[iDau2].id() != 0) return 0.5;
+ int idOutAbs = abs(event[iDau1].id());
+ if (idOutAbs == 0 || idOutAbs >18 ) return 0.5;
+ double ef = CoupEW::ef(idOutAbs);
+ double vf = CoupEW::vf(idOutAbs);
+ double af = CoupEW::af(idOutAbs);
+
+ // Calculate prefactors for interference and resonance part.
+ Vec4 psum = event[iDau1].p() + event[iDau2].p();
+ double sH = psum.m2Calc();
+ double intNorm = 2. * thetaWRat * sH * (sH - mZ*mZ)
+ / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
+ double resNorm = pow2(thetaWRat * sH)
+ / ( pow2(sH - mZ*mZ) + pow2(sH * gammaZ / mZ) );
+
+ // Calculate vector and axial expressions and find mix.
+ double vect = ei*ei * ef*ef + ei*vi * intNorm * ef*vf
+ + (vi*vi + ai*ai) * resNorm * vf*vf;
+ double axiv = (vi*vi + ai*ai) * resNorm * af*af;
+ return vect / (vect + axiv);
+}
+
+//*********
+
+// Set up to calculate QCD ME correction with calcMEcorr.
+// Normally for primary particles, but also from g/gamma -> f fbar.
+
+double TimeShower::findMEcorr(TimeDipoleEnd* dip, Particle& rad,
+ Particle& partner, Particle& emt) {
+
+ // Initial values and matrix element kind.
+ //cout << "\n enter findMEcorr " << dip->MEtype << " " << rad.id()
+ // << " " << partner.id() << " " << emt.id() << endl;
+ double wtME = 1.;
+ double wtPS = 1.;
+ int MEkind = dip->MEtype / 5;
+ int MEcombi = dip->MEtype % 5;
+
+ // Construct ME variables.
+ Vec4 sum = rad.p() + partner.p() + emt.p();
+ double eCMME = sum.mCalc();
+ double x1 = 2. * (sum * rad.p()) / pow2(eCMME);
+ double x2 = 2. * (sum * partner.p()) / pow2(eCMME);
+ double r1 = rad.m() / eCMME;
+ double r2 = partner.m() / eCMME;
+
+ // Derived ME variables, suitably protected.
+ double x1minus = max(XMARGIN, 1. + r1*r1 - r2*r2 - x1);
+ double x2minus = max(XMARGIN, 1. + r2*r2 - r1*r1 - x2) ;
+ double x3 = max(XMARGIN, 2. - x1 - x2);
+ //cout << scientific << setprecision(6) << "x_i = " << x1 << " " << x2
+ // << " " << x3 << " " << r1 << " " << r2 << endl;
+
+ // Begin processing of QCD dipoles.
+ if (dip->colType !=0) {
+
+ // Evaluate normal ME, for proper order of particles.
+ if (dip->MEorder)
+ wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix, x1, x2, r1, r2);
+ else wtME = calcMEcorr(MEkind, MEcombi, dip->MEmix, x2, x1, r2, r1);
+ //cout << " ME direct " << dip->MEorder << " " << wtME << endl;
+
+ // Split up total ME when two radiating particles.
+ if (dip->MEsplit) wtME = wtME * x1minus / x3;
+ //cout << " ME modif " << dip->MEsplit << " " << wtME << endl;
+
+ // Evaluate shower rate to be compared with.
+ wtPS = 2. / ( x3 * x2minus );
+ if (dip->MEgluinoRec) wtPS *= 9./4.;
+ //cout << " PS " << dip->MEgluinoRec << " " << wtPS << endl;
+
+ // For generic charge combination currently only massless expression.
+ // (Masses included only to respect phase space boundaries.)
+ } else if (dip->chgType !=0 && dip->MEtype == 101) {
+ double chg1 = ParticleDataTable::charge(rad.id());
+ double chg2 = ParticleDataTable::charge(partner.id());
+ wtME = (x1*x1 + x2*x2) * pow2( chg1 * x1minus / x3
+ - chg2 * x2minus / x3 );
+ wtPS = 2. * ( chg1*chg1 * x1minus / x3 + chg2*chg2 * x2minus / x3 );
+
+ // For flavour neutral system assume vector source and include masses.
+ } else if (dip->chgType !=0 && dip->MEtype == 102) {
+ wtME = calcMEcorr(2, 1, dip->MEmix, x1, x2, r1, r2) * x1minus / x3;
+ wtPS = 2. / ( x3 * x2minus );
+ }
+ if (wtME > wtPS) infoPtr->errorMsg("Warning in TimeShower::findMEcorr: "
+ "ME weight above PS one");
+
+ // Return ratio of actual ME to assumed PS rate of emission.
+ return wtME / wtPS;
+}
+
+//*********
+
+// Matrix elements for gluon (or photon) emission from
+// a two-body state; to be used by the parton shower routine.
+// Here x_i = 2 E_i/E_cm, r_i = m_i/E_cm and
+// 1/sigma_0 d(sigma)/d(x_1)d(x_2) = (alpha-strong/2 pi) * C_F * (this),
+// i.e. normalization is such that one recovers the familiar
+// (x_1^2 + x_2^2)/((1-x_1)*(1-x_2)) for the massless case.
+// Coupling structure:
+// kind = 1 : eikonal soft-gluon expression (spin-independent)
+// = 2 : V -> q qbar (V = vector/axial vector colour singlet)
+// = 3 : q -> q V
+// = 4 : S -> q qbar (S = scalar/pseudoscalar colour singlet)
+// = 5 : q -> q S
+// = 6 : V -> ~q ~qbar (~q = squark)
+// = 7 : ~q -> ~q V
+// = 8 : S -> ~q ~qbar
+// = 9 : ~q -> ~q S
+// = 10 : chi -> q ~qbar (chi = neutralino/chargino)
+// = 11 : ~q -> q chi
+// = 12 : q -> ~q chi
+// = 13 : ~g -> q ~qbar
+// = 14 : ~q -> q ~g
+// = 15 : q -> ~q ~g
+// = 16 : (9/4)*(eikonal) for gg -> ~g ~g
+// Note that the order of the decay products is important.
+// combi = 1 : pure non-gamma5, i.e. vector/scalar/...
+// = 2 : pure gamma5, i.e. axial vector/pseudoscalar/....
+// = 3 : mixture mix*(combi=1) + (1-mix)*(combi=2)
+// = 4 : mixture (combi=1) +- (combi=2)
+
+double TimeShower::calcMEcorr( int kind, int combiIn, double mixIn,
+ double x1, double x2, double r1, double r2) {
+
+ // Frequent variable combinations.
+ double x3 = 2. - x1 - x2;
+ double x1s = x1 * x1;
+ double x2s = x2 * x2;
+ double x3s = x3 * x3;
+ double x1c = x1 * x1s;
+ double x2c = x2 * x2s;
+ double x3c = x3 * x3s;
+ double r1s = r1 * r1;
+ double r2s = r2 * r2;
+ double r1c = r1 * r1s;
+ double r2c = r2 * r2s;
+ double r1q = r1s * r1s;
+ double r2q = r2s * r2s;
+ double prop1 = 1. + r1s - r2s - x1;
+ double prop2 = 1. + r2s - r1s - x2;
+ double prop1s = prop1 * prop1;
+ double prop2s = prop2 * prop2;
+ double prop12 = prop1 * prop2;
+ double prop13 = prop1 * x3;
+ double prop23 = prop2 * x3;
+
+ // Check input values. Return zero outside allowed phase space.
+ if (x1 - 2.*r1 < XMARGIN || prop1 < XMARGIN) return 0.;
+ if (x2 - 2.*r2 < XMARGIN || prop2 < XMARGIN) return 0.;
+ if (x1 + x2 - 1. - pow2(r1+r2) < XMARGIN) return 0.;
+ // Note: equivalent rewritten form 4. * ( (1. - x1) * (1. - x2)
+ // * (1. - r1s - r2s - x3) + r1s * (1. - x2s - x3) + r2s
+ // * (1. - x1s - x3) - pow2(r1s - r2s) ) gives abot same result.
+ if ( (x1s - 4.*r1s) * (x2s - 4.*r2s)
+ - pow2( 2. * (1. - x1 - x2 + r1s + r2s) + x1*x2 )
+ < XMARGIN * (XMARGINCOMB + r1 + r2) ) return 0.;
+
+ // Initial values; phase space.
+ int combi = max(1, min(4, combiIn) );
+ double mix = max(0., min(1., mixIn) );
+ bool isSet1 = false;
+ bool isSet2 = false;
+ bool isSet4 = false;
+ double ps = sqrtpos( pow2(1. - r1*r1 - r2*r2) - pow2(2. * r1 * r2) );
+ double rLO = 0., rFO = 0., rLO1 = 0., rFO1 = 0., rLO2 = 0.,
+ rFO2 = 0., rLO4 = 0., rFO4 = 0.;
+ double offset = 0;
+
+ // Select which kind of ME to use.
+ switch (kind) {
+
+ // case 1 is equal to default, i.e. eikonal expression.
+
+ // V -> q qbar (V = gamma*/Z0/W+-/...).
+ case 2:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(2.-r1s-r1q+6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
+ rFO1 = -(3.+6.*r1s+r1q-6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
+ +6.*r1*r2c+r2q-3.*x1+6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
+ +3.*r1s*x3+6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
+ +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s
+ +2.*x1*x3s+x3c-x2)
+ /prop2s
+ -2.*(-3.+r1s-6.*r1*r2+6.*r1c*r2+3.*r2s-4.*r1s*r2s
+ +6.*r1*r2c+2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s
+ -r2s*x1s+4.*x3+2.*r1s*x3+3.*r1*r2*x3-r2s*x3-3.*x1*x3
+ -2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s+r1*r2*x3s+x1*x3s)
+ /prop12
+ -(-1.+2.*r1s+r1q+6.*r1*r2+6.*r1c*r2-2.*r2s-6.*r1s*r2s
+ +6.*r1*r2c+r2q-x1-2.*r1s*x1-6.*r1*r2*x1+8.*r2s*x1+x1s
+ -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
+ /prop1s;
+ rFO1 = rFO1/2.;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(2.-r1s-r1q-6.*r1*r2-r2s+2.*r1s*r2s-r2q)/2.;
+ rFO2 = -(3.+6.*r1s+r1q+6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
+ -6.*r1*r2c+r2q-3.*x1-6.*r1*r2*x1+2.*r2s*x1+x1s-2.*r1s*x1s
+ +3.*r1s*x3-6.*r1*r2*x3-r2s*x3-2.*x1*x3-5.*r1s*x1*x3
+ +r2s*x1*x3+x1s*x3-3.*x3s-3.*r1s*x3s+r2s*x3s+2.*x1*x3s+x3c-x2)
+ /prop2s
+ -2.*(-3+r1s+6.*r1*r2-6.*r1c*r2+3.*r2s-4.*r1s*r2s-6.*r1*r2c
+ +2.*x1+3.*r1s*x1+r2s*x1-x1s-r1s*x1s-r2s*x1s+4.*x3+2.*r1s*x3
+ -3.*r1*r2*x3-r2s*x3-3.*x1*x3-2.*r1s*x1*x3+x1s*x3-x3s-r1s*x3s
+ -r1*r2*x3s+x1*x3s)
+ /prop12
+ -(-1.+2.*r1s+r1q-6.*r1*r2-6.*r1c*r2-2.*r2s-6.*r1s*r2s
+ -6.*r1*r2c+r2q-x1-2.*r1s*x1+6.*r1*r2*x1+8.*r2s*x1+x1s
+ -2.*r2s*x1s-r1s*x3+r2s*x3-r1s*x1*x3+r2s*x1*x3+x1s*x3+x2)
+ /prop1s;
+ rFO2 = rFO2/2.;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(2.-r1s-r1q-r2s+2.*r1s*r2s-r2q)/2.;
+ rFO4 = (1.-r1q+6.*r1s*r2s-r2q+x1+3.*r1s*x1-9.*r2s*x1-3.*x1s
+ -r1s*x1s+3.*r2s*x1s+x1c-x2-r1s*x2+r2s*x2-r1s*x1*x2+r2s*x1*x2
+ +x1s*x2)
+ /prop1s
+ -2.*(1.+r1s+r2s-4.*r1s*r2s+r1s*x1+2.*r2s*x1-x1s-r2s*x1s
+ +2.*r1s*x2+r2s*x2-3.*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
+ /prop12
+ +(1.-r1q+6.*r1s*r2s-r2q-x1+r1s*x1-r2s*x1+x2-9.*r1s*x2
+ +3.*r2s*x2+r1s*x1*x2-r2s*x1*x2-3.*x2s+3.*r1s*x2s-r2s*x2s
+ +x1*x2s+x2c)
+ /prop2s;
+ rFO4 = rFO4/2.;
+ isSet4 = true;
+ }
+ break;
+
+ // q -> q V.
+ case 3:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.-2.*r1s+r1q+r2s-6.*r1*r2s+r1s*r2s-2.*r2q);
+ rFO1 = -2.*(-1.+r1-2.*r1s+2.*r1c-r1q+pow5(r1)-r2s+r1*r2s
+ -5.*r1s*r2s+r1c*r2s-2.*r1*r2q+2.*x1-2.*r1*x1+2.*r1s*x1
+ -2.*r1c*x1+2.*r2s*x1+5.*r1*r2s*x1+r1s*r2s*x1+2.*r2q*x1
+ -x1s+r1*x1s-r2s*x1s+3.*x2+4.*r1s*x2+r1q*x2+2.*r2s*x2
+ +2.*r1s*r2s*x2-4.*x1*x2-2.*r1s*x1*x2-r2s*x1*x2+x1s*x2
+ -2.*x2s-2.*r1s*x2s+x1*x2s)
+ /prop23
+ +(2.*r2s+6.*r1*r2s-6.*r1s*r2s+6.*r1c*r2s+2.*r2q+6.*r1*r2q
+ -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2-6.*r1*r2s*x2
+ +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
+ +2.*r2s*x2s+x1*x2s)
+ /prop2s
+ +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
+ +r1q*x1-3.*r2s*x1+6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-
+ 2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+6.*r1*r2s*x2
+ +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
+ +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
+ /x3s;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.-2.*r1s+r1q+r2s+6.*r1*r2s+r1s*r2s-2.*r2q);
+ rFO2 = 2*(1.+r1+2.*r1s+2.*r1c+r1q+pow5(r1)+r2s+r1*r2s
+ +5.*r1s*r2s+r1c*r2s-2.*r1*r2q-2.*x1-2.*r1*x1-2.*r1s*x1
+ -2.*r1c*x1-2.*r2s*x1+5.*r1*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s
+ +r1*x1s+r2s*x1s-3.*x2-4.*r1s*x2-r1q*x2-2.*r2s*x2
+ -2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2-x1s*x2
+ +2.*x2s+2.*r1s*x2s-x1*x2s)
+ /prop23
+ +(2.*r2s-6.*r1*r2s-6.*r1s*r2s-6.*r1c*r2s+2.*r2q-6.*r1*r2q
+ -r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2-3.*r2s*x2+6.*r1*r2s*x2
+ +9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
+ +2.*r2s*x2s+x1*x2s)
+ /prop2s
+ +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
+ +r1q*x1-3.*r2s*x1-6.*r1*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s
+ -2.*r1s*x1s+x1c+7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2-6.*r1*r2s*x2
+ +r1s*r2s*x2-2.*r2q*x2-9.*x1*x2-3.*r1s*x1*x2+2.*r2s*x1*x2
+ +2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s+x1*x2s)
+ /x3s;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.-2.*r1s+r1q+r2s+r1s*r2s-2.*r2q);
+ rFO4 = 2*(1.+2.*r1s+r1q+r2s+5.*r1s*r2s-2.*x1-2.*r1s*x1
+ -2.*r2s*x1-r1s*r2s*x1-2.*r2q*x1+x1s+r2s*x1s-3.*x2-4.*r1s*x2
+ -r1q*x2-2.*r2s*x2-2.*r1s*r2s*x2+4.*x1*x2+2.*r1s*x1*x2+r2s*x1*x2
+ -x1s*x2+2.*x2s+2.*r1s*x2s-x1*x2s)
+ /prop23
+ +(2.*r2s-6.*r1s*r2s+2.*r2q-r2s*x1+r1s*r2s*x1-r2q*x1+x2-r1q*x2
+ -3.*r2s*x2+9.*r1s*r2s*x2-2.*r2q*x2-x1*x2+r1s*x1*x2-x2s-3.*r1s*x2s
+ +2.*r2s*x2s+x1*x2s)
+ /prop2s
+ +(-4.-8.*r1s-4.*r1q+4.*r2s-4.*r1s*r2s+8.*r2q+9.*x1+10.*r1s*x1
+ +r1q*x1-3.*r2s*x1+r1s*r2s*x1-2.*r2q*x1-6.*x1s-2.*r1s*x1s+x1c
+ +7.*x2+8.*r1s*x2+r1q*x2-7.*r2s*x2+r1s*r2s*x2-2.*r2q*x2-9.*x1*x2
+ -3.*r1s*x1*x2+2.*r2s*x1*x2+2.*x1s*x2-3.*x2s-r1s*x2s+2.*r2s*x2s
+ +x1*x2s)
+ /x3s;
+ isSet4 = true;
+ }
+ break;
+
+ // S -> q qbar (S = h0/H0/A0/H+-/...).
+ case 4:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
+ rFO1 = -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
+ -r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
+ /prop1s
+ -2.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
+ +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
+ /prop12
+ -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1-r1s*x1
+ +r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
+ /prop2s;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
+ rFO2 = -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
+ -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
+ /prop1s
+ -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
+ -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
+ /prop2s
+ +2.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
+ +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
+ /prop12;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.-r1s-r2s);
+ rFO4 = -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
+ +r1s*x2-r2s*x2-x1*x2)
+ /prop1s
+ -2.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1
+ +2.*r2s*x1+2.*r1s*x2-r2s*x2-x1*x2)
+ /prop12
+ -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1
+ +x2+3.*r1s*x2-r2s*x2-x1*x2)
+ /prop2s;
+ isSet4 = true;
+ }
+ break;
+
+ // q -> q S.
+ case 5:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.+r1s-r2s+2.*r1);
+ rFO1 = (4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
+ -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
+ /x3s
+ -2.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1
+ +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop23
+ +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
+ -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop2s;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.+r1s-r2s-2.*r1);
+ rFO2 = (4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
+ +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
+ /x3s
+ -2.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1
+ +r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop23
+ +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
+ -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop2s;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.+r1s-r2s);
+ rFO4 = (4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2
+ -r2s*x2+x1*x2+x2s)
+ /x3s
+ -2.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2
+ -r2s*x2+x1*x2+x2s)
+ /prop23
+ +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
+ -r2s*x2+x1*x2+x2s)
+ /prop2s;
+ isSet4 = true;
+ }
+ break;
+
+ // V -> ~q ~qbar (~q = squark).
+ case 6:
+ rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
+ rFO1 = 2.*3.+(1.+r1s+r2s-x1)*(4.*r1s-x1s)
+ /prop1s
+ +2.*(-1.-3.*r1s-r2s+x1+x1s*0.5+x2-x1*x2*0.5)
+ /prop1
+ +(1.+r1s+r2s-x2)*(4.*r2s-x2s)
+ /prop2s
+ +2.*(-1.-r1s-3.*r2s+x1+x2-x1*x2*0.5+x2s*0.5)
+ /prop2
+ -(-4.*r1s-4.*r1q-4.*r2s-8.*r1s*r2s-4.*r2q+2.*x1+6.*r1s*x1
+ +6.*r2s*x1-2.*x1s+2.*x2+6.*r1s*x2+6.*r2s*x2-4.*x1*x2
+ -2.*r1s*x1*x2-2.*r2s*x1*x2+x1s*x2-2.*x2s+x1*x2s)
+ /prop12;
+ isSet1 = true;
+ break;
+
+ // ~q -> ~q V.
+ case 7:
+ rLO1 = ps*(1.-2.*r1s+r1q-2.*r2s-2.*r1s*r2s+r2q);
+ rFO1 = 16.*r2s-8.*(4.*r2s+2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2
+ -2.*x2s)
+ /(3.*prop2)
+ +8.*(1.+r1s+r2s-x2)*(4.*r2s-x2s)
+ /(3.*prop2s)
+ +8.*(x1+x2)*(-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1
+ +2.*r1s*x1+2.*r2s*x1-x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-2.*x1*x2-x2s)
+ /(3.*x3s)
+ +8.*(-1.-r1s+r2s-x1)*(2.*r2s*x1+x2+r1s*x2+r2s*x2-x1*x2-x2s)
+ /(3.*prop2*x3)
+ -8.*(1.+2.*r1s+r1q+2.*r2s-2.*r1s*r2s+r2q-2.*x1-2.*r1s*x1
+ -4.*r2s*x1+x1s-3.*x2-3.*r1s*x2-3.*r2s*x2+3.*x1*x2+2.*x2s)
+ /(3.*x3);
+ rFO1 = 3.*rFO1/8.;
+ isSet1 = true;
+ break;
+
+ // S -> ~q ~qbar.
+ case 8:
+ rLO1 = ps;
+ rFO1 = (-1.-2.*r1s-r1q-2.*r2s+2.*r1s*r2s-r2q+2.*x1+2.*r1s*x1
+ +2.*r2s*x1-x1s-r2s*x1s+2.*x2+2.*r1s*x2+2.*r2s*x2-3.*x1*x2
+ -r1s*x1*x2-r2s*x1*x2+x1s*x2-x2s-r1s*x2s+x1*x2s)
+ /(prop1s*prop2s);
+ rFO1 = 2.*rFO1;
+ isSet1 = true;
+ break;
+
+ // ~q -> ~q S.
+ case 9:
+ rLO1 = ps;
+ rFO1 = (-1.-r1s-r2s+x2)
+ /prop2s
+ +(1.+r1s-r2s+x1)
+ /prop23
+ -(x1+x2)
+ /x3s;
+ isSet1 = true;
+ break;
+
+ // chi -> q ~qbar (chi = neutralino/chargino).
+ case 10:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.+r1s-r2s+2.*r1);
+ rFO1 = (2.*r1+x1)*(-1.-r1s-r2s+x1)
+ /prop1s
+ +2.*(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1
+ -r1s*x1*0.5-r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
+ /prop12
+ +(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1
+ -r2s*x1-3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop2s;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.-2.*r1+r1s-r2s);
+ rFO2 = (2.*r1-x1)*(1.+r1s+r2s-x1)
+ /prop1s
+ +2.*(-1.-r1s+2.*r1c-r2s+2.*r1*r2s+3.*x1*0.5-r1*x1
+ -r1s*x1*0.5-r2s*x1*0.5+x2-r1*x2+r1s*x2-x1*x2*0.5)
+ /prop12
+ +(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1
+ -r2s*x1-3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)/
+ prop2s;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.+r1s-r2s);
+ rFO4 = x1*(-1.-r1s-r2s+x1)
+ /prop1s
+ +2.*(-1.-r1s-r2s+3.*x1*0.5-r1s*x1*0.5-r2s*x1*0.5
+ +x2+r1s*x2-x1*x2*0.5)
+ /prop12
+ +(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2
+ -r2s*x2+x1*x2+x2s)
+ /prop2s;
+ isSet4 = true;
+ }
+ break;
+
+ // ~q -> q chi.
+ case 11:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.-pow2(r1+r2));
+ rFO1 = (1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
+ /x3s
+ -(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
+ -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
+ /prop2s
+ +(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
+ -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
+ /prop23;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.-pow2(r1-r2));
+ rFO2 = (1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
+ /x3s
+ -(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
+ -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
+ /prop2s
+ +(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1
+ +2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
+ /prop23;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.-r1s-r2s);
+ rFO4 = (1.+r1s+r2s-x1-x2)*(x1+x2)
+ /x3s
+ -(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2
+ +3.*r1s*x2-r2s*x2-x1*x2)
+ /prop2s
+ +(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
+ +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
+ /prop23;
+ isSet4 = true;
+ }
+ break;
+
+ // q -> ~q chi.
+ case 12:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.-r1s+r2s+2.*r2);
+ rFO1 = (2.*r2+x2)*(-1.-r1s-r2s+x2)
+ /prop2s
+ +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
+ -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
+ /x3s
+ +2.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2
+ +r1s*x2-x1*x2*0.5-x2s*0.5)
+ /prop23;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.-r1s+r2s-2.*r2);
+ rFO2 = (2.*r2-x2)*(1.+r1s+r2s-x2)
+ /prop2s
+ +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1+x1s
+ -3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
+ /x3s
+ +2.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2
+ +r1s*x2-x1*x2*0.5-x2s*0.5)
+ /prop23;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.-r1s+r2s);
+ rFO4 = x2*(-1.-r1s-r2s+x2)
+ /prop2s
+ +(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s
+ -3.*x2-r1s*x2+r2s*x2+x1*x2)
+ /x3s
+ +2.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2
+ +r1s*x2-x1*x2*0.5-x2s*0.5)
+ /prop23;
+ isSet4 = true;
+ }
+ break;
+
+ // ~g -> q ~qbar.
+ case 13:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.+r1s-r2s+2.*r1);
+ rFO1 = 4.*(2.*r1+x1)*(-1.-r1s-r2s+x1)
+ /(3.*prop1s)
+ -(-1.-r1s-2.*r1c-r2s-2.*r1*r2s+3.*x1*0.5+r1*x1-r1s*x1*0.5
+ -r2s*x1*0.5+x2+r1*x2+r1s*x2-x1*x2*0.5)
+ /(3.*prop12)
+ +3.*(-1.+r1-r1s-r1c-r2s+r1*r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1*x2
+ +r1s*x2-x1*x2*0.5)
+ /prop13
+ +3.*(4.-4.*r1s+4.*r2s-3.*x1-2.*r1*x1+r1s*x1-r2s*x1-5.*x2
+ -2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
+ /x3s
+ -3.*(3.-r1-5.*r1s-r1c+3.*r2s+r1*r2s-2.*x1-r1*x1+r1s*x1
+ -4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop23
+ +4.*(2.-2.*r1-6.*r1s-2.*r1c+2.*r2s-2.*r1*r2s-x1+r1s*x1-r2s*x1
+ -3.*x2+2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /(3.*prop2s);
+ rFO1 = 3.*rFO1/4.;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.+r1s-r2s-2.*r1);
+ rFO2 = 4.*(2.*r1-x1)*(1.+r1s+r2s-x1)
+ /(3.*prop1s)
+ +3.*(-1.-r1-r1s+r1c-r2s-r1*r2s+2.*x1+r2s*x1-x1s*0.5
+ +x2-r1*x2+r1s*x2-x1*x2*0.5)
+ /prop13
+ +(2.+2.*r1s-4.*r1c+2.*r2s-4.*r1*r2s-3.*x1+2.*r1*x1
+ +r1s*x1+r2s*x1-2.*x2+2.*r1*x2-2.*r1s*x2+x1*x2)
+ /(6.*prop12)
+ +3.*(4.-4.*r1s+4.*r2s-3.*x1+2.*r1*x1+r1s*x1-r2s*x1-5.*x2
+ +2.*r1*x2+r1s*x2-r2s*x2+x1*x2+x2s)
+ /x3s
+ -3.*(3.+r1-5.*r1s+r1c+3.*r2s-r1*r2s-2.*x1+r1*x1+r1s*x1-4.*x2
+ +2.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop23
+ +4.*(2.+2.*r1-6.*r1s+2.*r1c+2.*r2s+2.*r1*r2s-x1+r1s*x1-r2s*x1
+ -3.*x2-2.*r1*x2+3.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /(3.*prop2s);
+ rFO2 = 3.*rFO2/4.;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.+r1s-r2s);
+ rFO4 = 8.*x1*(-1.-r1s-r2s+x1)
+ /(3.*prop1s)
+ +6.*(-1-r1s-r2s+2.*x1+r2s*x1-x1s*0.5+x2+r1s*x2-x1*x2*0.5)
+ /prop13
+ +(2.+2.*r1s+2.*r2s-3.*x1+r1s*x1+r2s*x1-2.*x2-2.*r1s*x2+x1*x2)
+ /(3.*prop12)
+ +6.*(4.-4.*r1s+4.*r2s-3.*x1+r1s*x1-r2s*x1-5.*x2+r1s*x2-r2s*x2
+ +x1*x2+x2s)
+ /x3s
+ -6.*(3.-5.*r1s+3.*r2s-2.*x1+r1s*x1-4.*x2+2.*r1s*x2-r2s*x2+x1*x2+x2s)
+ /prop23
+ +8.*(2.-6.*r1s+2.*r2s-x1+r1s*x1-r2s*x1-3.*x2+3.*r1s*x2-r2s*x2
+ +x1*x2+x2s)
+ /(3.*prop2s);
+ rFO4 = 3.*rFO4/8.;
+ isSet4 = true;
+ }
+ break;
+
+ // ~q -> q ~g.
+ case 14:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.-r1s-r2s-2.*r1*r2);
+ rFO1 = 64.*(1.+r1s+2.*r1*r2+r2s-x1-x2)*(x1+x2)
+ /(9.*x3s)
+ -16.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q
+ +x1-r1s*x1+2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
+ /prop1s
+ -16.*(r1s+r1q-2.*r1c*r2+r2s-6.*r1s*r2s-2.*r1*r2c+r2q-r1s*x1
+ +r1*r2*x1+2.*r2s*x1+2.*r1s*x2+r1*r2*x2-r2s*x2-x1*x2)
+ /prop12
+ -64.*(-1.+r1q-2.*r1*r2-2.*r1c*r2-6.*r1s*r2s-2.*r1*r2c+r2q+x1
+ -r1s*x1+r2s*x1+x2+3.*r1s*x2+2.*r1*r2*x2-r2s*x2-x1*x2)
+ /(9.*prop2s)
+ +8.*(-1.+r1q-2.*r1*r2+2.*r1c*r2-2.*r2s-2.*r1*r2c-r2q-2.*r1s*x1
+ +2.*r2s*x1+x1s+x2-3.*r1s*x2-2.*r1*r2*x2+r2s*x2+x1*x2)
+ /prop13
+ -8.*(-1.-2.*r1s-r1q-2.*r1*r2-2.*r1c*r2+2.*r1*r2c+r2q+x1+r1s*x1
+ -2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
+ /(9.*prop23);
+ rFO1 = 9.*rFO1/64.;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.-r1s-r2s+2.*r1*r2);
+ rFO2 = 64.*(1.+r1s-2.*r1*r2+r2s-x1-x2)*(x1+x2)
+ /(9.*x3s)
+ -16.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
+ -r1s*x1-2.*r1*r2*x1+3.*r2s*x1+x2+r1s*x2-r2s*x2-x1*x2)
+ /prop1s
+ -64.*(-1.+r1q+2.*r1*r2+2.*r1c*r2-6.*r1s*r2s+2.*r1*r2c+r2q+x1
+ -r1s*x1+r2s*x1+x2+3.*r1s*x2-2.*r1*r2*x2-r2s*x2-x1*x2)
+ /(9.*prop2s)
+ +16.*(-r1s-r1q-2.*r1c*r2-r2s+6.*r1s*r2s-2.*r1*r2c-r2q+r1s*x1
+ +r1*r2*x1-2.*r2s*x1-2.*r1s*x2+r1*r2*x2+r2s*x2+x1*x2)
+ /prop12
+ +8.*(-1.+r1q+2.*r1*r2-2.*r1c*r2-2.*r2s+2.*r1*r2c-r2q-2.*r1s*x1
+ +2.*r2s*x1+x1s+x2-3.*r1s*x2+2.*r1*r2*x2+r2s*x2+x1*x2)
+ /prop13
+ -8.*(-1.-2.*r1s-r1q+2.*r1*r2+2.*r1c*r2-2.*r1*r2c+r2q+x1+r1s*x1+
+ 2.*r1*r2*x1-3.*r2s*x1+2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
+ /(9.*prop23);
+ rFO2 = 9.*rFO2/64.;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.-r1s-r2s);
+ rFO4 = 128.*(1.+r1s+r2s-x1-x2)*(x1+x2)
+ /(9.*x3s)
+ -32*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+3.*r2s*x1+x2
+ +r1s*x2-r2s*x2-x1*x2)
+ /prop1s
+ -32.*(r1s+r1q+r2s-6.*r1s*r2s+r2q-r1s*x1+2.*r2s*x1+2.*r1s*x2
+ -r2s*x2-x1*x2)
+ /prop12
+ -128.*(-1.+r1q-6.*r1s*r2s+r2q+x1-r1s*x1+r2s*x1+x2+3.*r1s*x2
+ -r2s*x2-x1*x2)
+ /(9.*prop2s)
+ +16.*(-1.+r1q-2.*r2s-r2q-2.*r1s*x1+2.*r2s*x1+x1s
+ +x2-3.*r1s*x2+r2s*x2+x1*x2)
+ /prop13
+ -16.*(-1.-2.*r1s-r1q+r2q+x1+r1s*x1-3.*r2s*x1
+ +2.*r1s*x2-2.*r2s*x2+x1*x2+x2s)
+ /(9.*prop23);
+ rFO4 = 9.*rFO4/128.;
+ isSet4 = true;
+ }
+ break;
+
+ // q -> ~q ~g.
+ case 15:
+ if (combi == 1 || combi == 3) {
+ rLO1 = ps*(1.-r1s+r2s+2.*r2);
+ rFO1 = 32*(2.*r2+x2)*(-1.-r1s-r2s+x2)
+ /(9.*prop2s)
+ +8.*(-1.-r1s-2.*r1s*r2-r2s-2.*r2c+x1+r2*x1+r2s*x1
+ +3.*x2*0.5-r1s*x2*0.5+r2*x2-r2s*x2*0.5-x1*x2*0.5)
+ /prop12
+ +8.*(2.+2.*r1s-2.*r2-2.*r1s*r2-6.*r2s-2.*r2c-3.*x1-r1s*x1
+ +2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
+ /prop1s
+ +32.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1-2.*r2*x1+r2s*x1+x1s
+ -3.*x2-r1s*x2-2.*r2*x2+r2s*x2+x1*x2)
+ /(9.*x3s)
+ -8.*(3.+3.*r1s-r2+r1s*r2-5.*r2s-r2c-4.*x1-r1s*x1
+ +2.*r2s*x1+x1s-2.*x2-r2*x2+r2s*x2+x1*x2)
+ /prop13
+ -8.*(-1.-r1s+r2+r1s*r2-r2s-r2c+x1+r2*x1+r2s*x1+2.*x2+r1s*x2
+ -x1*x2*0.5-x2s*0.5)
+ /(9.*prop23);
+ rFO1 = 9.*rFO1/32.;
+ isSet1 = true;
+ }
+ if (combi == 2 || combi == 3) {
+ rLO2 = ps*(1.-r1s+r2s-2.*r2);
+ rFO2 = 32*(2.*r2-x2)*(1.+r1s+r2s-x2)
+ /(9.*prop2s)
+ +8.*(-1.-r1s+2.*r1s*r2-r2s+2.*r2c+x1-r2*x1+r2s*x1
+ +3.*x2*0.5-r1s*x2*0.5-r2*x2-r2s*x2*0.5-x1*x2*0.5)
+ /prop12
+ +8.*(2.+2.*r1s+2.*r2+2.*r1s*r2-6.*r2s+2.*r2c-3.*x1-r1s*x1
+ -2.*r2*x1+3.*r2s*x1+x1s-x2-r1s*x2+r2s*x2+x1*x2)
+ /prop1s
+ -8.*(3.+3.*r1s+r2-r1s*r2-5.*r2s+r2c-4.*x1-r1s*x1+2.*r2s*x1+x1s
+ -2.*x2+r2*x2+r2s*x2+x1*x2)
+ /prop13
+ +32*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+2.*r2*x1+r2s*x1
+ +x1s-3.*x2-r1s*x2+2.*r2*x2+r2s*x2+x1*x2)
+ /(9.*x3s)
+ -8.*(-1.-r1s-r2-r1s*r2-r2s+r2c+x1-r2*x1+r2s*x1+2.*x2+r1s*x2
+ -x1*x2*0.5-x2s*0.5)
+ /(9.*prop23);
+ rFO2 = 9.*rFO2/32.;
+ isSet2 = true;
+ }
+ if (combi == 4) {
+ rLO4 = ps*(1.-r1s+r2s);
+ rFO4 = 64.*x2*(-1.-r1s-r2s+x2)
+ /(9.*prop2s)
+ +16.*(-1.-r1s-r2s+x1+r2s*x1+3.*x2*0.5-r1s*x2*0.5
+ -r2s*x2*0.5-x1*x2*0.5)
+ /prop12
+ -16.*(3.+3.*r1s-5.*r2s-4.*x1-r1s*x1+2.*r2s*x1+x1s-2.*x2+r2s*x2
+ +x1*x2)
+ /prop13
+ +64.*(4.+4.*r1s-4.*r2s-5.*x1-r1s*x1+r2s*x1+x1s-3.*x2
+ -r1s*x2+r2s*x2+x1*x2)
+ /(9.*x3s)
+ +16.*(2.+2.*r1s-6.*r2s-3.*x1-r1s*x1+3.*r2s*x1+x1s
+ -x2-r1s*x2+r2s*x2+x1*x2)
+ /prop1s
+ -16.*(-1.-r1s-r2s+x1+r2s*x1+2.*x2+r1s*x2-x1*x2*0.5-x2s*0.5)
+ /(9.*prop23);
+ rFO4 = 9.*rFO4/64.;
+ isSet4 = true;
+ }
+ break;
+
+ // g -> ~g ~g. Use (9/4)*eikonal. May be changed in the future.
+ case 16:
+ rLO = ps;
+ if (combi == 2) offset = x3s;
+ else if (combi == 3) offset = mix * x3s;
+ else if (combi == 4) offset = 0.5 * x3s;
+ rFO = ps * 4.5 * ( (x1+x2-1.+offset-r1s-r2s)/prop12
+ - r1s/prop2s - r2s/prop1s );
+ break;
+
+ // Eikonal expression for kind == 1; also acts as default.
+ default:
+ rLO = ps;
+ if (combi == 2) offset = x3s;
+ else if (combi == 3) offset = mix * x3s;
+ else if (combi == 4) offset = 0.5 * x3s;
+ rFO = ps * 2. * ( (x1+x2-1.+offset-r1s-r2s)/prop12
+ - r1s/prop2s - r2s/prop1s );
+ break;
+
+ // End of ME cases.
+ }
+
+ // Find relevant leading and first order expressions.
+ if (combi == 1 && isSet1) {
+ rLO = rLO1;
+ rFO = rFO1; }
+ else if (combi == 2 && isSet2) {
+ rLO = rLO2;
+ rFO = rFO2; }
+ else if (combi == 3 && isSet1 && isSet2) {
+ rLO = mix * rLO1 + (1.-mix) * rLO2;
+ rFO = mix * rFO1 + (1.-mix) * rFO2; }
+ else if (isSet4) {
+ rLO = rLO4;
+ rFO = rFO4; }
+ else if (combi == 4 && isSet1 && isSet2) {
+ rLO = 0.5 * (rLO1 + rLO2);
+ rFO = 0.5 * (rFO1 + rFO2); }
+ else if (isSet1) {
+ rLO = rLO1;
+ rFO = rFO1; }
+
+ // Return ratio of first to leading order cross section.
+ return rFO / rLO;
+}
+
+//*********
+
+// Find coefficient of azimuthal asymmetry from gluon polarization.
+
+void TimeShower::findAsymPol( Event& event, TimeDipoleEnd* dip) {
+
+ // Default is no asymmetry. Only gluons are studied.
+ dip->asymPol = 0.;
+ dip->iAunt = 0;
+ int iRad = dip->iRadiator;
+ if (!doPhiPolAsym || event[iRad].id() != 21) return;
+
+ // Trace grandmother via possibly intermediate recoil copies.
+ int iMother = event.iTopCopy(iRad);
+ int iGrandM = event[iMother].mother1();
+
+ // Check grandmother flavour and set aunt.
+ if (!event[iGrandM].isQuark() && !event[iGrandM].isGluon()) return;
+ dip->iAunt = (event[iGrandM].daughter1() == iMother)
+ ? event[iGrandM].daughter2() : event[iGrandM].daughter1();
+
+ // Coefficient from gluon production (approximate z by energy).
+ double zProd = event[iRad].e() / (event[iRad].e()
+ + event[dip->iAunt].e());
+ if (event[iGrandM].id() != 21) dip->asymPol = 2. * (1. - zProd)
+ / (1. + pow2(1. - zProd) );
+ else dip->asymPol = pow2( (1. - zProd) / (1. - zProd * (1. - zProd) ) );
+
+ // Coefficients from gluon decay.
+ if (dip->flavour == 21) dip->asymPol *= pow2( (1. - dip->z)
+ / (1. - dip->z * (1. - dip->z) ) );
+ else dip->asymPol *= -2. * dip->z *( 1. - dip->z )
+ / (1. - 2. * dip->z * (1. - dip->z) );
+
+}
+
+//*********
+
+// Print the list of dipoles.
+
+void TimeShower::list(ostream& os) {
+
+ // Header.
+ os << "\n -------- PYTHIA TimeShower Dipole Listing ----------------"
+ << "----------------------------------- \n \n i rad rec "
+ << " pTmax col chg gam oni isr sys type MErec mix or"
+ << "d spl ~gR \n" << fixed << setprecision(3);
+
+ // Loop over dipole list and print it.
+ for (int i = 0; i < int(dipEnd.size()); ++i)
+ os << setw(5) << i << setw(7) << dipEnd[i].iRadiator
+ << setw(7) << dipEnd[i].iRecoiler << setw(12) << dipEnd[i].pTmax
+ << setw(5) << dipEnd[i].colType << setw(5) << dipEnd[i].chgType
+ << setw(5) << dipEnd[i].gamType << setw(5) << dipEnd[i].isOctetOnium
+ << setw(5) << dipEnd[i].isrType << setw(5) << dipEnd[i].system
+ << setw(5) << dipEnd[i].MEtype << setw(7) << dipEnd[i].iMEpartner
+ << setw(8) << dipEnd[i].MEmix << setw(5) << dipEnd[i].MEorder
+ << setw(5) << dipEnd[i].MEsplit << setw(5) << dipEnd[i].MEgluinoRec
+ << "\n";
+
+ // Done.
+ os << "\n -------- End PYTHIA TimeShower Dipole Listing ------------"
+ << "-----------------------------------" << endl;
+
+}
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+// UserHooks.cc is a part of the PYTHIA event generator.
+// Copyright (C) 2008 Torbjorn Sjostrand.
+// PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
+// Please respect the MCnet Guidelines, see GUIDELINES for details.
+
+// Function definitions (not found in the header) for the UserHooks class.
+
+#include "UserHooks.h"
+
+namespace Pythia8 {
+
+//**************************************************************************
+
+// The UserHooks class.
+
+//*********
+
+// multiplySigmaBy allows the user to introduce a multiplicative factor
+// that modifies the cross section of a hard process. Since it is called
+// from before the event record is generated in full, the normal analysis
+// does not work. The code here provides a rather extensive summary of
+// which methods actually do work. It is a convenient starting point for
+// writing your own derived routine.
+
+double UserHooks::multiplySigmaBy( const SigmaProcess* sigmaProcessPtr,
+ const PhaseSpace* phaseSpacePtr, bool inEvent) {
+
+ // Process code, necessary when some to be treated differently.
+ //int code = sigmaProcessPtr->code();
+
+ // Final multiplicity, i.e. whether 2 -> 1 or 2 -> 2.
+ //int nFinal = sigmaProcessPtr->nFinal();
+
+ // Incoming x1 and x2 to the hard collision, and factorization scale.
+ //double x1 = phaseSpacePtr->x1();
+ //double x2 = phaseSpacePtr->x2();
+ //double Q2Fac = sigmaProcessPtr->Q2Fac();
+
+ // Renormalization scale and assumed alpha_strong and alpha_EM.
+ //double Q2Ren = sigmaProcessPtr->Q2Ren();
+ //double alphaS = sigmaProcessPtr->alphaSRen();
+ //double alphaEM = sigmaProcessPtr->alphaEMRen();
+
+ // Subprocess mass-square.
+ //double sHat = phaseSpacePtr->sHat();
+
+ // Now methods only relevant for 2 -> 2.
+ //if (nFinal == 2) {
+
+ // Mandelstam variables and hard-process pT.
+ //double tHat = phaseSpacePtr->tHat();
+ //double uHat = phaseSpacePtr->uHat();
+ //double pTHat = phaseSpacePtr->pTHat();
+
+ // Masses of the final-state particles. (Here 0 for light quarks.)
+ //double m3 = sigmaProcessPtr->m(3);
+ //double m4 = sigmaProcessPtr->m(4);
+ //}
+
+ // Dummy statement to avoid compiler warnings.
+ return ((inEvent && sigmaProcessPtr->code() == 0
+ && phaseSpacePtr->sHat() < 0.) ? 0. : 1.);
+
+}
+
+//*********
+
+// subEvent extracts currently resolved partons in the hard process.
+
+void UserHooks::subEvent(const Event& event, bool isHardest) {
+
+ // Reset work event to be empty.
+ workEvent.clear();
+
+ // Find which subsystem to study.
+ int iSys = 0;
+ if (!isHardest) iSys = event.sizeSystems() - 1;
+
+ // Loop through all the final partons of the given subsystem.
+ for (int i = 2; i < event.sizeSystem(iSys); ++i) {
+ int iOld = event.getInSystem( iSys, i);
+
+ // Copy partons to work event.
+ int iNew = workEvent.append( event[iOld]);
+
+ // No mothers. Position in full event as daughters.
+ workEvent[iNew].mothers( 0, 0);
+ workEvent[iNew].daughters( iOld, iOld);
+ }
+
+}
+
+//**************************************************************************
+
+// The SuppressSmallPT class, derived from UserHooks.
+
+//*********
+
+// Modify event weight at the trial level, before selection.
+
+double SuppressSmallPT::multiplySigmaBy( const SigmaProcess* sigmaProcessPtr,
+ const PhaseSpace* phaseSpacePtr, bool ) {
+
+ // Need to initialize first time this method is called.
+ if (!isInit) {
+
+ // Calculate pT0 as for multiple interactions.
+ // Fudge factor allows offset relative to MI framework.
+ double eCM = phaseSpacePtr->ecm();
+ double pT0Ref = Settings::parm("MultipleInteractions:pT0Ref");
+ double ecmRef = Settings::parm("MultipleInteractions:ecmRef");
+ double ecmPow = Settings::parm("MultipleInteractions:ecmPow");
+ double pT0 = pT0timesMI * pT0Ref * pow(eCM / ecmRef, ecmPow);
+ pT20 = pT0 * pT0;
+
+ // Initialize alpha_strong object as for multiple interactions,
+ // alternatively as for hard processes.
+ double alphaSvalue;
+ int alphaSorder;
+ if (useSameAlphaSasMI) {
+ alphaSvalue = Settings::parm("MultipleInteractions:alphaSvalue");
+ alphaSorder = Settings::mode("MultipleInteractions:alphaSorder");
+ } else {
+ alphaSvalue = Settings::parm("SigmaProcess:alphaSvalue");
+ alphaSorder = Settings::mode("SigmaProcess:alphaSorder");
+ }
+ alphaS.init( alphaSvalue, alphaSorder);
+
+ // Initialization finished.
+ isInit = true;
+ }
+
+ // Only modify 2 -> 2 processes.
+ int nFinal = sigmaProcessPtr->nFinal();
+ if (nFinal != 2) return 1.;
+
+ // pT scale of process. Weight pT^4 / (pT^2 + pT0^2)^2
+ double pTHat = phaseSpacePtr->pTHat();
+ double pT2 = pTHat * pTHat;
+ double wt = pow2( pT2 / (pT20 + pT2) );
+
+ if (numberAlphaS > 0) {
+ // Renormalization scale and assumed alpha_strong.
+ double Q2RenOld = sigmaProcessPtr->Q2Ren();
+ double alphaSOld = sigmaProcessPtr->alphaSRen();
+
+ // Reweight to new alpha_strong at new scale.
+ double Q2RenNew = pT20 + Q2RenOld;
+ double alphaSNew = alphaS.alphaS(Q2RenNew);
+ wt *= pow( alphaSNew / alphaSOld, numberAlphaS);
+ }
+
+ // End weight calculation.
+ return wt;
+
+}
+
+
+//**************************************************************************
+
+} // end namespace Pythia8
--- /dev/null
+<chapter name="A Second Hard Process">
+
+<h2>A Second Hard Process</h2>
+
+When you have selected a set of hard processes for hadron beams, the
+<aloc href="MultipleInteractions">multiple interactions</aloc>
+framework can add further interactions to build up a realistic
+underlying event. These further interactions can come from a wide
+variety of processes, and will occasionally be quite hard. They
+do represent a realistic random mix, however, which means one cannot
+predetermine what will happen. Occasionally there may be cases
+where one wants to specify also the second hard interaction rather
+precisely. The options on this page allow you to do precisely that.
+
+<flag name="SecondHard:generate" default="off">
+Generate two hard scatterings in a collision between hadron beams.
+You must further specify which set of processes to allow for
+the second, see below.
+</flag>
+
+<p/>
+In principle the whole <aloc href="ProcessSelection">process
+selection</aloc> allowed for the first process could be repeated
+for the second one. However, this would probably be overkill.
+Therefore here a more limited set of prepackaged process collections
+are made available, that can then be further combined at will.
+Since the description is almost completely symmetric between the
+first and the second process, you always have the possibility
+to pick one of the two processes according to the complete list
+of possibilities.
+
+<p/>
+Here comes the list of allowed sets of processes, to combine at will:
+
+<flag name="SecondHard:TwoJets" default="off">
+Standard QCD <ei>2 -> 2</ei> processes involving gluons and
+<ei>d, u, s, c, b</ei> quarks.
+</flag>
+
+<flag name="SecondHard:PhotonAndJet" default="off">
+A prompt photon recoiling against a quark or gluon jet.
+
+<flag name="SecondHard:TwoPhotons" default="off">
+Two prompt photons recoiling against each other.
+
+
+<flag name="SecondHard:SingleGmZ" default="off">
+Scattering <ei>q qbar -> gamma^*/Z^0</ei>, with full interference
+between the <ei>gamma^*</ei> and <ei>Z^0</ei>.
+</flag>
+
+<flag name="SecondHard:SingleW" default="off">
+Scattering <ei>q qbar' -> W^+-</ei>.
+</flag>
+
+<flag name="SecondHard:GmZAndJet" default="off">
+Scattering <ei>q qbar -> gamma^*/Z^0 g</ei> and
+<ei>q g -> gamma^*/Z^0 q</ei>.
+</flag>
+
+<flag name="SecondHard:WAndJet" default="off">
+Scattering <ei>q qbar' -> W^+- g</ei> and
+<ei>q g -> W^+- q'</ei>.
+</flag>
+
+<p/>
+A further process collection comes with a warning flag:
+
+<flag name="SecondHard:TwoBJets" default="off">
+The <ei>q qbar -> b bbar</ei> and <ei>g g -> b bbar</ei> processes.
+These are already included in the <code>TwoJets</code> sample above,
+so it would be doublecounting to include both, but we assume there
+may be cases where the <ei>b</ei> subsample will be of special interest.
+This subsample does not include flavour-excitation or gluon-splitting
+contributions to the <ei>b</ei> rate, however, so, depending
+on the topology if interest, it may or may not be a good approximation.
+</flag>
+
+<p/>
+The second hard process obeys exactly the same selection rules for
+<aloc href="PhaseSpaceCuts">phase space cuts</aloc> and
+<aloc href="CouplingsAndScales">couplings and scales</aloc>
+as the first one does. Specifically, a <ei>pTmin</ei> cut for
+<ei>2 -> 2</ei> processes would apply to the first and the second hard
+process alike, and ballpark half of the time the second could be
+generated with a larger <ei>pT</ei> than the first. (Exact numbers
+depending on the relative shape of the two cross sections.) That is,
+first and second is only used as an administrative distinction between
+the two, not as a physics ordering one.
+
+<h3>Cross-section calculation</h3>
+
+As an introduction, a brief reminder of Poissonian statistics.
+Assume a stochastic process in time, for now not necessarily a
+high-energy physics one, where the probability for an event to occur
+at any given time is independent of what happens at other times.
+Then the probability for <ei>n</ei> events to occur in a finite
+time interval is
+<eq>
+P_n = <n>^n exp(-<n>) / n!
+</eq>
+where <ei><n></ei> is the average number of events. If this
+number is small we can approximate <ei>exp(-<n>) = 1 </ei>,
+so that <ei>P_1 = <n></ei> and
+<ei>P_2 = <n>^2 / 2 = P_1^2 / 2</ei>.
+
+<p/>
+Now further assume that the events actually are of two different
+kinds <ei>a</ei> and <ei>b</ei>, occuring independently of each
+other, such that <ei><n> = <n_a> + <n_b></ei>.
+It then follows that the probability of having one event of type
+<ei>a</ei> (or <ei>b</ei>) and nothing else is
+<ei>P_1a = <n_a></ei> (or <ei>P_1b = <n_b></ei>).
+From
+<eq>
+P_2 = (<n_a> + <n_b>)^2 / 2 = (P_1a + P_1b)^2 / 2 =
+(P_1a^2 + 2 P_1a P_1b + P_1b^2) / 2
+</eq>
+it is easy to read off that the probability to have exactly two
+events of kind <ei>a</ei> and none of <ei>b</ei> is
+<ei>P_2aa = P_1a^2 / 2</ei> whereas that of having one <ei>a</ei>
+and one <ei>b</ei> is <ei>P_2ab = P_1a P_1b</ei>. Note that the
+former, with two identical events, contains a factor <ei>1/2</ei>
+while the latter, with two different ones, does not. If viewed
+in a time-ordered sense, the difference is that the latter can be
+obtained two ways, either first an <ei>a</ei> and then a <ei>b</ei>
+or else first a <ei>b</ei> and then an <ei>a</ei>.
+
+<p/>
+To translate this language into cross-sections for high-energy
+events, we assume that interactions can occur at different <ei>pT</ei>
+values independently of each other inside inelastic nondiffractive
+(= "minbias") events. Then the above probabilities translate into
+<ei>P_n = sigma_n / sigma_ND</ei> where <ei>sigma_ND</ei> is the
+total nondiffractive cross section. Again we want to assume that
+<ei>exp(-<n>)</ei> is close to unity, i.e. that the total
+hard cross section above <ei>pTmin</ei> is much smaller than
+<ei>sigma_ND</ei>. The hard cross section is dominated by QCD
+jet production, and a reasonable precaution is to require a
+<ei>pTmin</ei> of at least 20 GeV at LHC energies.
+(For <ei>2 -> 1</ei> processes such as
+<ei>q qbar -> gamma^*/Z^0 (-> f fbar)</ei> one can instead make a
+similar cut on mass.) Then the generic equation
+<ei>P_2 = P_1^2 / 2</ei> translates into
+<ei>sigma_2/sigma_ND = (sigma_1 / sigma_ND)^2 / 2</ei> or
+<ei>sigma_2 = sigma_1^2 / (2 sigma_ND)</ei>.
+
+<p/>
+Again different processes <ei>a, b, c, ...</ei> contribute,
+and by the same reasoning we obtain
+<ei>sigma_2aa = sigma_1a^2 / (2 sigma_ND)</ei>,
+<ei>sigma_2ab = sigma_1a sigma_1b / sigma_ND</ei>,
+and so on.
+
+<p/>
+There is one important correction to this picture: all collisions
+do no occur under equal conditions. Some are more central in impact
+parameter, others more peripheral. This leads to a further element of
+variability: central collisions are likely to have more activity
+than the average, peripheral less. Integrated over impact
+parameter standard cross sections are recovered, but correlations
+are affected by a "trigger bias" effect: if you select for events
+with a hard process you favour events at small impact parameter
+which have above-average activity, and therefore also increased
+chance for further interactions. (In PYTHIA this is the origin
+of the "pedestal effect", i.e. that events with a hard interaction
+have more underlying activity than the level found in minimum-bias
+events.) When you specify a matter overlap profile in the
+multiple-interactions scenario, such an enhancement/depletion factor
+<ei>f_impact</ei> is chosen event-by-event and can be averaged
+during the course of the run. As an example, the double Gaussian
+form used in Tune A gives approximately
+<ei><f_impact> = 2.5</ei>. The above equations therefore
+have to be modified to
+<ei>sigma_2aa = <f_impact> sigma_1a^2 / (2 sigma_ND)</ei>,
+<ei>sigma_2ab = <f_impact> sigma_1a sigma_1b / sigma_ND</ei>.
+Experimentalists often instead use the notation
+<ei>sigma_2ab = sigma_1a sigma_1b / sigma_eff</ei>,
+from which we see that PYTHIA "predicts"
+<ei>sigma_eff = sigma_ND / <f_impact></ei>.
+When the generation of multiple interactions is switched off it is
+not possible to calculate <ei><f_impact></ei> and therefore
+it is set to unity.
+
+<p/>
+When this recipe is to be applied to calculate
+actual cross sections, it is useful to distinguish three cases,
+depending on which set of processes are selected to study for
+the first and second interaction.
+
+<p/>
+(1) The processes <ei>a</ei> for the first interaction and
+<ei>b</ei> for the second one have no overlap at all.
+For instance, the first could be <code>TwoJets</code> and the
+second <code>TwoPhotons</code>. In that case, the two interactions
+can be selected independently, and cross sections tabulated
+for each separate subprocess in the two above classes. At the
+end of the run, the cross sections in <ei>a</ei> should be multiplied
+by <ei><f_impact> sigma_1b / sigma_ND</ei> to bring them to
+the correct overall level, and those in <ei>b</ei> by
+<ei><f_impact> sigma_1a / sigma_ND</ei>.
+
+<p/>
+(2) Exactly the same processes <ei>a</ei> are selected for the
+first and second interaction. In that case it works as above,
+with <ei>a = b</ei>, and it is only necessary to multiply by an
+additional factor <ei>1/2</ei>. A compensating factor of 2
+is automatically obtained for picking two different subprocesses,
+e.g. if <code>TwoJets</code> is selected for both interactions,
+then the combination of the two subprocesses <ei>q qbar -> g g</ei>
+and <ei>g g -> g g</ei> can trivially be obtained two ways.
+
+<p/>
+(3) The list of subprocesses partly but not completely overlap.
+For instance, the first process is allowed to contain <ei>a</ei>
+or <ei>c</ei> and the second <ei>b</ei> or <ei>c</ei>, where
+there is no overlap between <ei>a</ei> and <ei>b</ei>. Then,
+when an independent selection for the first and second interaction
+both pick one of the subprocesses in <ei>c</ei>, half of those
+events have to be thrown, and the stored cross section reduced
+accordingly. Considering the four possible combinations of first
+and second process, this gives a
+<eq>
+sigma'_1 = sigma_1a + sigma_1c * (sigma_2b + sigma_2c/2) /
+(sigma_2b + sigma_2c)
+</eq>
+with the factor <ei>1/2</ei> for the <ei>sigma_1c sigma_2c</ei> term.
+At the end of the day, this <ei>sigma'_1</ei> should be multiplied
+by the normalization factor
+<eq>
+f_1norm = <f_impact> (sigma_2b + sigma_2c) / sigma_ND
+</eq>
+here without a factor <ei>1/2</ei> (or else it would have been
+doublecounted). This gives the correct
+<eq>
+(sigma_2b + sigma_2c) * sigma'_1 = sigma_1a * sigma_2b
++ sigma_1a * sigma_2c + sigma_1c * sigma_2b + sigma_1c * sigma_2c/2
+</eq>
+The second interaction can be handled in exact analogy.
+
+<p/>
+The listing obtained with the <code>pythia.statistics()</code>
+already contain these corrections factors, i.e. cross sections
+are for the occurence of two interactions of the specified kinds.
+There is not a full tabulation of the matrix of all the possible
+combinations of a specific first process together with a specific
+second one (but the information is there for the user to do that,
+if desired). Instead <code>pythia.statistics()</code> shows this
+matrix projected onto the set of processes and associated cross
+sections for the first and the second interaction, respectively.
+Up to statistical fluctuations, these two sections of the
+<code>pythia.statistics()</code> listing both add up to the same
+total cross section for the event sample.
+
+<p/>
+There is a further special feature to be noted for this listing,
+and that is the difference between the number of "selected" events
+and the number of "accepted" ones. Here is how that comes about.
+Originally the first and second process are selected completely
+independently. The generation (in)efficiency is reflected in the
+different number of intially tried events for the first and second
+process, leading to the same number of selected events. While
+acceptable on their own, the combination of the two processes may
+be unacceptable, however. It may be that the two processes added
+together use more energy-momentum than kinematically allowed, or,
+even if not, are disfavoured when the PYTHIA approach to provide
+correlated parton densities is applied. Alternatively, referring
+to case (3) above, it may be because half of the events should
+be thrown for identical processes. Taken together, it is these
+effects that reduced the event number from "selected" to "accepted".
+(A further reduction may occur if a
+<aloc href="UserHooks">user hook</aloc> rejects some events.)
+
+<p/>
+In the cross section calculation above, the <ei>sigma'_1</ei>
+cross sections are based on the number of accepted events, while
+the <ei>f_1norm</ei> factor is evaluated based on the cross sections
+for selected events. That way the suppression by correlations
+between the two processes does not get to be doublecounted.
+
+<p/>
+The <code>pythia.statistics()</code> listing contains two final
+lines, indicating the summed cross sections <ei>sigma_1sum</ei> and
+<ei>sigma_2sum</ei> for the first and second set of processes, at
+the "selected" stage above, plus information on the <ei>sigma_ND</ei>
+and <ei><f_impact></ei> used. The total cross section
+generated is related to this by
+<eq>
+<f_impact> * (sigma_1sum * sigma_2sum / sigma_ND) *
+(n_accepted / n_selected)
+</eq>
+ with an additional factor of <ei>1/2</ei> for case 2 above.
+
+<p/>
+The error quoted for the cross section of a process is a combination
+in quadrature of the error on this process alone with the error on
+the normalization factor, including the error on
+<ei><f_impact></ei>. As always it is a purely statistical one
+and of course hides considerably bigger systematic uncertainties.
+
+<h3>Event information</h3>
+
+Normally the <code>process</code> event record only contains the
+hardest interaction, but in this case also the second hardest
+is stored there. If both of them are <ei>2 -> 2</ei> ones, the
+first would be stored in lines 3 - 6 and the second in 7 - 10.
+For both, status codes 21 - 29 would be used, as for a hardest
+process. Any resonance decay chains would occur after the two
+main processes, to allow normal parsing. The beams in 1 and 2
+only appear in one copy. This structure is echoed in the
+full <code>event</code> event record.
+
+<p/>
+Most of the properties accessible by the
+<aloc href="EventInformation"><code>pythia.info</code></aloc>
+methods refer to the first process, whether that happens to be the
+hardest or not. The code and <ei>pT</ei> scale of the second process
+are accessible by the <code>info.codeMI(1)</code> and
+<code>info.pTMI(1)</code>, however.
+
+<p/>
+The <code>sigmaGen()</code> and <code>sigmaErr()</code> methods provide
+the cross section and its error for the event sample as a whole,
+combining the information from the two hard processes as described
+above. In particular, the former should be used to give the
+weight of the generated event sample. The statitical error estimate
+is somewhat cruder and gives a larger value than the
+subprocess-by-subprocess one employed in
+<code>pythia.statistics()</code>, but this number is
+anyway less relevant, since systematical errors are likely to dominate.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Accessing Pythia6 Processes">
+
+<h2>Access PYTHIA 6 Processes</h2>
+
+Gradually all relevant processes from PYTHIA 6 are being
+re-implemented in PYTHIA 8, but this transition is not finished.
+For a while longer it may therefore at times be convenient to
+access the Fortran PYTHIA 6 process library. In order to give
+this access at runtime, and not only by writing/reading event files,
+an interface is provided to C++. This interface is residing in
+<code>Pythia6Interface.h</code>, and in addition the PYTHIA 6 library
+must be linked. The latter should normally be the most recent
+Fortran PYTHIA version, but must be at least 6.314, since this is
+the first version that allows processes to be output in the Les
+Houches format (and not only input).
+
+<p/>
+The routines interfaced are
+<ul>
+<li><code>pygive(command)</code> to give in a command to change a
+setting, e.g. to decide which processes should be generated,
+<li><code>pyinit( frame, beam, target, wIn)</code> to initialize
+the event generation chain,</li>
+<li><code>pyupin()</code> to fill this initialization information
+in the <code>HEPRUP</code> commonblock,</li>
+<li><code>pyupev()</code> to generate the next hard process and
+fill the event information in the <code>HEPEUP</code> commonblock,</li>
+<li><code>pylist( mode)</code> to list the event at the process
+level,</li>
+<li><code>pystat( mode)</code> to print statistics on the event
+generation process.</li>
+</ul>
+Details on allowed arguments are given in the PYTHIA 6.4 manual.
+
+<p/>
+These methods can be used in context of the
+<aloc href="LesHouchesAccord"><code>LHAupFortran</code></aloc> class.
+The existing code there takes care of converting <code>HEPRUP</code>
+and <code>HEPEUP</code> commonblock information from Fortran to C++,
+and of making it available to the PYTHIA 8 methods. What needs to be
+supplied are the two <code>LHAupFortran::fillHepRup()</code> and
+<code>LHAupFortran::fillHepEup()</code> methods. The first can
+contain an arbitrary number of <code>pygive(...)</code>, followed
+by <code>pyinit(...)</code> and <code>pyupin()</code> in that order.
+The second only needs to contain <code>pyupev()</code>. Finally,
+the use of <code>pylist(...)</code> and <code>pystat(...)</code>
+is entirely optional, and calls are best put directly in the
+main program.
+
+<p/>
+This means that all other Fortran routines have not been interfaced
+and cannot be accessed directly from the C++ code; there is no need
+for them in the current setup.
+
+<p/>
+PYTHIA 6.4 does its own rejection of events internally, according to
+the strategy option 3. However, the current runtime interface does not
+take cross-section information from PYTHIA 6.4. This means that both
+the initial maxima and the final cross sections printed by the PYTHIA 8
+routines are irrelevant in this case. Instead you have to study the
+standard PYTHIA 6.4 initialization printout and call on
+<code>pystat(...)</code> at the end of the run to obtain this information.
+It also means that you cannot mix with internally generated events,
+unlike what could have been allowed for strategy 3. Should a strong need
+arise, PYTHIA 6.4 could be modified to work with strategy option 1 and
+thus allow a mixing with internal processes, but we do not expect this
+to happen.
+
+<p/>
+An example of a <code>fillHepRup()</code> method to set up
+<ei>Z^0</ei> production at LHC, with masses above 50 GeV, would be
+<pre>
+bool LHAinitFortran::fillHepRup() {
+ Pythia6Interface::pygive("msel = 11");
+ Pythia6Interface::pygive("ckin(1) = 50.");
+ Pythia6Interface::pyinit("cms","p","p",14000.);
+ Pythia6Interface::pyupin();
+ return true;
+}
+</pre>
+and the process-generic <code>fillHepEup()</code> method would be
+<pre>
+bool LHAupFortran::fillHepEup() {
+ Pythia6Interface::pyupev();
+ return true;
+}
+</pre>
+Note that, of all parameters that could be set with the
+<code>PYGIVE</code>, only those that influence the generation of the
+hard processes have any impact, since this is the only part of the
+Fortran code that is used. Also, if you want to set many parameters,
+you can easily collect them in one file (separate from PYTHIA 8
+input) and parse that file.
+
+<p/>
+All hard PYTHIA 6 processes should be available for full generation
+in PYTHIA 8, at least to the extent that they are defined for beams
+of protons and antiprotons, which is the key application for PYTHIA 8
+so far. Soft processes, i.e. elastic and diffractive scattering, as well
+as minimum-bias events, require a different kinematics machinery, and
+can only be generated with the internal PYTHIA 8 processes.
+
+<p/>
+A simple example is found in <code>main51.cc</code>, another with parsed
+input in <code>main52.cc</code> and a third with HepMC output in
+<code>main54.cc</code>.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Beam Parameters">
+
+<h2>Beam Parameters</h2>
+
+The settings on this page relate to the beam identities and energies,
+to a beam momentum spread and to a beam interaction spot.
+As always, momenta and energies are to be given in units of GeV,
+and of space and time in mm.
+
+<h3>Incoming beams</h3>
+
+There are two ways to set the identities and energies of the two incoming
+beam particles. One is to use the <code>init()</code> method with no
+arguments. Then the settings variables below will be read and used. The
+alternative is to call <code>init(...)</code> with arguments that provide
+this information. Then you need not use the variables below (although it
+would still be possible). Note that, if nothing is done, you will default
+to LHC at the nominal energy.
+
+<modeopen name="Beams:idA" default="2212">
+The PDG <code>id</code> code for the first incoming particle.
+</modeopen>
+
+<modeopen name="Beams:idB" default="2212">
+The PDG <code>id</code> code for the second incoming particle.
+</modeopen>
+
+<modepick name="Beams:frameType" default="1" min="1" max="4">
+Choice of frame for the two colliding particles.
+<option value="1">the beams are colliding in their cm frame,
+and therefore only the cm energy needs to be provided, see
+<code>Beams:eCM</code> below.
+</option>
+<option value="2">the beams are back-to-back, but with different energies,
+see <code>Beams:eA</code> and <code>Beams:eB</code> below.
+This option could also be used for fixed-target configurations.
+</option>
+<option value="3">the beams are not back-to-back, and therefore the
+three-momentum of each incoming particle needs to be specified, see
+<code>Beams:pxA</code> through <code>Beams:pzB</code> below.
+</option>
+<option value="4">the beam and event information is stored in a
+Les Houches Event File, see <code>Beams:LHEF</code> below.
+</option>
+</modepick>
+
+<parm name="Beams:eCM" default="14000." min="10.">
+Collision CM energy, to be set if <code>Beams:frameType</code> = 1.
+</parm>
+
+<parm name="Beams:eA" default="7000." min="0.">
+The energy of the first incoming particle, moving in the
+<ei>+z </ei>direction, to be set if <code>Beams:frameType</code> = 2.
+If the particle energy is smaller than its mass
+it is assumed to be at rest.
+</parm>
+
+<parm name="Beams:eB" default="7000." min="0.">
+The energy of the second incoming particle, moving in the
+<ei>-z</ei> direction, to be set if <code>Beams:frameType</code> = 2.
+If the particle energy is smaller than its mass
+it is assumed to be at rest.
+</parm>
+
+<parm name="Beams:pxA" default="0.">
+The <ei>p_x</ei> component of the first incoming particle,
+to be set if <code>Beams:frameType</code> = 3.
+</parm>
+
+<parm name="Beams:pyA" default="0.">
+The <ei>p_y</ei> component of the first incoming particle,
+to be set if <code>Beams:frameType</code> = 3.
+</parm>
+
+<parm name="Beams:pzA" default="7000.">
+The <ei>p_z</ei> component of the first incoming particle,
+to be set if <code>Beams:frameType</code> = 3.
+</parm>
+
+<parm name="Beams:pxB" default="0.">
+The <ei>p_x</ei> component of the second incoming particle,
+to be set if <code>Beams:frameType</code> = 3.
+</parm>
+
+<parm name="Beams:pyB" default="0.">
+The <ei>p_y</ei> component of the second incoming particle,
+to be set if <code>Beams:frameType</code> = 3.
+</parm>
+
+<parm name="Beams:pzB" default="-7000.">
+The <ei>p_z</ei> component of the second incoming particle,
+to be set if <code>Beams:frameType</code> = 3.
+</parm>
+
+<word name="Beams:LHEF" default="void">
+The name of a Les Houches Event File,
+to be set if <code>Beams:frameType</code> = 4.
+</word>
+
+<h3>Beam momentum spread</h3>
+
+This framework currently is intended for a modest beam spread, such as
+experienced at hadron colliders. Thus it can be safely assumed that the
+physics does not change over the CM energy range probed, so that the
+parameters of the physics initialization at the nominal energy can be
+used as is. Currently it can <b>not</b> be used for the more extensive
+energy spread expected at linear <ei>e^+ e^-</ei> colliders. Also,
+any attempt to combine it with external Les Houches input of
+parton-level events is at own risk.
+
+<p/>
+On this page you can set the momentum spread according to a simple
+Gaussian distribution. If you instead want a more sophisticated
+parametrization, you can write and link your own
+<aloc href="BeamShape"><code>BeamShape</code></aloc> class.
+
+<flag name="Beams:allowMomentumSpread" default="off">
+Allow the beam momenta to be smeared around their initialization
+nominal values.
+</flag>
+
+<parm name="Beams:sigmaPxA" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>p_x</ei> spread of the
+first incoming particle.
+</parm>
+
+<parm name="Beams:sigmaPyA" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>p_y</ei> spread of the
+first incoming particle.
+</parm>
+
+<parm name="Beams:sigmaPzA" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>p_z</ei> spread of the
+first incoming particle.
+</parm>
+
+<parm name="Beams:maxDevA" default="5." min="0.">
+The triply Gaussian distribution <ei>(p_x, p_y, p_z)</ei> is restricted to
+a maximal total deviation from the nominal values <ei>(p_x0, p_y0, p_z0)</ei>
+for the first incoming particle, like
+<eq>
+(p_x - p_x0)^2/sigma_px^2 + (p_y - p_y0)^2/sigma_py^2 +
+(p_z - p_z0)^2/sigma_pz^2 < maxDev^2
+</eq>
+(Note the absence of a factor 2 in the denominator, unlike the Gaussians
+used to pick <ei>(p_x, p_y, p_z)</ei>.)
+</parm>
+
+<parm name="Beams:sigmaPxB" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>p_x</ei> spread of the
+second incoming particle.
+</parm>
+
+<parm name="Beams:sigmaPyB" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>p_y</ei> spread of the
+second incoming particle.
+</parm>
+
+<parm name="Beams:sigmaPzB" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>p_z</ei> spread of the
+second incoming particle.
+</parm>
+
+<parm name="Beams:maxDevB" default="5." min="0.">
+The triply Gaussian distribution <ei>(p_x, p_y, p_z)</ei> is restricted to
+a maximal total deviation from the nominal values <ei>(p_x0, p_y0, p_z0)</ei>,
+for the second incoming particle, like
+<eq>
+(p_x - p_x0)^2/sigma_px^2 + (p_y - p_y0)^2/sigma_py^2 +
+(p_z - p_z0)^2/sigma_pz^2 < maxDev^2
+</eq>
+(Note the absence of a factor 2 in the denominator, unlike the Gaussians
+used to pick <ei>(p_x, p_y, p_z)</ei>.)
+</parm>
+
+<h3>Beam interaction vertex</h3>
+
+On this page you can set the spread of the interaction vertex according to
+a simple Gaussian distribution. If you instead want a more sophisticated
+parametrization, you can write and link your own
+<aloc href="BeamShape"><code>BeamShape</code></aloc> class.
+
+<flag name="Beams:allowVertexSpread" default="off">
+Allow the interaction vertex of the two colliding beams to be smeared.
+If off, then the vertex is set to be the origin.
+</flag>
+
+<parm name="Beams:sigmaVertexX" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>x</ei> location of the
+interaction vertex.
+</parm>
+
+<parm name="Beams:sigmaVertexY" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>y</ei> location of the
+interaction vertex.
+</parm>
+
+<parm name="Beams:sigmaVertexZ" default="0." min="0.">
+The width of a Gaussian distribution of the <ei>z</ei> location of the
+interaction vertex.
+</parm>
+
+<parm name="Beams:maxDevVertex" default="5." min="0.">
+The triply Gaussian distribution of interaction vertex position
+<ei>(x, y, z)</ei> is restricted to a maximal total deviation from the
+origin, like
+<eq>
+x^2/sigma_x^2 + y^2/sigma_y^2 + z^2/sigma_z^2 < maxDevVertex^2
+</eq>
+(Note the absence of a factor 2 in the denominator, unlike the Gaussians
+used to pick <ei>(x, y, z)</ei>.)
+</parm>
+
+<parm name="Beams:sigmaTime" default="0." min="0.">
+The width of a Gaussian distribution of the collision time (in units of
+mm/c). Note that, if the above space parametrization is viewed as the
+effect of two incoming beams along the <ei>+-z</ei> axis, with each beam
+having a Gaussian spread, then the spread of the time would also become
+a Gaussian with the same width as the <ei>z</ei> one (times the
+velocity of the beams, which we expect is close to unity). For flexibility
+we have not enforced any such relation, however.
+</parm>
+
+<parm name="Beams:maxDevTime" default="5." min="0.">
+The collision time is restricted to be in the range
+<ei>|t| < sigma_t * maxDevTime</ei>.
+</parm>
+
+<p/>
+The distributions above are all centered at the origin. It is also
+possible to shift the above distributions to be centered around another
+nominal position. You must have <code>Beams:allowVertexSpread = on</code>
+to use this possibility.
+
+<parm name="Beams:offsetVertexX" default="0.">
+The <ei>x</ei> location of the interaction vertex is centered at this value.
+</parm>
+
+<parm name="Beams:offsetVertexY" default="0.">
+The <ei>y</ei> location of the interaction vertex is centered at this value.
+</parm>
+
+<parm name="Beams:offsetVertexZ" default="0.">
+The <ei>z</ei> location of the interaction vertex is centered at this value.
+</parm>
+
+<parm name="Beams:offsetTime" default="0.">
+The time <ei>t</ei> of the interaction vertex is centered at this value.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Beam Remnants">
+
+<h2>Beam Remnants</h2>
+
+<h3>Introduction</h3>
+
+The <code>BeamParticle</code> class contains information on all partons
+extracted from a beam (so far). As each consecutive multiple interaction
+defines its respective incoming parton to the hard scattering a
+new slot is added to the list. This information is modified when
+the backwards evolution of the spacelike shower defines a new
+initiator parton. It is used, both for the multiple interactions
+and the spacelike showers, to define rescaled parton densities based
+on the <ei>x</ei> and flavours already extracted, and to distinguish
+between valence, sea and companion quarks. Once the perturbative
+evolution is finished, further beam remnants are added to obtain a
+consistent set of flavours. The current physics framework is further
+described in <ref>Sjo04</ref>.
+
+<p/>
+Much of the above information is stored in a vector of
+<code>ResolvedParton</code> objects, which each contains flavour and
+momentum information, as well as valence/companion information and more.
+The <code>BeamParticle</code> method <code>list()</code> shows the
+contents of this vector, mainly for debug purposes.
+
+<p/>
+The <code>BeamRemnants</code> class takes over for the final step
+of adding primordial <ei>kT</ei> to the initiators and remnants,
+assigning the relative longitudinal momentum sharing among the
+remnants, and constructing the overall kinematics and colour flow.
+This step couples the two sides of an event, and could therefore
+not be covered in the <code>BeamParticle</code> class, which only
+considers one beam at a time.
+
+<p/>
+The methods of these classes are not intended for general use,
+and so are not described here.
+
+<p/>
+In addition to the parameters described on this page, note that the
+choice of <aloc href="PDFSelection">parton densities</aloc> is made
+in the <code>Pythia</code> class. Then pointers to the pdf's are handed
+on to <code>BeamParticle</code> at initialization, for all subsequent
+usage.
+
+<h3>Primordial <ei>kT</ei></h3>
+
+The primordial <ei>kT</ei> of initiators of hard-scattering subsystems
+are selected according to Gaussian distributions in <ei>p_x</ei> and
+<ei>p_y</ei> separately. The widths of these distributions are chosen
+to be dependent on the hard scale of the central process and on the mass
+of the whole subsystem defined by the two initiators:
+<eq>
+sigma = (sigma_soft * Q_half + sigma_hard * Q) / (Q_half + Q)
+ * m / (m_half + m)
+</eq>
+Here <ei>Q</ei> is the hard-process renormalization scale for the
+hardest process and the <ei>pT</ei> scale for subsequent multiple
+interactions, <ei>m</ei> the mass of the system, and
+<ei>sigma_soft</ei>, <ei>sigma_hard</ei>, <ei>Q_half</ei> and
+<ei>m_half</ei> parameters defined below. Furthermore each separately
+defined beam remnant has a distribution of width <ei>sigma_remn</ei>,
+independently of kinematical variables.
+
+<flag name="BeamRemnants:primordialKT" default="on">
+Allow or not selection of primordial <ei>kT</ei> according to the
+parameter values below.
+</flag>
+
+<parm name="BeamRemnants:primordialKTsoft" default="0.4" min="0.">
+The width <ei>sigma_soft</ei> in the above equation, assigned as a
+primordial <ei>kT</ei> to initiators in the soft-interaction limit.
+</parm>
+
+<parm name="BeamRemnants:primordialKThard" default="2.1" min="0.">
+The width <ei>sigma_hard</ei> in the above equation, assigned as a
+primordial <ei>kT</ei> to initiators in the hard-interaction limit.
+</parm>
+
+<parm name="BeamRemnants:halfScaleForKT" default="7." min="0.">
+The scale <ei>Q_half</ei> in the equation above, defining the
+half-way point between hard and soft interactions.
+</parm>
+
+<parm name="BeamRemnants:halfMassForKT" default="2." min="0.">
+The scale <ei>m_half</ei> in the equation above, defining the
+half-way point between low-mass and high-mass subsystems.
+(Kinematics construction can easily fail if a system is assigned
+a primordial <ei>kT</ei> value higher than its mass, so the
+mass-dampening is intended to reduce some troubles later on.)
+</parm>
+
+<parm name="BeamRemnants:primordialKTremnant" default="0.4" min="0.">
+The width <ei>sigma_remn</ei>, assigned as a primordial <ei>kT</ei>
+to beam-remnant partons.
+</parm>
+
+<p/>
+A net <ei>kT</ei> imbalance is obtained from the vector sum of the
+primordial <ei>kT</ei> values of all initiators and all beam remnants.
+This quantity is compensated by a shift shared equally between
+all partons, except that the dampening factor <ei>m / (m_half + m)</ei>
+is again used to suppress the role of small-mass systems.
+
+<p/>
+Note that the current <ei>sigma</ei> definition implies that
+<ei><pT^2> = <p_x^2>+ <p_y^2> = 2 sigma^2</ei>.
+It thus cannot be compared directly with the <ei>sigma</ei>
+of nonperturbative hadronization, where each quark-antiquark
+breakup corresponds to <ei><pT^2> = sigma^2</ei> and only
+for hadrons it holds that <ei><pT^2> = 2 sigma^2</ei>.
+The comparison is further complicated by the reduction of
+primordial <ei>kT</ei> values by the overall compensation mechanism.
+
+<h3>Colour flow</h3>
+
+The colour flows in the separate subprocesses defined in the
+multiple-interactions scenario are tied together via the assignment
+of colour flow in the beam remnant. This is not an unambiguous
+procedure, but currently no parameters are directly associated with it.
+However, a simple "minimal" procedure of colour flow only via the beam
+remnants does not result in a scenario in
+agreement with data, notably not a sufficiently steep rise of
+<ei><pT>(n_ch)</ei>. The true origin of this behaviour and the
+correct mechanism to reproduce it remains one of the big unsolved issues
+at the borderline between perturbative and nonperturbative QCD.
+As a simple attempt, an additional step is introduced, wherein the gluons
+of a lower-<ei>pT</ei> system are merged with the ones in a higher-pT one.
+
+<flag name="BeamRemnants:reconnectColours" default="on">
+Allow or not a system to be merged with another one.
+</flag>
+
+<parm name="BeamRemnants:reconnectRange" default="2.5" min="0." max="10.">
+A system with a hard scale <ei>pT</ei> can be merged with one of a
+harder scale with a probability that is
+<ei>pT0_Rec^2 / (pT0_Rec^2 + pT^2)</ei>, where
+<ei>pT0_Rec</ei> is <code>reconnectRange</code> times <ei>pT0</ei>,
+the latter being the same energy-dependent dampening parameter as
+used for multiple interactions.
+Thus it is easy to merge a low-<ei>pT</ei> system with any other,
+but difficult to merge two high-<ei>pT</ei> ones with each other.
+</parm>
+
+<p/>
+The procedure is used iteratively. Thus first the reconnection probability
+<ei>P = pT0_Rec^2 / (pT0_Rec^2 + pT^2)</ei> of the lowest-<ei>pT</ei>
+system is found, and gives the probability for merger with the
+second-lowest one. If not merged, it is tested with the third-lowest one,
+and so on. For the <ei>m</ei>'th higher system the reconnection
+probability thus becomes <ei>(1 - P)^(m-1) P</ei>. That is, there is
+no explicit dependence on the higher <ei>pT</ei> scale, but implicitly
+there is via the survival probability of not already having been merged
+with a lower-<ei>pT</ei> system. Also note that the total reconnection
+probability for the lowest-<ei>pT</ei> system in an event with <ei>n</ei>
+systems becomes <ei>1 - (1 - P)^(n-1)</ei>. Once the fate of the
+lowest-<ei>pT</ei> system has been decided, the second-lowest is considered
+with respect to the ones above it, then the third-lowest, and so on.
+
+<p/>
+Once it has been decided which systems should be joined, the actual merging
+is carried out in the opposite direction. That is, first the hardest
+system is studied, and all colour dipoles in it are found (including to
+the beam remnants, as defined by the holes of the incoming partons).
+Next each softer system to be merged is studied in turn. Its gluons are,
+in decreasing <ei>pT</ei> order, inserted on the colour dipole <ei>i,j</ei>
+that gives the smallest <ei>(p_g p_i)(p_g p_j)/(p_i p_j)</ei>, i.e.
+minimizes the "disturbance" on the existing dipole, in terms of
+<ei>pT^2</ei> or <ei>Lambda</ei> measure (string length). The insertion
+of the gluon means that the old dipole is replaced by two new ones.
+Also the (rather few) quark-antiquark pairs that can be traced back to
+a gluon splitting are treated in close analogy with the gluon case.
+Quark lines that attach directly to the beam remnants cannot be merged
+but are left behind.
+
+<p/>
+The joining procedure can be viewed as a more sophisticated variant of
+the one introduced already in <ref>Sjo87</ref>. Clearly it is ad hoc.
+It hopefully captures some elements of truth. The lower <ei>pT</ei> scale
+a system has the larger its spatial extent and therefore the larger its
+overlap with other systems. It could be argued that one should classify
+individual initial-state partons by <ei>pT</ei> rather than the system
+as a whole. However, for final-state radiation, a soft gluon radiated off
+a hard parton is actually produced at late times and therefore probably
+less likely to reconnect. In the balance, a classification by system
+<ei>pT</ei> scale appears sensible as a first try.
+
+<p/>
+Note that the reconnection is carried out before resonance decays are
+considered. Colour inside a resonance therefore is not reconnected.
+This is a deliberate choice, but certainly open to discussion and
+extensions at a later stage, as is the rest of this procedure.
+
+<h3>Further variables</h3>
+
+<modeopen name="BeamRemnants:maxValQuark" default="3" min="0" max="5">
+The maximum valence quark kind allowed in acceptable incoming beams,
+for which multiple interactions are simulated. Default is that hadrons
+may contain <ei>u</ei>, <ei>d</ei> and <ei>s</ei> quarks,
+but not <ei>c</ei> and <ei>b</ei> ones, since sensible
+kinematics has not really been worked out for the latter.
+</modeopen>
+
+<modeopen name="BeamRemnants:companionPower" default="4" min="0" max="4">
+When a sea quark has been found, a companion antisea quark ought to be
+nearby in <ei>x</ei>. The shape of this distribution can be derived
+from the gluon mother distribution convoluted with the
+<ei>g -> q qbar</ei> splitting kernel. In practice, simple solutions
+are only feasible if the gluon shape is assumed to be of the form
+<ei>g(x) ~ (1 - x)^p / x</ei>, where <ei>p</ei> is an integer power,
+the parameter above. Allowed values correspond to the cases programmed.
+<br/>
+Since the whole framework is approximate anyway, this should be good
+enough. Note that companions typically are found at small <ei>Q^2</ei>,
+if at all, so the form is supposed to represent <ei>g(x)</ei> at small
+<ei>Q^2</ei> scales, close to the lower cutoff for multiple interactions.
+</modeopen>
+
+<p/>
+When assigning relative momentum fractions to beam-remnant partons,
+valence quarks are chosen according to a distribution like
+<ei>(1 - x)^power / sqrt(x)</ei>. This <ei>power</ei> is given below
+for quarks in mesons, and separately for <ei>u</ei> and <ei>d</ei>
+quarks in the proton, based on the approximate shape of low-<ei>Q^2</ei>
+parton densities. The power for other baryons is derived from the
+proton ones, by an appropriate mixing. The <ei>x</ei> of a diquark
+is chosen as the sum of its two constituent <ei>x</ei> values, and can
+thus be above unity. (A common rescaling of all remnant partons and
+particles will fix that.) An additional enhancement of the diquark
+momentum is obtained by its <ei>x</ei> value being rescaled by the
+<code>valenceDiqEnhance</code> factor.
+
+<parm name="BeamRemnants:valencePowerMeson" default="0.8" min="0.">
+The abovementioned power for valence quarks in mesons.
+</parm>
+
+<parm name="BeamRemnants:valencePowerUinP" default="3.5" min="0.">
+The abovementioned power for valence <ei>u</ei> quarks in protons.
+</parm>
+
+<parm name="BeamRemnants:valencePowerDinP" default="2.0" min="0.">
+The abovementioned power for valence <ei>d</ei> quarks in protons.
+</parm>
+
+<parm name="BeamRemnants:valenceDiqEnhance" default="2.0" min="0.5"
+max="10.">
+Enhancement factor for valence diqaurks in baryons, relative to the
+simple sum of the two constituent quarks.
+</parm>
+
+<flag name="BeamRemnants:allowJunction" default="on">
+The <code>off</code> option is intended for debug purposes only, as
+follows. When more than one valence quark is kicked out of a baryon
+beam, as part of the multiple interactions scenario, the subsequent
+hadronization is described in terms of a junction string topology.
+This description involves a number of technical complications that
+may make the program more unstable. As an alternative, by switching
+this option off, junction configurations are rejected (which gives
+an error message that the remnant flavour setup failed), and the
+multiple interactions and showers are redone until a
+junction-free topology is found.
+</flag>
+
+<h3>Diffractive system</h3>
+
+When an incoming hadron beam is diffractively excited, it is modeled
+as if either a valence quark or a gluon is kicked out from the hadron.
+In the former case this produces a simple string to the leftover
+remnant, in the latter it gives a hairpin arrangement where a string
+is stretched from one quark in the remnant, via the gluon, back to the
+rest of the remnant. The latter ought to dominate at higher mass of
+the diffractive system. Therefore an approximate behaviour like
+<eq>
+P_q / P_g = N / m^p
+</eq>
+is assumed.
+
+<parm name="BeamRemnants:pickQuarkNorm" default="5.0" min="0.">
+The abovementioned normalization <ei>N</ei> for the relative quark
+rate in diffractive systems.
+</parm>
+
+<parm name="BeamRemnants:pickQuarkPower" default="1.0" min="0.">
+The abovementioned mass-dependence power <ei>p</ei> for the relative
+quark rate in diffractive systems.
+</parm>
+
+<p/>
+When a gluon is kicked out from the hadron, the longitudinal momentum
+sharing between the the two remnant partons is determined by the
+same parameters as above. It is plausible that the primordial
+<ei>kT</ei> may be lower than in perturbative processes, however:
+
+<parm name="BeamRemnants:diffPrimKTwidth" default="0.5" min="0.">
+The width of Gaussian distributions in <ei>p_x</ei> and <ei>p_y</ei>
+separately that is assigned as a primordial <ei>kT</ei> to the two
+beam remnants when a gluon is kicked out of a diffractive system.
+</parm>
+
+<parm name="BeamRemnants:diffLargeMassSuppress" default="2." min="0.">
+The choice of longitudinal and transverse structure of a diffractive
+beam remnant for a kicked-out gluon implies a remnant mass
+<ei>m_rem</ei> distribution (i.e. quark plus diquark invariant mass
+for a baryon beam) that knows no bounds. A suppression like
+<ei>(1 - m_rem^2 / m_diff^2)^p</ei> is therefore introduced, where
+<ei>p</ei> is the <code>diffLargeMassSuppress</code> parameter.
+
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Beam Shape">
+
+<h2>Beam Shape</h2>
+
+The <aloc href="BeamParameters">Beam Parameters</aloc>
+page explains how you can set a momentum spread of the two incoming
+beams, and a spread and offset for the location of the interaction
+vertex. The spread is based on a simple parametrization in terms of
+independent Gaussians, however, which is likely to be too primitive
+for realistic applications.
+
+<p/>
+It is therefore possible to define your own class, derived from the
+<code>BeamShape</code> base class, and hand it in to Pythia with the
+<aloc href="ProgramFlow">
+<code>pythia.setBeamShapePtr( BeamShape*)</code></aloc> method.
+Below we describe what such a class has to do. An explicit toy example
+is shown in <code>main27.cc</code>.
+
+<p/>
+The <code>BeamShape</code> base class has a very simple structure.
+It only has two virtual methods. The first, <code>init()</code>, is
+used for initialization. The second, <code>pick()</code>, selects
+beam momentum and production vertex in the current event.
+
+<p/>
+The base-class <code>init()</code> method simply reads in the values
+stored in the <code>Settings</code> data base. You are free to
+write your own derived initialization routine, or use the existing one.
+In the latter case you can then give your own modified interpretation
+to the beam spread parameters defined there.
+
+<p/>
+The two flags <code>Beams:allowMomentumSpread</code> and
+<code>Beams:allowVertexSpread</code> should not be tampered with,
+however. These are checked elsewhere to determine whether the beam
+shape should be set or not, whereas the other momentum-spread
+and vertex-spread parameters are local to this class.
+
+<p/>
+The <code>pick()</code> method is the key one to supply in the derived
+class. Here you are free to pick whatever parametrization you desire
+for beam momenta and vertex position, including correlations between
+the two. At the end of the day, you should set
+<br/><code>deltaPxA, deltaPyA, deltaPzA</code> for the three-momentum
+deviation of the first incoming beam, relative to the nominal values;
+<br/><code>deltaPxB, deltaPyB, deltaPzB</code> for the three-momentum
+deviation of the second incoming beam, relative to the nominal values;
+<br/><code>vertexX, vertexY, vertexZ, vertexT</code> for the
+production-vertex position and time.
+<br/>These values will then be read out with the three base-class methods
+<code>deltaPA()</code>, <code>deltaPB()</code> and <code>vertex()</code>.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Bibliography">
+
+<h2>Bibliography</h2>
+
+<dl>
+
+<dt>Alt89</dt>
+<dd>G. Altarelli, B. Mele and M. Ruiz-Altaba,
+Z. Phys. C45 (1989) 109</dd>
+
+<dt>Alw06</dt>
+<dd>J. Alwall et al., Computer Physics Commun. 176 (2007) 300
+[hep-ph/0609017]</dd>
+
+<dt>And83</dt>
+<dd>B. Andersson, G. Gustafson, G. Ingelman and T. Sjöstrand,
+Phys. Rep. 97 (1983) 31</dd>
+
+<dt>Bar06</dt>
+<dd>M. Bargiotti, talk at the HERA4LHC workshop,
+http://mbargiot.web.cern.ch/mbargiot/talks/
+
+<dt>Bau90</dt>
+<dd>U. Baur, M. Spira and P. M. Zerwas, Phys. Rev. D42 (1990) 815</dd>
+
+<dt>Ben85</dt>
+<dd>H.-U. Bengtsson, W.-S. Hou, A. Soni and D.H. Stork,
+Phys. Rev. Lett. 55 (1985) 2762</dd>
+
+<dt>Ben87</dt>
+<dd>M. Bengtsson and T. Sjöstrand, Nucl. Phys. B289 (1987) 810</dd>
+
+<dt>Ber87</dt>
+<dd>UA4 Collaboration, D. Bernard et al., Phys. Lett. B198 (1987) 583</dd>
+
+<dt>Boo01</dt>
+<dd>E. Boos et al., in the Proceedings of the Workshop on Physics
+at TeV Colliders, Les Houches, France, 21 May - 1 Jun 2001
+[hep-ph/0109068]</dd>
+
+<dt>Bow81</dt>
+<dd>M.G. Bowler, Z. Phys. C11 (1981) 169</dd>
+
+<dt>Cah82</dt>
+<dd>R. Cahn, Z. Physik C15 (1982) 253</dd>
+
+<dt>Dob01</dt>
+<dd>M. Dobbs and J.B. Hansen, Computer Physics Comm. 134 (2001) 41</dd>
+
+<dt>Don92</dt>
+<dd>A. Donnachie and P.V. Landshoff, Phys. Lett. B296 (1992) 227</dd>
+
+<dt>Ede97</dt>
+<dd>P. Eden and G. Gustafson, Z. Phys. C75 (1997) 41</dd>
+
+<dt>Glu95</dt>
+<dd>M. Glück, E. Reya and A. Vogt, Z. Phys. C67 (1995) 433</dd>
+
+<dt>Gus86</dt>
+<dd>G. Gustafson, Phys. Lett. B175 (1986) 453;
+<br/>G. Gustafson and U. Pettersson, Nucl. Phys. B306 (1988) 746;
+<br/>L. Lönnblad, Computer Physics Commun. 71 (1992) 15</dd>
+
+<dt>Hew88</dt>
+<dd>J.L. Hewett and S. Pakvasa, Phys. Rev. D37 (1988) 3165</dd>
+
+<dt>Hui97</dt>
+<dd>K. Huitu, J. Maalampi, A. Pietilä and M. Raidal,
+Nucl. Phys. B487 (1997) 27 and private communication;
+<br/>G. Barenboim, K. Huitu, J. Maalampi and M. Raidal,
+Phys. Lett. B394 (1997) 132</dd>
+
+<dt>Kle89</dt>
+<dd>R. Kleiss et al., in `Z physics at LEP 1',
+eds. G. Altarelli, R. Kleiss and C. Verzegnassi,
+CERN 89-08 (Geneva, 1989), Vol. 3, p. 143</dd>
+
+<dt>Lai00</dt>
+<dd>CTEQ Collaboration, H.L. Lai et al.,
+Eur. Phys. J. C12 (2000) 375</dd>
+
+<dt>Lon95</dt>
+<dd>L. Lönnblad and T. Sjöstrand, Phys. Lett. B351 (1995) 293,
+Eur. Phys. J. C2 (1998) 165</dd>
+
+<dt>Mar90</dt>
+<dd>G. Marsaglia, A. Zaman and W.-W. Tsang,
+Stat. Prob. Lett. 9 (1990) 35</dd>
+
+<dt>Miu99</dt>
+<dd>G. Miu and T. Sjöstrand, Phys. Lett. B449 (1999) 313</dd>
+
+<dt>Nas00</dt>
+<dd>P. Nason et al., in "Standard model physics (and more) at the LHC",
+eds. G. Altarelli and M.L. Mangano, CERN 2000-004, p. 231
+[hep-ph/0003142]</dd>
+
+<dt>Nor00</dt>
+<dd>E. Norrbin and T. Sjöstrand, Eur. Phys. J. C17 (2000) 137</dd>
+
+<dt>Nor01</dt>
+ <dd>E. Norrbin and T. Sjöstrand, Nucl. Phys. B603 (2001) 297</dd>
+
+<dt>Pet83</dt>
+<dd>C. Peterson, D. Schlatter, I. Schmitt and P. Zerwas,
+Phys. Rev. D27 (1983) 105</dd>
+
+<dt>Sch97</dt>
+<dd>G.A. Schuler and T. Sjöstrand, Phys. Rev. D49 (1994) 2257,
+Z. Phys. C73 (1997) 677</dd>
+
+<dt>Sjo84</dt>
+<dd>T. Sjöstrand, Nucl. Phys. B248 (1984) 469</dd>
+
+<dt>Sey95</dt>
+<dd>M. Seymour, Phys. Lett. B354 (1995) 409</dd>
+
+<dt>Sjo85</dt>
+<dd>T. Sjöstrand, Phys. Lett. 157B (1985) 321;
+<br/>M. Bengtsson, T. Sjöstrand and M. van Zijl, Z. Phys. C32 (1986) 67
+</dd>
+
+<dt>Sjo87</dt>
+<dd>T. Sjöstrand and M. van Zijl, Phys. Rev. D36 (1987) 2019</dd>
+
+<dt>Sjo03</dt>
+<dd>T. Sjöstrand and P.Z. Skands, Nucl. Phys. B659 (2003) 243</dd>
+
+<dt>Sjo04</dt>
+<dd>T. Sjöstrand and P.Z. Skands, JHEP 03 (2004) 053</dd>
+
+<dt>Sjo05</dt>
+<dd>T. Sjöstrand and P.Z. Skands, Eur. Phys. J. C39 (2005) 129</dd>
+
+<dt>Sjo06</dt>
+<dd>T. Sjöstrand, S. Mrenna and P.Z. Skands,
+JHEP 05 (2006) 026 [hep-ph/0603175]</dd>
+
+<dt>Ska04</dt>
+<dd>P. Skands et al., JHEP 07 (2004) 036 [hep-ph/0311123]</dd>
+
+<dt>Wha05</dt>
+<dd>M.R. Whalley, D. Bourilkov and R.C. Group,
+in `HERA and the LHC', eds. A. De Roeck and H. Jung,
+CERN-2005-014, p. 575 [hep-ph/0508110]</dd>
+
+<dt>Yao06</dt>
+<dd>Particle Data Group, W.-M. Yao et al.,
+J. Phys. G33 (2006) 1</dd>
+
+</dl>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Bose-Einstein Effects">
+
+<h2>Bose-Einstein Effects</h2>
+
+The <code>BoseEinstein</code> class performs shifts of momenta
+of identical particles to provide a crude estimate of
+Bose-Einstein effects. The algorithm is the BE_32 one described in
+<ref>Lon95</ref>, with a Gaussian parametrization of the enhancement.
+We emphasize that this approach is not based on any first-principles
+quantum mechanical description of interference phenomena; such
+approaches anyway have many problems to contend with. Instead a cruder
+but more robust approach is adopted, wherein BE effects are introduced
+after the event has already been generated, with the exception of the
+decays of long-lived particles. The trick is that momenta of identical
+particles are shifted relative to each other so as to provide an
+enhancement of pairs closely separated, which is compensated by a
+depletion of pairs in an intermediate region of separation.
+
+<p/>
+More precisely, the intended target form of the BE corrrelations in
+BE_32 is
+<eq>
+f_2(Q) = (1 + lambda * exp(-Q^2 R^2))
+ * (1 + alpha * lambda * exp(-Q^2 R^2/9) * (1 - exp(-Q^2 R^2/4)))
+</eq>
+where <ei>Q^2 = (p_1 + p_2)^2 - (m_1 + m_2)^2</ei>.
+Here the strength <ei>lambda</ei> and effective radius <ei>R</ei>
+are the two main parameters. The first factor of the
+equation is implemented by pulling pairs of identical hadrons closer
+to each other. This is done in such a way that three-monentum is
+conserved, but at the price of a small but non-negligible negative
+shift in the energy of the event. The second factor compensates this
+by pushing particles apart. The negative <ei>alpha</ei> parameter is
+determined iteratively, separately for each event, so as to restore
+energy conservation. The effective radius parameter is here <ei>R/3</ei>,
+i.e. effects extend further out in <ei>Q</ei>. Without the dampening
+<ei>(1 - exp(-Q^2 R^2/4))</ei> in the second factor the value at the
+origin would become <ei>f_2(0) = (1 + lambda) * (1 + alpha * lambda)</ei>,
+with it the desired value <ei>f_2(0) = (1 + lambda)</ei> is restored.
+The end result can be viewed as a poor man's rendering of a rapidly
+dampened oscillatory behaviour in <ei>Q</ei>.
+
+<p/>
+Further details can be found in <ref>Lon95</ref>. For instance, the
+target is implemented under the assumption that the initial distribution
+in <ei>Q</ei> can be well approximated by pure phase space at small
+values, and implicitly generates higher-order effects by the way
+the algorithm is implemented. The algorithm is applied after the decay
+of short-lived resonances such as the <ei>rho</ei>, but before the decay
+of longer-lived particles.
+
+<p/>
+This algorithm is known to do a reasonable job of describing BE
+phenomena at LEP. It has not been tested against data for hadron
+colliders, to the best of our knowledge, so one should exercise some
+judgement before using it. Therefore by default the master switch
+<aloc href="MasterSwitches">HadronLevel:BoseEinstein</aloc> is off.
+Furthermore, the implementation found here is not (yet) as
+sophisticated as the one used at LEP2, in that no provision is made
+for particles from separate colour singlet systems, such as
+<ei>W</ei>'s and <ei>Z</ei>'s, interfering only at a reduced rate.
+
+<p/>
+<b>Warning:</b> The algorithm will create a new copy of each particle
+with shifted momentum by BE effects, with status code 99, while the
+original particle with the original momentum at the same time will be
+marked as decayed. This means that if you e.g. search for all
+<ei>pi+-</ei> in an event you will often obtain the same particle twice.
+One way to protect yourself from unwanted doublecounting is to
+use only particles with a positive status code, i.e. ones for which
+<code>event[i].isFinal()</code> is <code>true</code>.
+
+
+<h3>Main parameters</h3>
+
+<flag name="BoseEinstein:Pion" default="on">
+Include effects or not for identical <ei>pi^+</ei>, <ei>pi^-</ei>
+and <ei>pi^0</ei>.
+</flag>
+
+<flag name="BoseEinstein:Kaon" default="on">
+Include effects or not for identical <ei>K^+</ei>, <ei>K^-</ei>,
+<ei>K_S^0</ei> and <ei>K_L^0</ei>.
+</flag>
+
+<flag name="BoseEinstein:Eta" default="on">
+Include effects or not for identical <ei>eta</ei> and <ei>eta'</ei>.
+</flag>
+
+<parm name="BoseEinstein:lambda" default="1." min="0." max="2.">
+The strength parameter for Bose-Einstein effects. On physical grounds
+it should not be above unity, but imperfections in the formalism
+used may require that nevertheless.
+</parm>
+
+<parm name="BoseEinstein:QRef" default="0.2" min="0.05" max="1.">
+The size parameter of the region in <ei>Q</ei> space over which
+Bose-Einstein effects are significant. Can be thought of as
+the inverse of an effective distance in normal space,
+<ei>R = hbar / QRef</ei>, with <ei>R</ei> as used in the above equation.
+That is, <ei>f_2(Q) = (1 + lambda * exp(-(Q/QRef)^2)) * (...)</ei>.
+</parm>
+
+<parm name="BoseEinstein:widthSep" default="0.02" min="0.001" max="1.">
+Particle species with a width above this value (in GeV) are assumed
+to be so short-lived that they decay before Bose-Einstein effects
+are considered, while otherwise they do not. In the former case the
+decay products thus can obtain shifted momenta, in the latter not.
+The default has been picked such that both <ei>rho</ei> and
+<ei>K^*</ei> decay products would be modified.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Compositeness Processes">
+
+<h2>Compositeness Processes</h2>
+
+Compositeness scenarios may give rise to sharp resonances of excited
+quarks and leptons. An excited copy of the first generation is
+implemented, consisting of spin 1/2 particles.
+
+<p/>
+The current implementation contains gauge interaction production
+by quark-gluon fusion or lepton-photon fusion and contact interaction
+production by quark-quark or quark-antiquark scattering. In additions
+to the compositness scale and couplings listed below, you are expected
+to change the excited-fermion masses in accordance with what is desired.
+See <ref>Bau90</ref> for conventions.
+
+<p/>
+A non-trivial angular dependence is included in the decay for the
+<ei>2 -> 1</ei> processes, but has not been included for the
+<ei>2 -> 2</ei> ones.
+
+<h3>Production processes</h3>
+
+A few different production processes have been implemented, which normally
+would not overlap and therefore could be run together.
+
+<flag name="ExcitedFermion:all" default="off">
+Common switch for the group of implemented processes that produce an
+excited fermion.
+</flag>
+
+<flag name="ExcitedFermion:dg2dStar" default="off">
+Scatterings <ei>d g -> d^*</ei>.
+Code 4001.
+</flag>
+
+<flag name="ExcitedFermion:ug2uStar" default="off">
+Scatterings <ei>u g -> u^*</ei>.
+Code 4002.
+</flag>
+
+<flag name="ExcitedFermion:sg2sStar" default="off">
+Scatterings <ei>s g -> s^*</ei>.
+Code 4003.
+</flag>
+
+<flag name="ExcitedFermion:cg2cStar" default="off">
+Scatterings <ei>c g -> c^*</ei>.
+Code 4004.
+</flag>
+
+<flag name="ExcitedFermion:bg2bStar" default="off">
+Scatterings <ei>b g -> b^*</ei>.
+Code 4005.
+</flag>
+
+<flag name="ExcitedFermion:egm2eStar" default="off">
+Scatterings <ei>e gamma -> e^*</ei>.
+Code 4011.
+</flag>
+
+<flag name="ExcitedFermion:mugm2muStar" default="off">
+Scatterings <ei>mu gamma -> mu^*</ei>.
+Code 4013.
+</flag>
+
+<flag name="ExcitedFermion:taugm2tauStar" default="off">
+Scatterings <ei>tau gamma -> tau^*</ei>.
+Code 4015.
+</flag>
+
+<flag name="ExcitedFermion:qq2dStarq" default="off">
+Scatterings <ei>q q(bar) -> d^* q(bar)</ei>.
+Code 4021.
+</flag>
+
+<flag name="ExcitedFermion:qq2uStarq" default="off">
+Scatterings <ei>q q(bar) -> u^* q(bar)</ei>.
+Code 4022.
+</flag>
+
+<flag name="ExcitedFermion:qq2sStarq" default="off">
+Scatterings <ei>q q(bar) -> s^* q(bar)</ei>.
+Code 4023.
+</flag>
+
+<flag name="ExcitedFermion:qq2cStarq" default="off">
+Scatterings <ei>q q(bar) -> c^* q(bar)</ei>.
+Code 4024.
+</flag>
+
+<flag name="ExcitedFermion:qq2bStarq" default="off">
+Scatterings <ei>q q(bar) -> b^* q(bar)</ei>.
+Code 4025.
+</flag>
+
+<flag name="ExcitedFermion:qqbar2eStare" default="off">
+Scatterings <ei>q qbar -> e^*+- e^-+</ei>.
+Code 4031.
+</flag>
+
+<flag name="ExcitedFermion:qqbar2nueStarnue" default="off">
+Scatterings <ei>q qbar -> nu_e^* nu_ebar</ei>.
+Code 4032.
+</flag>
+
+<flag name="ExcitedFermion:qqbar2muStarmu" default="off">
+Scatterings <ei>q qbar -> mu^*+- mu^-+</ei>.
+Code 4033.
+</flag>
+
+<flag name="ExcitedFermion:qqbar2numuStarnumu" default="off">
+Scatterings <ei>q qbar -> nu_mu^* nu_mubar</ei>.
+Code 4034.
+</flag>
+
+<flag name="ExcitedFermion:qqbar2tauStartau" default="off">
+Scatterings <ei>q qbar -> tau^*+- tau^-+</ei>.
+Code 4035.
+</flag>
+
+<flag name="ExcitedFermion:qqbar2nutauStarnutau" default="off">
+Scatterings <ei>q qbar -> nu_tau^* nu_taubar</ei>.
+Code 4036.
+</flag>
+
+<h3>Parameters</h3>
+
+The basic couplings of the model are
+
+<parm name="ExcitedFermion:Lambda" default="1000." min="100.">
+compositeness scale <ei>Lambda</ei> in GeV.
+</parm>
+
+<parm name="ExcitedFermion:coupF" default="1.0" min="0.0">
+strength <ei>f</ei> of the <ei>SU(2)</ei> coupling.
+</parm>
+
+<parm name="ExcitedFermion:coupFprime" default="1.0" min="0.0">
+strength <ei>f'</ei> of the <ei>U(1)</ei> coupling.
+</parm>
+
+<parm name="ExcitedFermion:coupFcol" default="1.0" min="0.0">
+strength <ei>f_c</ei> of the <ei>SU(3)</ei> coupling.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Couplings and Scales">
+
+<h2>Couplings and Scales</h2>
+
+Here is collected some possibilities to modify the scale choices
+of couplings and parton densities for all internally implemented
+hard processes. This is based on them all being derived from the
+<code>SigmaProcess</code> base class. The matrix-element coding is
+also used by the multiple-interactions machinery, but there with a
+separate choice of <ei>alpha_strong(M_Z^2)</ei> value and running,
+and separate PDF scale choices. Also, in <ei>2 -> 2</ei> and
+<ei>2 -> 3</ei> processes where resonances are produced, their
+couplings and thereby their Breit-Wigner shapes are always evaluated
+with the resonance mass as scale, irrespective of the choices below.
+
+<h3>Couplings and K factor</h3>
+
+The size of QCD cross sections is mainly determined by
+<parm name="SigmaProcess:alphaSvalue" default="0.1265"
+min="0.06" max="0.25">
+The <ei>alpha_strong</ei> value at scale <ei>M_Z^2</ei>.
+</parm>
+
+<p/>
+The actual value is then regulated by the running to the <ei>Q^2</ei>
+renormalization scale, at which <ei>alpha_strong</ei> is evaluated
+<modepick name="SigmaProcess:alphaSorder" default="1" min="0" max="2">
+Order at which <ei>alpha_strong</ei> runs,
+<option value="0">zeroth order, i.e. <ei>alpha_strong</ei> is kept
+fixed.</option>
+<option value="1">first order, which is the normal value.</option>
+<option value="2">second order. Since other parts of the code do
+not go to second order there is no strong reason to use this option,
+but there is also nothing wrong with it.</option>
+</modepick>
+
+<p/>
+QED interactions are regulated by the <ei>alpha_electromagnetic</ei>
+value at the <ei>Q^2</ei> renormalization scale of an interaction.
+<modepick name="SigmaProcess:alphaEMorder" default="1" min="-1" max="1">
+The running of <ei>alpha_em</ei> used in hard processes.
+<option value="1">first-order running, constrained to agree with
+<code>StandardModel:alphaEMmZ</code> at the <ei>Z^0</ei> mass.
+</option>
+<option value="0">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed at its value at vanishing momentum transfer.</option>
+<option value="-1">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed, but at <code>StandardModel:alphaEMmZ</code>, i.e. its value
+at the <ei>Z^0</ei> mass.
+</option>
+</modepick>
+
+<p/>
+In addition there is the possibility of a global rescaling of
+cross sections (which could not easily be accommodated by a
+changed <ei>alpha_strong</ei>, since <ei>alpha_strong</ei> runs)
+<parm name="SigmaProcess:Kfactor" default="1.0" min="0.5" max="4.0">
+Multiply almost all cross sections by this common fix factor. Excluded
+are only unresolved processes, where cross sections are better
+<aloc href="TotalCrossSections">set directly</aloc>, and
+multiple interactions, which have a separate <ei>K</ei> factor
+<aloc href="MultipleInteractions">of their own</aloc>.
+This degree of freedom is primarily intended for hadron colliders, and
+should not normally be used for <ei>e^+e^-</ei> annihilation processes.
+</parm>
+
+<h3>Renormalization scales</h3>
+
+The <ei>Q^2</ei> renormalization scale can be chosen among a few different
+alternatives, separately for <ei>2 -> 1</ei>, <ei>2 -> 2</ei> and two
+different kinds of <ei>2 -> 3</ei> processes. In addition a common
+multiplicative factor may be imposed.
+
+<modepick name="SigmaProcess:renormScale1" default="1" min="1" max="2">
+The <ei>Q^2</ei> renormalization scale for <ei>2 -> 1</ei> processes.
+The same options also apply for those <ei>2 -> 2</ei> and <ei>2 -> 3</ei>
+processes that have been specially marked as proceeding only through
+an <ei>s</ei>-channel resonance, by the <code>isSChannel()</code> virtual
+method of <code>SigmaProcess</code>.
+<option value="1">the squared invariant mass, i.e. <ei>sHat</ei>.
+</option>
+<option value="2">fix scale set in <code>SigmaProcess:renormFixScale</code>
+below.
+</option>
+</modepick>
+
+<modepick name="SigmaProcess:renormScale2" default="2" min="1" max="5">
+The <ei>Q^2</ei> renormalization scale for <ei>2 -> 2</ei> processes.
+<option value="1">the smaller of the squared transverse masses of the two
+outgoing particles, i.e. <ei>min(mT_3^2, mT_4^2) =
+pT^2 + min(m_3^2, m_4^2)</ei>.
+</option>
+<option value="2">the geometric mean of the squared transverse masses of
+the two outgoing particles, i.e. <ei>mT_3 * mT_4 =
+sqrt((pT^2 + m_3^2) * (pT^2 + m_4^2))</ei>.
+</option>
+<option value="3">the arithmetic mean of the squared transverse masses of
+the two outgoing particles, i.e. <ei>(mT_3^2 + mT_4^2) / 2 =
+pT^2 + 0.5 * (m_3^2 + m_4^2)</ei>. Useful for comparisons
+with PYTHIA 6, where this is the default.
+</option>
+<option value="4">squared invariant mass of the system,
+i.e. <ei>sHat</ei>. Useful for processes dominated by
+<ei>s</ei>-channel exchange.
+</option>
+<option value="5">fix scale set in <code>SigmaProcess:renormFixScale</code>
+below.
+</option>
+</modepick>
+
+<modepick name="SigmaProcess:renormScale3" default="3" min="1" max="6">
+The <ei>Q^2</ei> renormalization scale for "normal" <ei>2 -> 3</ei>
+processes, i.e excepting the vector-boson-fusion processes below.
+Here it is assumed that particle masses in the final state either match
+or are heavier than that of any <ei>t</ei>-channel propagator particle.
+(Currently only <ei>g g / q qbar -> H^0 Q Qbar</ei> processes are
+implemented, where the "match" criterion holds.)
+<option value="1">the smaller of the squared transverse masses of the three
+outgoing particles, i.e. min(mT_3^2, mT_4^2, mT_5^2).
+</option>
+<option value="2">the geometric mean of the two smallest squared transverse
+masses of the three outgoing particles, i.e.
+<ei>sqrt( mT_3^2 * mT_4^2 * mT_5^2 / max(mT_3^2, mT_4^2, mT_5^2) )</ei>.
+</option>
+<option value="3">the geometric mean of the squared transverse masses of the
+three outgoing particles, i.e. <ei>(mT_3^2 * mT_4^2 * mT_5^2)^(1/3)</ei>.
+</option>
+<option value="4">the arithmetic mean of the squared transverse masses of
+the three outgoing particles, i.e. <ei>(mT_3^2 + mT_4^2 + mT_5^2)/3</ei>.
+</option>
+<option value="5">squared invariant mass of the system,
+i.e. <ei>sHat</ei>.
+</option>
+<option value="6">fix scale set in <code>SigmaProcess:renormFixScale</code>
+below.
+</option>
+</modepick>
+
+<modepick name="SigmaProcess:renormScale3VV" default="3" min="1" max="6">
+The <ei>Q^2</ei> renormalization scale for <ei>2 -> 3</ei>
+vector-boson-fusion processes, i.e. <ei>f_1 f_2 -> H^0 f_3 f_4</ei>
+with <ei>Z^0</ei> or <ei>W^+-</ei> <ei>t</ei>-channel propagators.
+Here the transverse masses of the outgoing fermions do not reflect the
+virtualities of the exchanged bosons. A better estimate is obtained
+by replacing the final-state fermion masses by the vector-boson ones
+in the definition of transverse masses. We denote these combinations
+<ei>mT_Vi^2 = m_V^2 + pT_i^2</ei>.
+<option value="1">the squared mass <ei>m_V^2</ei> of the exchanged
+vector boson.
+</option>
+<option value="2">the geometric mean of the two propagator virtuality
+estimates, i.e. <ei>sqrt(mT_V3^2 * mT_V4^2)</ei>.
+</option>
+<option value="3">the geometric mean of the three relevant squared
+transverse masses, i.e. <ei>(mT_V3^2 * mT_V4^2 * mT_H^2)^(1/3)</ei>.
+</option>
+<option value="4">the arithmetic mean of the three relevant squared
+transverse masses, i.e. <ei>(mT_V3^2 + mT_V4^2 + mT_H^2)/3</ei>.
+</option>
+<option value="5">squared invariant mass of the system,
+i.e. <ei>sHat</ei>.
+</option>
+<option value="6">fix scale set in <code>SigmaProcess:renormFixScale</code>
+below.
+</option>
+</modepick>
+
+<parm name="SigmaProcess:renormMultFac" default="1." min="0.1" max="10.">
+The <ei>Q^2</ei> renormalization scale for <ei>2 -> 1</ei>,
+<ei>2 -> 2</ei> and <ei>2 -> 3</ei> processes is multiplied by
+this factor relative to the scale described above (except for the options
+with a fix scale). Should be use sparingly for <ei>2 -> 1</ei> processes.
+</parm>
+
+<parm name="SigmaProcess:renormFixScale" default="10000." min="1.">
+A fix <ei>Q^2</ei> value used as renormalization scale for <ei>2 -> 1</ei>,
+<ei>2 -> 2</ei> and <ei>2 -> 3</ei> processes in some of the options above.
+</parm>
+
+<h3>Factorization scales</h3>
+
+Corresponding options exist for the <ei>Q^2</ei> factorization scale
+used as argument in PDF's. Again there is a choice of form for
+<ei>2 -> 1</ei>, <ei>2 -> 2</ei> and <ei>2 -> 3</ei> processes separately.
+For simplicity we have let the numbering of options agree, for each event
+class separately, between normalization and factorization scales, and the
+description has therefore been slightly shortened. The default values are
+<b>not</b> necessarily the same, however.
+
+<modepick name="SigmaProcess:factorScale1" default="1" min="1" max="2">
+The <ei>Q^2</ei> factorization scale for <ei>2 -> 1</ei> processes.
+The same options also apply for those <ei>2 -> 2</ei> and <ei>2 -> 3</ei>
+processes that have been specially marked as proceeding only through
+an <ei>s</ei>-channel resonance.
+<option value="1">the squared invariant mass, i.e. <ei>sHat</ei>.
+</option>
+<option value="2">fix scale set in <code>SigmaProcess:factorFixScale</code>
+below.
+</option>
+</modepick>
+
+<modepick name="SigmaProcess:factorScale2" default="1" min="1" max="5">
+The <ei>Q^2</ei> factorization scale for <ei>2 -> 2</ei> processes.
+<option value="1">the smaller of the squared transverse masses of the two
+outgoing particles.
+</option>
+<option value="2">the geometric mean of the squared transverse masses of
+the two outgoing particles.
+</option>
+<option value="3">the arithmetic mean of the squared transverse masses of
+the two outgoing particles. Useful for comparisons with PYTHIA 6, where
+this is the default.
+</option>
+<option value="4">squared invariant mass of the system,
+i.e. <ei>sHat</ei>. Useful for processes dominated by
+<ei>s</ei>-channel exchange.
+</option>
+<option value="5">fix scale set in <code>SigmaProcess:factorFixScale</code>
+below.
+</option>
+</modepick>
+
+<modepick name="SigmaProcess:factorScale3" default="2" min="1" max="6">
+The <ei>Q^2</ei> factorization scale for "normal" <ei>2 -> 3</ei>
+processes, i.e excepting the vector-boson-fusion processes below.
+<option value="1">the smaller of the squared transverse masses of the three
+outgoing particles.
+</option>
+<option value="2">the geometric mean of the two smallest squared transverse
+masses of the three outgoing particles.
+</option>
+<option value="3">the geometric mean of the squared transverse masses of the
+three outgoing particles.
+</option>
+<option value="4">the arithmetic mean of the squared transverse masses of
+the three outgoing particles.
+</option>
+<option value="5">squared invariant mass of the system,
+i.e. <ei>sHat</ei>.
+</option>
+<option value="6">fix scale set in <code>SigmaProcess:factorFixScale</code>
+below.
+</option>
+</modepick>
+
+<modepick name="SigmaProcess:factorScale3VV" default="2" min="1" max="6">
+The <ei>Q^2</ei> factorization scale for <ei>2 -> 3</ei>
+vector-boson-fusion processes, i.e. <ei>f_1 f_2 -> H^0 f_3 f_4</ei>
+with <ei>Z^0</ei> or <ei>W^+-</ei> <ei>t</ei>-channel propagators.
+Here we again introduce the combinations <ei>mT_Vi^2 = m_V^2 + pT_i^2</ei>
+as replacements for the normal squared transverse masses of the two
+outgoing quarks.
+<option value="1">the squared mass <ei>m_V^2</ei> of the exchanged
+vector boson.
+</option>
+<option value="2">the geometric mean of the two propagator virtuality
+estimates.
+</option>
+<option value="3">the geometric mean of the three relevant squared
+transverse masses.
+</option>
+<option value="4">the arithmetic mean of the three relevant squared
+transverse masses.
+</option>
+<option value="5">squared invariant mass of the system,
+i.e. <ei>sHat</ei>.
+</option>
+<option value="6">fix scale set in <code>SigmaProcess:factorFixScale</code>
+below.
+</option>
+</modepick>
+
+<parm name="SigmaProcess:factorMultFac" default="1." min="0.1" max="10.">
+The <ei>Q^2</ei> factorization scale for <ei>2 -> 1</ei>,
+<ei>2 -> 2</ei> and <ei>2 -> 3</ei> processes is multiplied by
+this factor relative to the scale described above (except for the options
+with a fix scale). Should be use sparingly for <ei>2 -> 1</ei> processes.
+</parm>
+
+<parm name="SigmaProcess:factorFixScale" default="10000." min="1.">
+A fix <ei>Q^2</ei> value used as factorization scale for <ei>2 -> 1</ei>,
+<ei>2 -> 2</ei> and <ei>2 -> 3</ei> processes in some of the options above.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Electroweak Processes">
+
+<h2>Electroweak Processes</h2>
+
+This page contains processes involving Prompt-photon, <ei>gamma^*/Z^0</ei>
+and <ei>W^+-</ei> production, plus a few with <ei>t</ei>-channel boson
+exchange.
+
+<h3>Prompt photon processes</h3>
+
+This group collects the processes where one or two photons are
+produced by the hard process. Additional sources of photons
+include parton showers and hadron decays. A <ei>pT</ei> cut
+is required to stay away from the unphysical low-<ei>pT</ei> region.
+An eikonalized description, intended to be valid at all <ei>pT</ei>,
+is included as part of the multiple-interactions framework.
+
+<flag name="PromptPhoton:all" default="off">
+Common switch for the group of all prompt photon processes,
+as listed separately in the following.
+</flag>
+
+<flag name="PromptPhoton:qg2qgamma" default="off">
+Scattering <ei>q g -> q gamma</ei>.
+Code 201.
+</flag>
+
+<flag name="PromptPhoton:qqbar2ggamma" default="off">
+Scattering <ei>q qbar -> g gamma</ei>.
+Code 202.
+</flag>
+
+<flag name="PromptPhoton:gg2ggamma" default="off">
+Scattering <ei>g g -> g gamma</ei>.
+<note>Note:</note> This is a box graph. The full quark-mass dependence
+in the loop leads to very complicated expressions. The current
+implementation is based on assuming five massless quarks (see below),
+and thus is questionable at small (<ei>pT < m_b</ei>) or large
+(<ei>pT > m_t</ei>) transverse momenta.
+Code 203.
+</flag>
+
+<flag name="PromptPhoton:ffbar2gammagamma" default="off">
+Scattering <ei>q qbar -> gamma gamma</ei>.
+Code 204.
+</flag>
+
+<flag name="PromptPhoton:gg2gammagamma" default="off">
+Scattering <ei>g g -> gamma gamma</ei>.
+<note>Note:</note> This is a box graph. The full quark-mass dependence
+in the loop leads to very complicated expressions. The current
+implementation is based on assuming five massless quarks (see below),
+and thus is questionable at small (<ei>pT < m_b</ei>) or large
+(<ei>pT > m_t</ei>) transverse momenta.
+Code 205.
+</flag>
+
+<modeopen name="PromptPhoton:nQuarkLoop" default="5" min="3" max="6">
+Number of quark flavours included in the box graphs resposible for
+<ei>g g -> g gamma</ei> and <ei>g g-> gamma gamma</ei> processes.
+Owing to the complexity if the massive expressions, quarks are treated
+as massless. The default value should be applicable in the range of
+transverse momenta above the <ei>b</ei> mass but below the <ei>t</ei> one.
+</modeopen>
+
+<h3>Weak boson processes</h3>
+
+Under this heading we group processes involving the production
+of a single electroweak gauge boson, i.e. a <ei>gamma^*/Z^0</ei>
+or a <ei>W^+-</ei>, or a pair of them, or one of them in
+combination with a parton. Since the three sets are partly
+conflicting, each is associated with its own group flag.
+In addition, <ei>t</ei>-channel exchange of such a boson
+between two fermions form a separate group.
+
+<p/>
+There is one flag that can be used to influence the <ei>gamma^*/Z^0</ei>
+structure in all the processes below where it is produced, unless
+otherwise stated.
+<modepick name="WeakZ0:gmZmode" default="0" min="0" max="2">
+Choice of full <ei>gamma^*/Z^0</ei> structure or not in relevant
+processes.
+<option value="0">full <ei>gamma^*/Z^0</ei> structure,
+with interference included.</option>
+<option value="1">only pure <ei>gamma^*</ei> contribution.</option>
+<option value="2">only pure <ei>Z^0</ei> contribution.</option>
+<note>Note</note>: irrespective of the option used, the particle produced
+will always be assigned code 23 for <ei>Z^0</ei>, and open decay channels
+is purely dictated by what is set for the <ei>Z^0</ei>.
+</modepick>
+
+<h4>Boson exchange</h4>
+
+The two processes in this subgroup is included as part of the
+multiple-interactions framework.
+
+<flag name="WeakBosonExchange:all" default="off">
+Common switch for the group of <ei>gamma^*/Z^0</ei>
+or <ei>W^+-</ei> exchange between two fermions.
+</flag>
+
+<flag name="WeakBosonExchange:ff2ff(t:gmZ)" default="off">
+Scattering <ei>f f' -> f f'</ei> via </ei>gamma^*/Z^0</ei>
+<ei>t</ei>-channel exchange, with full interference
+between the <ei>gamma^*</ei> and <ei>Z^0</ei>.
+Code 211.
+</flag>
+
+<flag name="WeakBosonExchange:ff2ff(t:W)" default="off">
+Scattering <ei>f_1 f_2 -> f_3 f_4</ei> via </ei>W^+-</ei>
+<ei>t</ei>-channel exchange.
+Code 212.
+</flag>
+
+<h4>Single boson</h4>
+
+<flag name="WeakSingleBoson:all" default="off">
+Common switch for the group of a single <ei>gamma^*/Z^0</ei>
+or <ei>W^+-</ei> production.
+</flag>
+
+<flag name="WeakSingleBoson:ffbar2gmZ" default="off">
+Scattering <ei>f fbar -> gamma^*/Z^0</ei>, with full interference
+between the <ei>gamma^*</ei> and <ei>Z^0</ei>.
+Code 221.
+</flag>
+
+<flag name="WeakSingleBoson:ffbar2W" default="off">
+Scattering <ei>f fbar' -> W^+-</ei>.
+Code 222.
+</flag>
+
+<flag name="WeakSingleBoson:ffbar2ffbar(s:gm)" default="off">
+Scattering <ei>f fbar -> gamma^* -> f' fbar'</ei>. Subset of
+process 221, but written as a <ei>2 -> 2</ei> process, so that
+<ei>pT</ei> can be used as ordering variable, e.g. in multiple
+interactions. Hardcoded for the final state being either of the
+five quark flavours or three lepton ones. Not included in the
+<code>WeakSingleBoson:all</code> set, but included in the
+multiple-interactions framework.
+Code 223.
+</flag>
+
+<h4>Boson pair</h4>
+
+<flag name="WeakDoubleBoson:all" default="off">
+Common switch for the group of pair production of <ei>gamma^*/Z^0</ei>
+and <ei>W^+-</ei>.
+</flag>
+
+<flag name="WeakDoubleBoson:ffbar2gmZgmZ" default="off">
+Scattering <ei>f fbar' -> gamma^*/Z^0 gamma^*/Z^0</ei>.
+Code 231.
+</flag>
+
+<flag name="WeakDoubleBoson:ffbar2ZW" default="off">
+Scattering <ei>f fbar' -> Z^0 W^+-</ei>. Note that here the
+<ei>gamma^*</ei> contribution is not (currently) included.
+Code 232.
+</flag>
+
+<flag name="WeakDoubleBoson:ffbar2WW" default="off">
+Scattering <ei>f fbar -> W^+ W^-</ei>.
+Code 233.
+</flag>
+
+<h4>Boson and parton</h4>
+
+<flag name="WeakBosonAndParton:all" default="off">
+Common switch for the group of production of a single electroweak
+gauge boson, i.e. a <ei>gamma^*/Z^0</ei> or a <ei>W^+-</ei>, in
+association with a parton, i.e. a quark, gluon, photon or lepton.
+These processes give first-order corrections to the ones in the
+<code>WeakSingleBoson</code> class, and both sets cannot be used
+simultaneously without unphysical doublecounting. The current class
+should only be used to study the high-<ei>pT</ei> tail of the
+gauge-boson production processes (for LHC applications at least
+<ei>pT</ei> > 20 GeV), while the ones in <code>WeakSingleBoson</code>
+should be used for inclusive production.
+</flag>
+
+<flag name="WeakBosonAndParton:qqbar2gmZg" default="off">
+Scattering <ei>q qbar -> gamma^*/Z^0 g</ei>.
+Code 241.
+</flag>
+
+<flag name="WeakBosonAndParton:qg2gmZq" default="off">
+Scattering <ei>q g -> gamma^*/Z^0 q </ei>.
+Code 242.
+</flag>
+
+<flag name="WeakBosonAndParton:ffbar2gmZgm" default="off">
+Scattering <ei>f fbar -> gamma^*/Z^0 gamma</ei>.
+Code 243.
+</flag>
+
+<flag name="WeakBosonAndParton:fgm2gmZf" default="off">
+Scattering <ei>f gamma -> gamma^*/Z^0 f</ei>.
+Code 244.
+</flag>
+
+<flag name="WeakBosonAndParton:qqbar2Wg" default="off">
+Scattering <ei>q qbar -> W^+- g</ei>.
+Code 251.
+</flag>
+
+<flag name="WeakBosonAndParton:qg2Wq" default="off">
+Scattering <ei>q g -> W^+- q</ei>.
+Code 252.
+</flag>
+
+<flag name="WeakBosonAndParton:ffbar2Wgm" default="off">
+Scattering <ei>f fbar -> W^+- gamma</ei>.
+Code 253.
+</flag>
+
+<flag name="WeakBosonAndParton:fgm2Wf" default="off">
+Scattering <ei>f gamma -> W^+- f</ei>.
+Code 254.
+</flag>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Error Checks">
+
+<h2>Error Checks</h2>
+
+There is a few settings related to error checking during program
+execution. Many other checks are performed as well, but do not
+have any specific setting related to themselves.
+
+<flag name="Check:particleData" default="off">
+Check the particle data tables for potential problems during
+initialization. This includes inconsistent use of charge in particle
+names, inconsistent setup of mass, mass range, width and lifetime,
+sum of branching ratios not unity (allowed but discouraged) or charge
+not conserved in a decay channel. Warnings should be viewed as reasons
+to check further, but need not indicate a true problem, and also not all
+problems may be caught.
+The <code>pythia.particleData.checkTable(level)</code> method,
+used for these checks, may also be called directly.
+</flag>
+
+<modepick name="Check:levelParticleData" default="1">
+The level of verbosity and checks of particle data, if switched on.
+<option value="0">mimimal amount of checks, e.g. that no channels open.
+</option>
+<option value="1">further warning if individual channels closed,
+except for resonances.</option>
+<option value="2">also print branching-ratio-averaged threshold mass
+except for resonances.</option>
+<option value="11">as 1, but include resonances in detailed checks.
+</option>
+<option value="12">as 2, but include resonances in detailed checks.
+</option>
+</modepick>
+
+<flag name="Check:event" default="on">
+When an event has been successfully generated, check that the
+final event record in <code>event</code> does not contain any
+unphysical particles, or nonconserved charge or energy-momentum.
+If this check fails, then <code>pythia.next()</code> obtains the
+value <code>false</code>, i.e. the event is counted as aborted.
+</flag>
+
+<modeopen name="Check:nErrList" default="0">
+The number of erroneous events, in the above check, for which
+event listing and other detailed information will be printed.
+After that, only the normal error messages will be issued.
+Error counters are always updated, and accumulated numbers can be
+shown with <code>pythia.statistics()</code> at the end of the run.
+</modeopen>
+
+<parm name="Check:epTolErr" default="1e-4">
+Maximum allowed summed deviation of <ei>E</ei>, <ei>p_x</ei>,
+<ei>p_y</ei> and <ei>p_z</ei> between the incoming beams and the
+final state, as a fraction of the initial energy, above which the
+event is counted as aborted.
+(Unfortunetely roundoff errors do not scale linearly with the energy,
+and also have a very long tail. So while most events at lower energies
+may be correct to better than 1e-10, at LHC it does not have to signal
+any fundamental bug if also the default tolerance above is violated
+occasionally.)
+</parm>
+
+<parm name="Check:epTolWarn" default="1e-6">
+A check on the same summed deviation as above, but counted as a
+warning rather than an error, and not leading to the event being
+classified as aborted.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Event Analysis">
+
+<h2>Event Analysis</h2>
+
+<h3>Introduction</h3>
+
+The routines in this section are intended to be used to analyze
+event properties. As such they are not part of the main event
+generation chain, but can be used in comparisons between Monte
+Carlo events and real data. They are rather free-standing, but
+assume that input is provided in the PYTHIA 8
+<code>Event</code> format, and use a few basic facilities such
+as four-vectors.
+
+<h3>Sphericity</h3>
+
+The standard sphericity tensor is
+<eq>
+ S^{ab} = (sum_i p_i^a p_i^b) / (sum_i p_i^2)
+</eq>
+where the <ei>sum i</ei> runs over the particles in the event,
+<ei>a, b = x, y, z,</ei> and <ei>p</ei> without such an index is
+the absolute size of the three-momentum . This tensor can be
+diagonalized to find eigenvalues and eigenvectors.
+
+<p/>
+The above tensor can be generalized by introducing a power
+<ei>r</ei>, such that
+<eq>
+ S^{ab} = (sum_i p_i^a p_i^b p_i^{r-2}) / (sum_i p_i^r)
+</eq>
+In particular, <ei>r = 1</ei> gives a linear dependence on momenta
+and thus a collinear safe definition, unlike sphericity.
+
+<p/>
+A sphericity analysis object is declared by
+<class name="Sphericity sph( power, select)">
+where
+<argument name="power" default="2.">
+is the power <ei>r</ei> defined above, i.e.
+<argoption value="2.">gives Spericity, and</argoption>
+<argoption value="1.">gives the linear form.</argoption>
+</argument>
+<argument name="select" default="2">
+tells which particles are analyzed,
+<argoption value="1">all final-state particles,</argoption>
+<argoption value="2">all observable final-state particles,
+i.e. excluding neutrinos and other particles without strong or
+electromagnetic interactions (the <code>isVisible()</code>
+particle method), and
+</argoption>
+<argoption value="3">only charged final-state particles.</argoption>
+</argument>
+</class>
+
+<p/>
+The analysis is performed by a call to the method
+<method name="analyze( event)">
+where
+<argument name="event">is an object of the <code>Event</code> class,
+most likely the <code>pythia.event</code> one.
+</argument>
+<br/>If the routine returns <code>false</code> the analysis failed,
+e.g. if too few particles are present to analyze.
+</method>
+
+<p/>
+After the analysis has been performed, a few <code>Sphericity</code>
+class methods are available to return the result of the analysis:
+<method name="sphericity()">
+gives the sphericity (or equivalent if <ei>r</ei> is not 2),
+</method>
+<method name="aplanarity()">
+gives the aplanarity (with the same comment),
+</method>
+<method name="eigenValue(i)">
+gives one of the three eigenvalues for <ei>i</ei> = 1, 2 or 3, in
+descending order,
+</method>
+<method name="EventAxis(i)">
+gives the matching eigenvector, as a <code>Vec4</code> with vanishing
+time/energy component.
+</method>
+<method name="list()">
+provides a listing of the above information.
+</method>
+<method name="nError()">
+tells the number of times <code>analyze</code> failed to analyze events.
+</method>
+
+<h3>Thrust</h3>
+
+Thrust is obtained by varying the thrust axis so that the longitudinal
+momentum component projected onto it is maximized, and thrust itself is
+then defined as the sum of absolute longitudinal momenta divided by
+the sum of absolute momenta. The major axis is found correspondingly
+in the plane transverse to thrust, and the minor one is then defined
+to be transverse to both. Oblateness is the difference between the major
+and the minor values.
+
+<p/>
+The calculation of thrust is more computer-time-intensive than e.g.
+linear sphericity, introduced above, and has no specific advantages except
+historical precedent. In the PYTHIA 6 implementation the search was
+speeded up at the price of then not being guaranteed to hit the absolute
+maximum. The current implementation studies all possibilities, but at
+the price of being slower, with time consumption for an event with
+<ei>n</ei> particles growing like <ei>n^3</ei>.
+
+<p/>
+A thrust analysis object is declared by
+<class name="Thrust thr( select)">
+where
+<argument name="select" default="2">
+tells which particles are analyzed,
+<argoption value="1">all final-state particles,</argoption>
+<argoption value="2">all observable final-state particles,
+i.e. excluding neutrinos and other particles without strong or
+electromagnetic interactions (the <code>isVisible()</code>
+particle method), and
+</argoption>
+<argoption value="3">only charged final-state particles.</argoption>
+</argument>
+</class>
+
+<p/>
+The analysis is performed by a call to the method
+<method name="analyze( event)">
+where
+<argument name="event">is an object of the <code>Event</code> class,
+most likely the <code>pythia.event</code> one.
+</argument>
+<br/>If the routine returns <code>false</code> the analysis failed,
+e.g. if too few particles are present to analyze.
+</method>
+
+<p/>
+After the analysis has been performed, a few <code>Thrust</code>
+class methods are available to return the result of the analysis:
+<method name="thrust(), tMajor(), tMinor(), oblateness()">
+gives the thrust, major, minor and oblateness values, respectively,
+<method name="EventAxis(i)">
+gives the matching event-axis vectors, for <ei>i</ei> = 1, 2 or 3
+corresponding to thrust, major or minor, as a <code>Vec4</code> with
+vanishing time/energy component.
+</method>
+<method name="list()">
+provides a listing of the above information.
+</method>
+<method name="nError()">
+tells the number of times <code>analyze</code> failed to analyze events.
+</method>
+
+<h3>ClusterJet</h3>
+
+<code>ClusterJet</code> (a.k.a. <code>LUCLUS</code> and
+<code>PYCLUS</code>) is a clustering algorithm of the type used for
+analyses of <ei>e^+e^-</ei> events, see the PYTHIA 6 manual. A few
+options are available for some well-known distance measures. Cutoff
+distances can either be given in terms of a scaled quadratic quantity
+like <ei>y = pT^2/E^2</ei> or an unscaled linear one like <ei>pT</ei>.
+
+<p/>
+A cluster-jet analysis object is declared by
+<class name="ClusterJet clusterJet( measure, select, massSet,
+precluster, reassign)">
+where
+<argument name="measure" default="Lund">distance measure, to be provided
+as a character string (actually, only the first character is necessary)
+<argoption value="Lund">the Lund <ei>pT</ei> distance,</argoption>
+<argoption value="JADE">the JADE mass distance, and</argoption>
+<argoption value="Durham">the Durham <ei>kT</ei> measure.</argoption>
+</argument>
+<argument name="select" default="2">
+tells which particles are analyzed,
+<argoption value="1">all final-state particles,</argoption>
+<argoption value="2">all observable final-state particles,
+i.e. excluding neutrinos and other particles without strong or
+electromagnetic interactions (the <code>isVisible()</code> particle
+method), and
+</argoption>
+<argoption value="3">only charged final-state particles.</argoption>
+</argument>
+<argument name="massSet" default="2">masses assumed for the particles
+used in the analysis
+<argoption value="0">all massless,</argoption>
+<argoption value="1">photons are massless while all others are
+assigned the <ei>pi+-</ei> mass, and
+</argoption>
+<argoption value="2">all given their correct masses.</argoption>
+</argument>
+<argument name="precluster" default="false">
+perform or not a early preclustering step, where nearby particles
+are lumped together so as to speed up the subsequent normal clustering.
+</argument>
+<argument name="reassign" default="false">
+reassign all particles to the nearest jet each time after two jets
+have been joined.
+</argument>
+</class>
+
+<p/>
+The analysis is performed by a
+<method name="analyze( event, yScale, pTscale, nJetMin, nJetMax)">
+where
+<argument name="event">is an object of the <code>Event</code> class,
+most likely the <code>pythia.event</code> one.
+</argument>
+<argument name="yScale">
+is the cutoff joining scale, below which jets are joined. Is given
+in quadratic dimensionless quantities. Either <code>yScale</code>
+or <code>pTscale</code> must be set nonvanishing, and the larger of
+the two dictates the actual value.
+</argument>
+<argument name="pTscale">
+is the cutoff joining scale, below which jets are joined. Is given
+in linear quantities, such as <ei>pT</ei> or <ei>m</ei> depending on
+the measure used, but always in units of GeV. Either <code>yScale</code>
+or <code>pTscale</code> must be set nonvanishing, and the larger of
+the two dictates the actual value.
+</argument>
+<argument name="nJetMin" default="1">
+the minimum number of jets to be reconstructed. If used, it can override
+the <code>yScale</code> and <code>pTscale</code> values.
+</argument>
+<argument name="nJetMax" default="0">
+the maximum number of jets to be reconstructed. Is not used if below
+<code>nJetMin</code>. If used, it can override the <code>yScale</code>
+and <code>pTscale</code> values. Thus e.g.
+<code>nJetMin = nJetMax = 3</code> can be used to reconstruct exactly
+3 jets.
+</argument>
+<br/>If the routine returns <code>false</code> the analysis failed,
+e.g. because the number of particles was smaller than the minimum number
+of jets requested.
+</method>
+
+<p/>
+After the analysis has been performed, a few <code>ClusterJet</code>
+class methods are available to return the result of the analysis:
+<method name="size()">
+gives the number of jets found, with jets numbered 0 through
+<code>size() - 1</code>,
+</method>
+<method name="p(i)">
+gives a <code>Vec4</code> corresponding to the four-momentum defined by
+the sum of all the contributing particles to the <ei>i</ei>'th jet,
+</method>
+<method name="jetAssignment(i)">
+gives the index of the jet that the particle <ei>i</ei> of the event
+record belongs to,
+</method>
+<method name="list()">
+provides a listing of the reconstructed jets.
+</method>
+<method name="nError()">
+tells the number of times <code>analyze</code> failed to analyze events.
+</method>
+
+<h3>CellJet</h3>
+
+<code>CellJet</code> (a.k.a. <code>PYCELL</code>) is a simple cone jet
+finder in the UA1 spirit, see the PYTHIA 6 manual. It works in an
+<ei>(eta, phi, eT)</ei> space, where <ei>eta</ei> is pseudorapidity,
+<ei>phi</ei> azimuthal angle and <ei>eT</ei> transverse energy.
+It will draw cones in <ei>R = sqrt(Delta-eta^2 + Delta-phi^2)</ei>
+around seed cells. If the total <ei>eT</ei> inside the cone exceeds
+the threshold, a jet is formed, and the cells are removed from further
+analysis. There are no split or merge procedures, so later-found jets
+may be missing some of the edge regions already used up by previous
+ones.
+
+<p/>
+A cell-jet analysis object is declared by
+<class name="CellJet cellJet( etaMax, nEta, nPhi, select, smear,
+resolution, upperCut, threshold)">
+where
+<argument name="etaMax" default="5.">
+the maximum +-pseudorapidity that the detector is assumed to cover.
+</argument>
+<argument name="nEta" default="50">
+the number of equal-sized bins that the <ei>+-etaMax</ei> range
+is assumed to be divided into.
+</argument>
+<argument name="nPhi" default="32">
+the number of equal-sized bins that the <ei>phi</ei> range
+<ei>+-pi</ei> is assumed to be divided into.
+</argument>
+<argument name="select" default="2">
+tells which particles are analyzed,
+<argoption value="1">all final-state particles,</argoption>
+<argoption value="2">all observable final-state particles,
+i.e. excluding neutrinos and other particles without strong or
+electromagnetic interactions (the <code>isVisible()</code> particle
+method),
+and</argoption>
+<argoption value="3">only charged final-state particles.</argoption>
+</argument>
+<argument name="smear" default="0">
+strategy to smear the actual <ei>eT</ei> bin by bin,
+<argoption value="0">no smearing,</argoption>
+<argoption value="1">smear the <ei>eT</ei> according to a Gaussian
+with width <ei>resolution * sqrt(eT)</ei>, with the Gaussian truncated
+at 0 and <ei>upperCut * eT</ei>,</argoption>
+<argoption value="2">smear the <ei>e = eT * cosh(eta)</ei> according
+to a Gaussian with width <ei>resolution * sqrt(e)</ei>, with the
+Gaussian truncated at 0 and <ei>upperCut * e</ei>.</argoption>
+</argument>
+<argument name="resolution" default="0.5">
+see above
+</argument>
+<argument name="upperCut" default="2.">
+see above
+</argument>
+<argument name="threshold" default="0 GeV">
+completely neglect all bins with an <ei>eT < threshold</ei>.
+</argument>
+</class>
+
+<p/>
+The analysis is performed by a
+<method name="analyze( event, eTjetMin, coneRadius, eTseed)">
+where
+<argument name="event">is an object of the <code>Event</code> class,
+most likely the <code>pythia.event</code> one.
+</argument>
+<argument name="eTjetMin" default="20. GeV">
+is the minimum transverse energy inside a cone for this to be
+accepted as a jet.
+</argument>
+<argument name="coneRadius" default="0.7">
+ is the size of the cone in <ei>(eta, phi)</ei> space drawn around
+the geometric center of the jet.
+</argument>
+<argument name="eTseed" default="1.5 GeV">
+the mimimum <ei>eT</ei> in a cell for this to be acceptable as
+the trial center of a jet.
+</argument>
+<br/>If the routine returns <code>false</code> the analysis failed,
+but currently this is not foreseen ever to happen.
+</method>
+
+<p/>
+After the analysis has been performed, a few <code>CellJet</code>
+class methods are available to return the result of the analysis:
+<method name="size()">
+gives the number of jets found, with jets numbered 0 through
+<code>size() - 1</code>,
+</method>
+<method name="eT(i)">
+gives the <ei>eT</ei> of the <ei>i</ei>'th jet, where jets have been
+ordered with decreasing <ei>eT</ei> values,
+</method>
+<method name="etaCenter(i), phiCenter(i)">
+gives the <ei>eta</ei> and <ei>phi</ei> coordinates of the geometrical
+center of the <ei>i</ei>'th jet,
+</method>
+<method name="etaWeighted(i), phiWeighted(i)">
+gives the <ei>eta</ei> and <ei>phi</ei> coordinates of the
+<ei>eT</ei>-weighted center of the <ei>i</ei>'th jet,
+</method>
+<method name="multiplicity(i)">
+gives the number of particles clustered into the <ei>i</ei>'th jet,
+</method>
+<method name="pMassless(i)">
+gives a Vec4 corresponding to the four-momentum defined by the
+<ei>eT</ei> and the weighted center of the <ei>i</ei>'th jet,
+</method>
+<method name="pMassive(i)">
+gives a <code>Vec4</code> corresponding to the four-momentum defined by
+the sum of all the contributing cells to the <ei>i</ei>'th jet, where
+each cell contributes a four-momentum as if all the <ei>eT</ei> is
+deposited in the center of the cell,
+</method>
+<method name="m(i)">
+gives the invariant mass of the <ei>i</ei>'th jet, defined by the
+<code>pMassive</code> above,
+</method>
+<method name="list()">
+provides a listing of the above information (except <code>pMassless</code>,
+for reasons of space).
+</method>
+<method name="nError()">
+tells the number of times <code>analyze</code> failed to analyze events.
+</method>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Event Information">
+
+<h2>Event Information</h2>
+
+The <code>Info</code> class collects various one-of-a-kind information,
+some relevant for all events and others for the current event.
+An object <code>info</code> is a public member of the <code>Pythia</code>
+class, so if you e.g. have declared <code>Pythia pythia</code>, the
+<code>Info</code> methods can be accessed by
+<code>pythia.info.method()</code>. Most of this is information that
+could also be obtained e.g. from the event record, but is here more
+directly available. It is primarily intended for processes generated
+internally in PYTHIA, but many of the methods would work also for
+events fed in via the Les Houches Accord.
+
+<p/>
+Here are the currently available methods related to each event:
+
+<method name="list()">
+a listing of most of the information set for the current event.
+</method>
+
+<method name="idA(), idB()">
+the identities of the two beam particles.
+</method>
+
+<method name="pzA(), pzB()">
+the longitudinal momenta of the two beam particles.
+</method>
+
+<method name="eA(), eB()">
+the energies of the two beam particles.
+</method>
+
+<method name="mA(), mB()">
+the masses of the two beam particles.
+</method>
+
+<method name="eCM(), s()">
+the cm energy and its square for the two beams.
+</method>
+
+<method name="name(), code()">
+the name and code of the process that occured.
+</method>
+
+<method name="nFinal()">
+the number of final-state partons in the hard process.
+</method>
+
+<method name="isResolved()">
+are beam particles resolved, i.e. were PDF's used for the process?
+</method>
+
+<method name="isDiffractiveA(), isDiffractiveB()">
+is either beam diffractively excited?
+</method>
+
+<method name="isMinBias()">
+is the process a minimum-bias one?
+</method>
+
+<method name="isLHA()">
+has the process been generated from external Les Houches Accord
+information?
+</method>
+
+<method name="atEndOfFile()">
+true if a linked Les Houches class refuses to return any further
+events, presumably because it has reached the end of the file from
+which events have been read in.
+</method>
+
+<method name="hasSub()">
+does the process have a subprocess classification?
+Currently only true for minbias and Les Houches events, where it allows
+the hardest collision to be identified.
+</method>
+
+<method name="nameSub(), codeSub(), nFinalSub()">
+the name, code and number of final-state partons in the subprocess
+that occured when <code>hasSub()</code> is true. For a minimum-bias event
+the <code>code</code> would always be 101, while <code>codeSub()</code>
+would vary depending on the actual hardest interaction, e.g. 111 for
+<ei>g g -> g g</ei>. For a Les Houches event the <code>code</code> would
+always be 9999, while <code>codeSub()</code> would be the external
+user-defined classification code. The methods below would also provide
+information for such particular subcollisions.
+</method>
+
+<method name="id1(), id2()">
+the identities of the two partons coming in to the hard process.
+</method>
+
+<method name="x1(), x2()">
+<ei>x</ei> fractions of the two partons coming in to the hard process.
+</method>
+
+<method name="y(), tau()">
+rapidity and scaled mass-squared of the hard-process subsystem, as
+defined by the above <ei>x</ei> values.
+</method>
+
+<method name="pdf1(), pdf2()">
+parton densities <ei>x*f(x,Q^2</ei> )evaluated for the two incoming
+partons; could be used e.g. for reweighting purposes.
+</method>
+
+<method name="QFac(), Q2Fac()">
+the <ei>Q^2</ei> or <ei>Q^2</ei> factorization scale at which the
+densities were evaluated.
+</method>
+
+<method name="isValence1(), isValence2()">
+<code>true</code> if the two hard incoming partons have been picked
+to belong to the valence piece of the parton-density distribution,
+else <code>false</code>. Should be interpreted with caution.
+Information is not set if you switch off parton-level processing.
+</method>
+
+<method name="alphaS(), alphaEM()">
+the <ei>alpha_strong</ei> and <ei>alpha_electromagnetic</ei> values used
+for the hard process.
+</method>
+
+<method name="QRen(), Q2Ren()">
+the <ei>Q</ei> or <ei>Q^2</ei> renormalization scale at which
+<ei>alpha_strong</ei> and <ei>alpha_electromagnetic</ei> were evaluated.
+</method>
+
+<method name="mHat(), sHat()">
+the invariant mass and its square for the hard process.
+</method>
+
+<method name="tHat(), uHat()">
+the remaining two Mandelstam variables; only defined for <ei>2 -> 2</ei>
+processes.
+</method>
+
+<method name="pTHat(), pT2Hat()">
+transverse momentum and its square in the rest frame of a <ei>2 -> 2</ei>
+processes.
+</method>
+
+<method name="m3Hat(), m4Hat()">
+the masses of the two outgoing particles in a <ei>2 -> 2</ei> processes.
+</method>
+
+<method name="thetaHat(), phiHat()">
+the polar and azimuthal scattering angles in the rest frame of
+a <ei>2 -> 2</ei> process.
+</method>
+
+<method name="weight()">
+weight assigned to the current event. Is normally 1 and thus uninteresting.
+However, for Les Houches events some strategies allow negative weights,
+which then after unweighting lead to events with weight -1. There are also
+strategies where no unweighting is done, and therefore a nontrivial event
+weight must be used e.g. when filling histograms.
+</method>
+
+<method name="bMI()">
+the impact parameter <ei>b</ei> assumed for the current collision when
+multiple interactions are simulated. Is not expressed in any physical
+size (like fm), but only rescaled so that the average should be unity
+for minimum-bias events (meaning less than that for events with hard
+processes).
+</method>
+
+<method name="enhanceMI()">
+The choice of impact parameter implies an enhancement or depletion of
+the rate of subsequent interactions, as given by this number. Again
+the average is normalized be unity for minimum-bias events (meaning
+more than that for events with hard processes).
+</method>
+
+<method name="nMI()">
+the number of hard interactions in the current event. Is 0 for elastic
+and diffractive events, and else at least 1, with more possible from
+multiple interactions.
+</method>
+
+<method name="codeMI(i), pTMI(i)">
+the process code and transverse momentum of the <code>i</code>'th
+subprocess, with <code>i</code> in the range from 0 to
+<code>nMI() - 1</code>. The values for subprocess 0 is redundant with
+information already provided above.
+</method>
+
+<method name="nISR(), nFSRinProc(), nFSRinRes()">
+the number of emissions in the initial-state showering, in the final-state
+showering excluding resonance decys, and in the final-state showering
+inside resonance decays, respectively.
+</method>
+
+<p/>
+Here are the currently available methods related to the event sample
+as a whole. While continuously updated during the run, it is recommended
+only to study these properties at the end of the event generation,
+when the full statistics is available.
+
+<method name="nTried(), nSelected(), nAccepted()">
+the total number of tried phase-space points, selected hard processes
+and finally accepted events, summed over all allowed subprocesses.
+The first number is only intended for a study of the phase-space selection
+efficiency. The last two numbers usually only disagree if the user introduces
+some veto during the event-generation process; then the former is the number
+of acceptable events found by PYTHIA and the latter the number that also
+were approved by the user. If you set <aloc href="ASecondHardProcess">a
+second hard process</aloc> there may also be a mismatch.
+</method>
+
+<method name="sigmaGen(), sigmaErr()">
+the estimated cross section and its estimated error,
+summed over all allowed subprocesses, in units of mb. The numbers refer to
+the accepted event sample above, i.e. after any user veto.
+</method>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="The Event Record">
+
+<h2>The Event Record</h2>
+
+The <code>Event</code> class for event records basically is a vector of
+<code>Particle</code>s, so that it can expand to fit the event size.
+The index operator is overloaded, so that <code>event[i]</code>
+corresponds to the <code>i</code>'th particle of an <code>Event</code>
+object <code>event</code>. Thus <code>event[i].id()</code> returns the
+identity of the <code>i</code>'th particle. References to the first,
+<code>i</code>'th and last particle are obtained with
+<code>event.front()</code>, <code>event.at(i)</code> and
+<code>event.back()</code>, respectively.
+
+<p/>
+The event size can be found with <code>size()</code>, i.e. valid
+particles are stored in <code>0 <= i < event.size()</code>.
+
+<p/>
+Line 0 is used to represent the event as a whole, with its total
+four-momentum and invariant mass, but does not form part of the
+event history. Lines 1 and 2 contains the two incoming beams, and
+only from here on history tracing works as could be expected. That
+way unassigned mother and daughter indices can be put 0 without
+ambiguity. Depending on the task at hand, a loop may therefore start
+at an index 1 without any loss. Specifically, for translation to other
+event record formats such as HepMC <ref>Dob01</ref>, where the first
+index is 1, the Pythia entry 0 definitely ought to be skipped in order
+to minimize the danger of errors.
+
+<p/>
+New particles can be added to the end of the current event record
+with <code>append(Particle)</code>, or
+<code>append(id, status, mother1, mother2, daughter1, daughter2,
+col, acol, p, m, scale)</code>
+where <code>p</code> is the four-momentum vector, and everything except
+<code>id</code> defaults to 0. The <code>append</code> method returns
+the index of the new particle position.
+
+<p/>
+The existing particle at index <code>iCopy</code> can be copied to the end
+with <code>copy(iCopy, newStatus = 0)</code>. By default, i.e. with
+<code>newStatus = 0</code>, everything is copied precisely as it is,
+which means that history information has to be modified further by hand
+to make sense. With a positive <code>newStatus</code>, the new copy is set
+up to be the daughter of the old, with status code <code>newStatus</code>,
+and the status code of <code>iCopy</code> is negated. With a negative
+<code>newStatus</code>, the new copy is instead set up to be the mother
+of <code>iCopy</code>.
+
+<p/>
+The event record can be emptied for the next event by a
+<code>clear()</code>. The last <code>n</code> entries can be removed by
+<code>popBack(n)</code>, where <code>n = 1</code> by default.
+The <code>=</code> operator is overloaded to allow a copying of
+an event record, and <code>+=</code> to append an event to an
+existing one. In the latter case mother, daughter and colour tags are
+shifted to make a consistent record. The zeroth particle of the
+appended event is not copied, but the zeroth particle of the combined
+event is updated to the full energy-momentum content.
+
+<p/>
+A listing of the whole event is obtained with <code>list()</code>.
+The basic id, status, mother, daughter, colour, four-momentum
+and mass data are always given, but the method can also be called with
+a few optional arguments for further information:
+<method name="list(showScaleAndVertex, showMothersAndDaughters, os)">
+where
+<argument name="showScaleAndVertex" default="false"> optionally give a
+second line for each particle, with the production scale (in GeV), the
+production vertex (in mm or mm/c) and the invariant lifetime
+(also in mm/c).
+</argument>
+<argument name="showMothersAndDaughters" default="false">
+gives a list of all daughters and mothers of a particle, as defined by
+the <code>motherList(i)</code> and <code>daughterList(i)</code> methods
+described below. It is mainly intended for debug purposes.
+</argument>
+<argument name="os" default="cout"> a reference to the <code>ostream</code>
+object to which the event listing will be directed.
+</argument>
+</method>
+
+<p/>
+Each particle in the event record has a pointer to the corresponding
+particle species in the particle database, used to find some particle
+properties. This pointer is automatically set whenever the particle
+identity is set by one of the normal methods. Of course its value is
+specific to the memory location of the current run, and so it has no
+sense to save it if events are written to file. Should you use some
+persistency scheme that bypasses the normal methods when the event is
+read back in, you can use <code>restorePtrs()</code> afterwards to set
+these pointers appropriately.
+
+<p/>
+The user would normally be concerned with the <code>Event</code> object
+that is a public member <code>event</code> of the <code>Pythia</code> class.
+Thus, having declared a <code>Pythia</code> object <code>pythia</code>,
+<code>pythia.event[i].id()</code> would be used to return the identity
+of the <code>i</code>'th particle, and <code>pythia.event.size()</code> to
+give the size of the event record.
+
+<p/>
+A <code>Pythia</code> object contains a second event record for the
+hard process alone, called <code>process</code>, used as input for the
+generation of the complete event. Thus one may e.g. call either
+<code>pythia.process.list()</code> or <code>pythia.event.list()</code>.
+To distinguish those two rapidly at visual inspection, the
+<code>"Pythia Event Listing"</code> header is printed out differently,
+in one case adding <code>"(hard process)"</code> and in the other
+<code>"(complete event)"</code>. When <code>+=</code> is used to
+append an event, the modified event is printed with
+<code>"(combination of several events)"</code> as a reminder.
+
+<p/>
+One data member in an <code>Event</code> object is used to keep track of the
+largest <code>col()</code> or <code>acol()</code> tag set so far, so that
+new ones do not clash. The <code>lastcolTag()</code> method returns the
+last tag assigned, i.e. largest value in the current event, and
+<code>nextColTag()</code> ups it by one before returing the value. The
+latter method thus is used when a new colour tag is needed.
+
+<modeopen name="Event:startColTag" default="100" min="0" max="1000">
+This sets the initial value used, so that the first one assigned is
+<code>startColTag+1</code>, etc. The Les Houches accord <ref>Boo01</ref>
+suggests this number to be 500, but 100 works equally well.
+</modeopen>
+
+<p/>
+The <code>scale()</code> methods can be used to set or get the scale
+(in GeV) of the event as a whole. Further methods for event properties
+may be added in the future.
+
+<p/>
+A few methods exist to rotate and boost events. These derive from the
+<aloc href="FourVectors">Vec4</aloc> methods, and affect both the
+momentum and the vertex (position) components of all particles.
+
+<method name="rot(theta, phi)">
+rotate by this polar and azimuthal angle (expressed in radians).
+</method>
+
+<method name="bst(betaX, betaY, betaZ)">
+boost by this vector. Optionally you may provide the <ei>gamma</ei>
+value as a fourth argument, if you deem this may help avoid roundoff
+errors for big boosts. You may alternatively supply a <code>Vec4</code>
+four-vector, in which case the boost vector <ei>beta = p/E</ei>.
+</method>
+
+<method name="rotbst(M)">
+rotate and boost by the combined action encoded in the
+<aloc href="FourVectors"><code>RotBstMatrix</code></aloc> <code>M</code>.
+</method>
+
+<p/>
+There are also a few methods with an individual particle index
+<code>i</code> as input, but requiring some search operations in
+the event record, and therefore not possible to define inside the
+<code>Particle</code> class:
+
+<method name="motherList(i)">
+returns a <code>vector<int></code> containing a list of all the
+mothers of a particle. This list is empty for entries 0, 1 and 2,
+i.e. the "system" in line 0 is not counted as part of the history.
+Normally the list contains one or two mothers, but it can also be more,
+e.g. in string fragmentation the whole fragmenting system is counted
+as mothers to the primary hadrons. Mothers are listed in ascending order.
+</method>
+
+<method name="daughterList(i)">
+returns a <code>vector<int></code> containing a list of all the
+daughters of a particle. This list is empty for a particle that did
+not decay (or, if the evolution is stopped early enough, a parton
+that did not branch), while otherwise it can contain a list of
+varying length, from one to many. Many partons may have the same
+<code>daughterList</code>, e.g. in the hard process and fragmentation
+steps. For the two incoming beam particles, all shower initiators and
+beam remnants are counted as daughters, with the one in slot 0 being
+the one leading up to the hardest interaction. The "system" in line 0
+does not have any daughters, i.e. is not counted as part of the history.
+</method>
+
+<method name="iTopCopy(i), iBotCopy(i)">
+are used to trace carbon copies of the particle at index <code>i</code> up
+to its top mother or down to its bottom daughter. If there are no such
+carbon copies, <code>i</code> itself will be returned.
+</method>
+
+<method name="iTopCopyId(i), iBotCopyId(i)">
+also trace top mother and bottom daughter, but do not require carbon
+copies, only that one can find an unbroken chain, of mothers or daughters,
+with the same flavour <code>id</code> code. When it encounters ambiguities,
+say a <ei>g -> g g</ei> branching or a <ei>u u -> u u</ei> hard scattering,
+it will stop the tracing and return the current position. It can be confused
+by nontrivial flavour changes, e.g. a hard process <ei>u d -> d u</ei>
+by <ei>W^+-</ei> exchange will give the wrong answer. These methods
+therefore are of limited use for common particles, in particular for the
+gluon, but should work well for "rare" particles.
+</method>
+
+<method name="sisterList(i)">
+returns a <code>vector<int></code> containing a list of all the
+sisters of a particle, i.e. all the daughters of the first mother,
+except the particle itself.
+</method>
+
+<method name="sisterListTopBot(i)">
+returns a <code>vector<int></code> containing a list of all the
+sisters of a particle, tracking up and back down through carbon copies
+if required. That is, the particle is first traced up with
+<code>iTopCopy()</code> before its mother is found, and then all
+the particles in the <code>daughterList()</code> of this mother are
+traced down with <code>iBotCopy()</code>, omitting the original
+particle itself. Any non-final particles are removed from the list.
+Should this make the list empty the search criterion is widened so that
+all final daughters are allowed, not only carbon-copy ones. A second
+argument <code>false</code> inhibits the second step, and increases
+the risk that an empty list is returned. A typical example of this
+is for ISR cascades, e.g. <ei>e -> e gamma</ei> where the photon
+may not have any obvious sister in the final state if the bottom copy
+of the photon is an electron that annihilates and thus is not part of
+the final state.
+</method>
+
+<method name="isAncestor(i, iAncestor)">
+traces the particle <code>i</code> upwards through mother, grandmother,
+and so on, until either <code>iAncestor</code> is found or the top of
+the record is reached. Normally one unique mother is required,
+as is the case e.g. in decay chains or in parton showers, so that
+e.g. the tracing through a hard scattering would not work. For
+hadronization, first-rank hadrons are identified with the respective
+string endpoint quark, which may be useful e.g. for <ei>b</ei> physics,
+while higher-rank hadrons give <code>false</code>. Currently also
+ministrings that collapsed to one single hadron and junction topologies
+give <code>false</code>.
+</method>
+
+<h3>The Junction Class</h3>
+
+The event record also contains a vector of junctions, which often
+is empty or else contains only a very few per event. Methods are
+available to add further junctions or query the current junction list.
+This is only for the expert user, however, and is not discussed
+further here, but only the main points.
+
+<p/>
+A junction stores the properites associated with a baryon number that
+is fully resolved, i.e. where three different colour indices are
+involved. There are two main applications,
+<ol>
+<li>baryon beams, where at least two valence quarks are kicked out,
+and so the motion of the baryon number is notrivial;</li>
+<li>baryon-number violating processes, e.g. in SUSY with broken
+<ei>R</ei>-parity.</li>
+</ol>
+Information on junctions is set, partly in the process generation,
+partly in the beam remnants machinery, and used by the fragmentation
+routines, but the normal user does not have to know the details.
+
+<p/>
+For each junction, information is stored on the kind of junction, and
+on the three (anti)colour indices that are involved in the junction.
+The possibilities foreseen are:
+<ul>
+<li><code>kind = 1</code> : incoming colourless particle to three
+outgoing colours (e.g. baryon beam remnant or
+<ei>neutralino -> q q q</ei>);</li>
+<li><code>kind = 2</code> : incoming colourless particle to three
+outgoing anticolours;</li>
+<li><code>kind = 3</code> : one incoming anticolor (stored first)
+and two outgoing colours (e.g. antisquark decaying to quark);</li>
+<li><code>kind = 4</code> : one incoming color (stored first) and two
+outgoing anticolours;</li>
+<li><code>kind = 5</code> : incoming colour octet to three colours,
+where the incoming colour passes through unchanged and so need not
+be bokkept here, while the incoming anticolor (stored first) and the
+two outgoing colours are (e.g. gluino decay to three quarks);</li>
+<li><code>kind = 6</code> : incoming colour octet to three anticolours,
+where the incoming anticolour passes through unchanged and so need not
+be bookkept here, while the incoming color (stored first) and the two
+outgoing colours are.</li>
+</ul>
+The odd (even) <code>kind</code> codes corresponds to a +1 (-1) change in
+baryon number across the junction.
+<note>Warning:</note> Currently only <code>kind = 1, 2</code> are
+implemented.
+
+<p/>
+The kind and colour information in the list of junctions can be set
+or read with methods of the <code>Event</code> class, but are not of
+common interest and so not described here.
+
+<p/>
+A listing of current junctions can be obtained with the
+<code>listJunctions()</code> method.
+
+<h3>Subsystems</h3>
+
+The event record also contains a few vectors where parton indices can be
+stored, classified by subsystem. Such information is needed to interleave
+multiple interactions, initial-state showers, final-state showers
+and beam remnants. It could also be used in other places. It is intended
+to be accessed only by experts, such as implementors of
+<aloc href="ImplementNewShowers">new showering models</aloc>.
+
+<p/>
+A listing of current subsystems can be obtained with the
+<code>listSystems()</code> method.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Event Statistics">
+
+<h2>Event Statistics</h2>
+
+At the end of the run you will want to write out the final statistics
+on number of events generated, the corresponding cross sections and
+the number of errors encountered. This is done with
+<pre>
+ pythia.statistics(all = false, reset = false);
+</pre>
+assuming <code>pythia</code> is an instance of the <code>Pythia</code>
+class.
+<ul>
+<li>The optional argument <code>all</code>, if <code>true</code>,
+allows a more extensive listing than the default one, see
+multiple-interactions statistics below.</li>
+<li>The optional argument <code>reset</code>, if <code>true</code>,
+implies that all counters, e.g on events generated and errors experienced,
+are reset to zero whenever the routine is called. The default instead is
+that all stored statistics information is unaffected by the call.
+Counters are automatically reset in each new <code>pythia.init()</code>
+call, however, so the only time the <code>reset</code> option makes a
+difference is if <code>statistics</code> is called several times in a
+(sub)run.</li>
+</ul>
+
+<p/>
+The <code>pythia.statistics(...)</code> method in its turn calls on the
+methods below, for the different kinds of information.
+
+<h3>Cross-section statistics</h3>
+
+The <code>ProcessLevel::statistics()</code> member will loop over the
+list of existing processes, and for each write out name, code,
+the number of tried, selected and accepted events, the cross section and
+the estimated error on the latter. The three different event numbers are
+related to the Monte Carlo method used, whereby an initial upper estimate
+of the cross section is used to select a large number of trial phase-space
+points, whereof then not all survive. Rejections are normally done by the
+internal machinery, but can also be obtained by
+<aloc href="UserHooks">user hooks</aloc>.
+Therefore:
+<ul>
+<li><b>tried</b> events reflect the original number of
+phase-space points probed, as part of the upper estimate;</li>
+<li><b>selected</b> events correspond to those that survive
+the internal Monte-Carlo selection procedure;</li>
+<li><b>accepted</b> events are those that also survive
+the additional user cuts.</li>
+</ul>
+In most runs there would be no user hooks implemented, and then the
+numbers of selected and of accepted events will agree. Aborted events
+(see below) usually appear in the selected statistics but not in the
+accepted one.
+
+<p/>
+For Les Houches events the total cross section will be correctly
+displayed; however the (optional) error value will not be used, so that
+the reported error will be smaller than the correct statistical ones,
+and often vanish completely. Furthermore, while the number of events
+is shown for each user process, the cross section is only for the sum
+of them.
+
+<h3>Error messages</h3>
+
+When Pythia is run, errors may occur, and give rise to warning messages.
+These may be of varying severity, as follows:
+<ul>
+<li><b>Abort</b> means things went seriously wrong, and the
+initialization or event generation failed. In the former case it is
+not possible to generate events at all, in the latter the current
+event is flawed and should be skipped. In either case the respective
+method, <code>pythia.init(...)</code> or <code>pythia.next()</code>,
+then also returns the value <code>false</code>. There are occasions
+where an abort may be deliberate, such as when a file of Les Houches
+Events is read and the end of the file is reached.</li>
+<li><b>Error</b> normally is less severe. Typically the program will
+back up one step and try again. There are cases where this is not possible,
+in particular during the initialization and the generation of a hard
+process, and then the error may be followed by an abort as a direct
+consequence (with two separate messages).</li>
+<li><b>Warning</b> is even less severe. In some cases the program will
+try again, with good chances of success, in others no measure at all
+need to be taken.</li>
+</ul>
+
+<p/>
+The error messages is handled by a small part of the <code>Info</code>
+class. It is handed any abort, error or warning messages during the event
+generation phase, and will store each distinct message, with a counter
+for how many times it is issued. Thus it is possible to limit the number
+of identical messages issued, currently hardcoded so that each kind of
+error message is only printed once
+(<code>static const int TIMESTOPRINT = 1</code>).
+The summary table printed by <code>pythia.statistics()</code>
+provides a table with all the different messages issued, in
+alphabetical order, with the total number of times each was generated.
+
+<h3>Multiple-interactions statistics</h3>
+
+If you call <code>pythia.statistics(true)</code>, i.e. with the first
+optional argument <code>true</code>, also statistics on multiple
+interactions is printed, comprising a list of all allowed subprocesses
+with how many times each of them has been generated. For the minimum-bias
+process this also includes the hardest interaction, while else the
+hardest process is excluded from the statistics. (This is because
+the hardest process is of the same character and generated by the same
+machinery in the former case but not in the latter. Also, for the
+former case only, the standard statistics listing only lists
+minimum bias as one single process, i.e. does not further specify
+the character of the hardest subprocess, so there is not any overlap
+between the two.)
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="External Decays">
+
+<h2>External Decays</h2>
+
+<code>DecayHandler</code> is a base class for the external handling of
+decays. It is intended for normal particle decays, primarily
+<ei>B</ei> mesons and <ei>tau</ei>, and cannot be used to redirect
+decays of heavy resonances like <ei>t</ei> or <ei>Z^0</ei>.
+The user-written derived class is called if a pointer to it has
+been given with the <aloc href="ProgramFlow">
+<code>pythia.decayPtr()</code></aloc>
+method, where it also is specified which particles it will be called for.
+This particle information is accessible with the
+<aloc href="ParticleDataScheme"><code>doExternalDecay()</code></aloc>
+method.
+
+<p/>
+There is only one pure virtual method in <code>DecayHandler</code>,
+to do the decay:
+<method name="virtual bool decay(vector<int>& idProd, vector<double>&
+mProd, vector<Vec4>& pProd, int iDec, const Event& event)">
+where
+<argument name="idProd"> is a list of particle PDG identity codes,
+</argument>
+<argument name="mProd"> is a list of their respective masses (in GeV), and
+</argument>
+<argument name="pProd"> is a list of their respective four-momenta.
+</argument>
+</method>
+
+<p/>
+At input, these vectors each have size one, so that <code>idProd[0]</code>,
+<code>mProd[0]</code> and <code>pProd[0]</code> contain information on the
+particle that is to be decayed. At output, the vectors should have
+increased by the addition of all the decay products. Even if initially
+defined in the rest frame of the mother, the products should have been
+boosted so that their four-momenta add up to the <code>pProd[0]</code> of
+the decaying particle.
+
+<p/>
+Should it be of interest to know the prehistory of the decaying
+particle, e.g. to set some helicity information affecting the
+decay angular distribution, the full event record is available
+read-only, with info in which slot <code>iDec</code> the decaying particle
+is stored.
+
+<p/>
+The routine should return <code>true</code> if it managed the decay and
+<code>false</code> otherwise, in which case <code>Pythia</code> will try
+to do the decay itself. This e.g. means you can choose to do some decay
+channels yourself, and leave others to <code>Pythia</code>. To avoid
+doublecounting, the channels you want to handle should be switched off
+in the <code>Pythia</code> particle database. In the beginning of the
+external <code>decay</code> method you should then return
+<code>false</code> with a probability given by the sum of the branching
+ratios for those channels you do not want to handle yourself.
+
+<p/>
+Note that the decay vertex is always set by <code>Pythia</code>, and that
+<ei>B-Bbar</ei> oscillations have already been taken into account,
+if they were switched on. Thus <code>idProd[0]</code> may be the opposite
+of <code>event[iDec].id()</code>, where the latter provides the code at
+production.
+
+<p/>
+A sample test program is available in <code>main23.cc</code>, providing
+a simple example of how to use this facility.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Extra-Dimensional Processes">
+
+<h2>Extra-Dimensional Processes</h2>
+
+Scenarios with extra dimensions allow a multitude of processes.
+Currently the only ones implemented involve the production of an
+excited graviton state <ei>G^*</ei> within a Randall-Sundrum scenario.
+This state is assigned PDG code 5000039. Decays into fermion, gluon
+and photon pairs are handled with the correct angular distributions,
+while other decay channels currently are handled isotropically.
+
+<h3>Production processes</h3>
+
+There are two lowest-order processes that together normally should be
+sufficient for a simulation of <ei>G^*</ei> production.
+
+<flag name="ExtraDimensionsG*:all" default="off">
+Common switch for the group of lowest-order <ei>G^*</ei> production
+processes, i.e. the two ones below.
+</flag>
+
+<flag name="ExtraDimensionsG*:gg2G*" default="off">
+Scatterings <ei>g g -> G^*</ei>.
+Code 5001.
+</flag>
+
+<flag name="ExtraDimensionsG*:ffbar2G*" default="off">
+Scatterings <ei>f fbar -> G^*</ei>.
+Code 5002.
+</flag>
+
+<p/>
+In addition there are three first-order processes included. These are of
+less interest, but can be used for dedicated studies of the high-<ei>pT</ei>
+tail of <ei>G^*</ei> producton. As usual, it would be doublecounting to
+include the lowest-order and first-order processes simultaneously.
+Therefore the latter ones are not included with the
+<code>ExtraDimensionsG*:all = on</code> option. In this set of processes
+all decay angles are assumed istropic.
+
+<flag name="ExtraDimensionsG*:gg2G*g" default="off">
+Scatterings <ei>g g -> G^* g</ei>.
+Code 5003.
+</flag>
+
+<flag name="ExtraDimensionsG*:qg2G*q" default="off">
+Scatterings <ei>q g -> G^* q</ei>.
+Code 5004.
+</flag>
+
+<flag name="ExtraDimensionsG*:qqbar2G*g" default="off">
+Scatterings <ei>q qbar -> G^* g</ei>.
+Code 5005.
+</flag>
+
+
+<h3>Parameters</h3>
+
+In the above scenario the main free parameter is the <ei>G^*</ei> mass,
+which is set as usual. In addition there is one further parameter.
+
+<parm name="ExtraDimensionsG*:kappaMG" default="0.054" min="0.0">
+dimensionless coupling, which enters quadratically in all partial
+widths of the <ei>G^*</ei>. Is
+<ei>kappa m_G* = sqrt(2) x_1 k / Mbar_Pl</ei>,
+where <ei>x_1 = 3.83</ei> is the first zero of the <ei>J_1</ei> Bessel
+function and <ei>Mbar_Pl</ei> is the modified Planck mass.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Flavour Selection">
+
+<h2>Flavour Selection</h2>
+
+The <code>StringFlav</code> class handles the choice of a new flavour
+in the fragmentation process, and the production of a new hadron
+from a set of input flavours. It is mainly used by the string
+fragmentation machinery (including ministrings), but also e.g.
+in some particle decays and for some beam-remnant cases. The basic
+concepts are in agreement with <ref>And83</ref>. The baryon-sector
+implementation is based on the <code>MSTJ(12)=3</code> option of
+PYTHIA 6, i.e. new SU(6) weights scheme with at most one popcorn meson.
+
+<p/>
+The relative production rates of different particle species is
+influenced by the parameters below. Some have only an impact on
+one specific quantity, but most directly or indirectly have
+consequences for many observables. Therefore the values to use have
+to be viewed in the context of a complete <aloc href="Tunes">tune</aloc>.
+
+<h3>New flavours</h3>
+
+The main parameters of the selection of a new flavour are
+
+<parm name="StringFlav:probStoUD" default="0.30" min="0.0" max="1.0">
+the suppression of <ei>s</ei> quark production relative to ordinary
+<ei>u</ei> or <ei>d</ei> one.
+</parm>
+
+<parm name="StringFlav:probQQtoQ" default="0.10" min="0.0" max="1.0">
+the suppression of diquark production relative to quark production,
+i.e. of baryon relative to meson production.
+</parm>
+
+<parm name="StringFlav:probSQtoQQ" default="0.4" min="0.0" max="1.0">
+the suppression of strange diquark production relative to light
+diquark production, over and above the one already given by
+<code>probStoU</code>.
+</parm>
+
+<parm name="StringFlav:probQQ1toQQ0" default="0.05" min="0.0" max="1.0">
+the suppression of spin 1 diquark production relative to spin 0 one,
+apart from the factor of 3 enhancement of spin 0 from counting the
+number of states.
+</parm>
+
+<h3>Standard-meson production</h3>
+
+The bulk of the particle production corresponds to the lowest-lying
+pseudoscalar and vector multiplets. Their production rates are
+determined by the parameters in this section.
+
+<p/>
+For a given set of flavours, produced according to the probabilities
+outlined above, the ratio of vector-to-pseudocalar meson production
+is described by the parameters below.
+The maximum allowed rate for each case has been set according to
+spin-counting rules, but we expect the real rates to be lower,
+especially for lighter mesons, owing to the vector-pseudoscalar
+mass splitting.
+
+<parm name="StringFlav:mesonUDvector" default="1.0" min="0." max="3.">
+the relative production ratio vector/pseudoscalar for light
+(<ei>u</ei>, <ei>d</ei>) mesons.
+</parm>
+<parm name="StringFlav:mesonSvector" default="1.5" min="0." max="3.">
+the relative production ratio vector/pseudoscalar for strange mesons.
+</parm>
+<parm name="StringFlav:mesonCvector" default="2.5" min="0." max="3.">
+the relative production ratio vector/pseudoscalar for charm mesons.
+</parm>
+<parm name="StringFlav:mesonBvector" default="3.0" min="0." max="3.">
+the relative production ratio vector/pseudoscalar for bottom mesons.
+</parm>
+
+<p/>
+Inside each light-quark meson nonet, an octet-singlet mixing angle
+describes the mixing of the two flavour-diagonal isoscalar = 0 states.
+(For terminology and details see <ref>Yao06</ref>, chapter 14 on the
+quark model.)
+This angle is needed to specify the probability for such a <ei>q qbar</ei>
+state to project onto a specific meson. More transparent formuale are
+obtained by introducing the angle <ei>alpha = theta + 54.7</ei> degrees:
+<eq>
+ f = (uubar + ddbar)/sqrt(2) * sin(alpha) + ssbar * cos(alpha)<br/>
+ f' = (uubar + ddbar)/sqrt(2) * cos(alpha) - ssbar * sin(alpha)
+</eq>
+
+<parm name="StringFlav:thetaPS" default="-15." min="-90." max="90.">
+gives the mixing angle <ei>theta_PS</ei> in the pseudoscalar meson sector
+(which is rather poorly determined), expressed in degrees.
+Here <ei>f</ei> is associated with <ei>eta'</ei> and <ei>f'</ei> with
+<ei>eta</ei>. (This standard but counterintuitive choice is fixed up
+in the code by replacing <ei>alpha -> 90^0 - alpha</ei> so that
+<ei>eta <-> eta'</ei>; relative signs do not matter since we are
+interested in probabilities only.)
+</parm>
+
+<parm name="StringFlav:thetaV" default="36." min="-90." max="90.">
+gives the mixing angle <ei>theta_V</ei> in the vector meson sector
+(which is somewhat better determined), expressed in degrees.
+Here <ei>f</ei> is associated with <ei>omega</ei> and <ei>f'</ei>
+with <ei>phi</ei>.
+</parm>
+
+<p/>
+Further, the simple model overestimates the production of <ei>eta</ei>
+and, in particular, <ei>eta'</ei> mesons, which can be rectified by
+
+<parm name="StringFlav:etaSup" default="1.0" min="0." max="1.">
+the additional suppression of <ei>eta</ei> production, multiplying the
+normal production probability. Thus 0 means no <ei>eta</ei> at all
+are produced, while 1 means full rate.
+</parm>
+
+<parm name="StringFlav:etaPrimeSup" default="0.4" min="0." max="1.">
+the additional suppression of <ei>eta'</ei> production, multiplying the
+normal production probability. Thus 0 means no <ei>eta'</ei> at all
+are produced, while 1 means full rate.
+</parm>
+
+<h3>Excited-meson production</h3>
+
+Several excited mesons, ie. with radial or orbital excitations, have been
+observed at non-negligible production rates. Extrapolated to all states
+a fair fraction of all particle production might proceed through such
+states. There are big uncertainties, however, since these excited
+mesons in many cases are extremely poorly known. This also means that
+the modelling of their production and decay is very primitive, and
+even that the inclusion of the production of such states may lead to a
+degraded agreement with data. Currently the default is that all such
+production is switched off.
+
+<p/>
+Parameters are provided to switch them on. By demand, this machinery
+has been made more flexible than in the past. Therefore one parameter is
+provided for each combination of heaviest flavour
+(<ei>u/d</ei>, <ei>s</ei>, <ei>c</ei> or <ei>b</ei>) and
+multiplet produced. In each case the production rate is normalized to
+that of the lowest-lying pseudoscalar of the same flavour content, as for
+the vector-meson rates introduced above. The multiplets available are the
+four obtained for one unit of orbital angular momentum, in the
+nonrelativistic classification. Using <ei>J</ei> to denote the sum of
+quark spin <ei>S</ei> and orbital angular momentum <ei>L</ei>, i.e. what
+would normally be called the spin of the meson, one has:
+<ul>
+<li>a pseudovector multiplet with <ei>L=1, S=0, J=1</ei>;</li>
+<li>a scalar multiplet with <ei>L=1, S=1, J=0</ei>;</li>
+<li>a pseudovector multiplet with <ei>L=1, S=1, J=1</ei>;</li>
+<li>a tensor multiplet with <ei>L=1, S=1, J=2</ei>.</li>
+</ul>
+
+The maximum allowed rate for each case has been set according to
+spin-counting rules, but we expect the real rates to be significantly
+lower, owing to mass suppression.
+
+<parm name="StringFlav:mesonUDL1S0J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=0,J=1)</ei>/pseudoscalar
+for light (<ei>u</ei>, <ei>d</ei>) mesons.
+</parm>
+
+<parm name="StringFlav:mesonUDL1S1J0" default="0.0" min="0." max="1.">
+the relative scalar production ratio
+<ei>(L=1,S=1,J=0)</ei>/pseudoscalar
+for light (<ei>u</ei>, <ei>d</ei>) mesons.
+</parm>
+
+<parm name="StringFlav:mesonUDL1S1J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=1,J=1)</ei>/pseudoscalar
+for light (<ei>u</ei>, <ei>d</ei>) mesons.
+</parm>
+
+<parm name="StringFlav:mesonUDL1S1J2" default="0.0" min="0." max="5.">
+the relative tensor production ratio
+<ei>(L=1,S=1,J=2)</ei>/pseudoscalar
+for light (<ei>u</ei>, <ei>d</ei>) mesons.
+</parm>
+
+<parm name="StringFlav:mesonSL1S0J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=0,J=1)</ei>/pseudoscalar
+for strange mesons.
+</parm>
+
+<parm name="StringFlav:mesonSL1S1J0" default="0.0" min="0." max="1.">
+the relative scalar production ratio
+<ei>(L=1,S=1,J=0)</ei>/pseudoscalar
+for strange mesons.
+</parm>
+
+<parm name="StringFlav:mesonSL1S1J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=1,J=1)</ei>/pseudoscalar
+for strange mesons.
+</parm>
+
+<parm name="StringFlav:mesonSL1S1J2" default="0.0" min="0." max="5.">
+the relative tensor production ratio
+<ei>(L=1,S=1,J=2)</ei>/pseudoscalar
+for strange mesons.
+</parm>
+
+<parm name="StringFlav:mesonCL1S0J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=0,J=1)</ei>/pseudoscalar
+for charm mesons.
+</parm>
+
+<parm name="StringFlav:mesonCL1S1J0" default="0.0" min="0." max="1.">
+the relative scalar production ratio
+<ei>(L=1,S=1,J=0)</ei>/pseudoscalar
+for charm mesons.
+</parm>
+
+<parm name="StringFlav:mesonCL1S1J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=1,J=1)</ei>/pseudoscalar
+for charm mesons.
+</parm>
+
+<parm name="StringFlav:mesonCL1S1J2" default="0.0" min="0." max="5.">
+the relative tensor production ratio
+<ei>(L=1,S=1,J=2)</ei>/pseudoscalar
+for charm mesons.
+</parm>
+
+<parm name="StringFlav:mesonBL1S0J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=0,J=1)</ei>/pseudoscalar
+for bottom mesons.
+</parm>
+
+<parm name="StringFlav:mesonBL1S1J0" default="0.0" min="0." max="1.">
+the relative scalar production ratio
+<ei>(L=1,S=1,J=0)</ei>/pseudoscalar
+for bottom mesons.
+</parm>
+
+<parm name="StringFlav:mesonBL1S1J1" default="0.0" min="0." max="3.">
+the relative pseudovector production ratio
+<ei>(L=1,S=1,J=1)</ei>/pseudoscalar
+for bottom mesons.
+</parm>
+
+<parm name="StringFlav:mesonBL1S1J2" default="0.0" min="0." max="5.">
+the relative tensor production ratio
+<ei>(L=1,S=1,J=2)</ei>/pseudoscalar
+for bottom mesons.
+</parm>
+
+<p/>
+In addition, an octet-singlet mixing angle is needed for each multiplet,
+as for the pseudoscalar and vector multiplets above. Only for the
+tensor multiplet does any determination exist; for the other multiplets
+default has been chose so that <ei>ssbar</ei> does not mix with the light
+quarks, and so that the <ei>ssbar</ei> state is the heavier of the two.
+
+<parm name="StringFlav:thetaL1S0J1" default="35.3" min="-90." max="90.">
+gives the mixing angle <ei>theta</ei> in the <ei>(L=1,S=0,J=1)</ei>
+pseudovector meson sector, expressed in degrees.
+</parm>
+
+<parm name="StringFlav:thetaL1S1J0" default="35.3" min="-90." max="90.">
+gives the mixing angle <ei>theta</ei> in the <ei>(L=1,S=1,J=0)</ei>
+scalar meson sector, expressed in degrees.
+</parm>
+
+<parm name="StringFlav:thetaL1S1J1" default="35.3" min="-90." max="90.">
+gives the mixing angle <ei>theta</ei> in the <ei>(L=1,S=1,J=1)</ei>
+pseudovector meson sector, expressed in degrees.
+</parm>
+
+<parm name="StringFlav:thetaL1S1J2" default="28.0" min="-90." max="90.">
+gives the mixing angle <ei>theta</ei> in the <ei>(L=1,S=1,J=2)</ei>
+tensor meson sector, expressed in degrees.
+</parm>
+
+<h3>Baryon production</h3>
+
+The relative rate of baryon production is mainly given by the quark
+and diquark production parameters above, plus SU(6) Clebsch-Gordans.
+The one modifiable parameter related to these coefficients is
+
+<parm name="StringFlav:decupletSup" default="1.0" min="0.0" max="1.0">
+the suppression, relative to default SU(6) factors, of decuplet
+baryon production. Default corresponds to no suppression, while 0
+corresponds to no decuplet production at all.
+</parm>
+
+<p/>
+In addition, if popcorn production is allowed, wherein a set of mesons
+(<ei>M</ei>) may be producted in between the baryon (<ei>B</ei>) and
+the antibaryon (<ei>Bbar</ei>), a set of further parameters is introduced.
+Currently only the simplest scenario is implemented, wherein at most
+one intermediate meson may be produced.
+
+<parm name="StringFlav:popcornRate" default="0.5" min="0." max="2.0">
+gives the relative rates of <ei>B Bbar</ei> and <ei>B M Bbar</ei>
+production, roughly as
+<eq>
+Prob(B M Bbar) / (Prob(B Bbar) + Prob(B M Bbar)) =
+popcornRate / (0.5 + popcornRate)
+</eq>
+(the complete expression depends on all the quark and diquark production
+parameters and is therefore not so useful).
+</parm>
+
+<parm name="StringFlav:popcornSpair" default="0.5" min="0." max="1.0">
+extra suppression for having an <ei>s sbar</ei> pair shared between
+the <ei>B</ei> and <ei>Bbar</ei> in a <ei>B M Bbar</ei> configuration.
+</parm>
+
+<parm name="StringFlav:popcornSmeson" default="0.5" min="0." max="1.0">
+extra suppression for having a strange meson <ei>M</ei> in a
+<ei>B M Bbar</ei> configuration.
+</parm>
+
+<p/>
+Finally, there are some indications that leading-baryon production
+may be further suppressed. A proper description should probably be
+based on a suppression of early production times <ref>Ede97</ref>,
+but we here only implement a simpler version where production near
+the end of a string, as defined by rank, is suppressed. The more
+detailed studies suggest that leading <ei>c</ei> and <ei>b</ei> baryon
+production will be less suppressed, so we leave it open to set
+light- and heavy-baryon suppression separately.
+
+<flag name="StringFlav:suppressLeadingB" default="off">
+Suppress leading-baryon production.
+<option value="off">No suppression.</option>
+<option value="on">Suppress the production of a diquark in the string
+breaking closest to a quark end of a string, by either of the factors
+below. This suppresses the production of first-rank baryons by the same
+amount. Indirectly also the second-rank and, if popcorn production is
+switched on, third-rank (anti)baryon production is affected. </option>
+</flag>
+
+<parm name="StringFlav:lightLeadingBSup" default="0.5" min="0." max="1.0">
+extra suppression of leading-baryon production for a light-quark
+jet, i.e. <ei>d</ei>, <ei>u</ei> or <ei>s</ei>, when
+<code>suppressLeadingB = on</code>. Thus 0 means no leading-baryon
+production at all, while 1 means full rate.
+</parm>
+
+<parm name="StringFlav:heavyLeadingBSup" default="0.9" min="0." max="1.0">
+extra suppression of leading-baryon production for a heavy-quark
+jet, i.e. <ei>c</ei> or <ei>b</ei>, when
+<code>suppressLeadingB = on</code>. Thus 0 means no leading-baryon
+production at all, while 1 means full rate.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Four-Vectors">
+
+<h2>Four-Vectors</h2>
+
+The <code>Vec4</code> class gives an implementation of four-vectors.
+The member function names are based on the assumption that these
+represent momentum vectors. Thus one can get or set
+<code>px()</code>, <code>py()</code>, <code>pz()</code> and
+<code>e()</code>, but not <ei>x, y, z</ei> or <ei>t</ei>. (When
+production vertices are defined in the particle class, this is
+partly circumvented by new methods that hide a <code>Vec4</code>.)
+All four values can be set in the constructor, or later by the
+<code>p</code> method, with input in the order
+<code>(px, py, pz, e)</code>.
+
+<p/>
+The <code>Particle</code> object contains a <code>Vec4 p</code> that
+stores the particle four-momentum, and another <code>Vec4 vProd</code>
+for the production vertex. Therefore a user would not normally access the
+<code>Vec4</code> class directly, but by using the similarly-named methods
+of the <code>Particle</code> class, see
+<aloc href="ParticleProperties">Particle Properties</aloc>.
+(The latter also stores the particle mass separately, offering an element
+of redundancy, helpful in avoiding some roundoff errors.)
+However, you may find some knowledge of the four-vectors
+convenient, e.g. as part of some simple analysis code based
+directly on the PYTHIA output, say to define the four-vector sum
+of a set of particles.
+
+<p/>
+A set of overloaded operators are defined for four-vectors, so that
+one may naturally add, subtract, multiply or divide four-vectors with
+each other or with double numbers, for all the cases that are
+meaningful. Of course the equal sign also works as expected.
+The << operator is overloaded to write out the values of the
+four components of a <code>Vec4</code>.
+
+<p/>
+A number of methods provides output of derived quantities, such as:
+<ul>
+<li><code>mCalc(), m2Calc()</code> the (squared) mass, calculated from
+the four-vectors. If <ei>m^2 < 0</ei> the mass is given with a
+minus sign, <ei>-sqrt(-m^2)</ei>.
+<li><code>pT(), pT2()</code> the (squared) transverse momentum.</li>
+<li><code>pAbs(), pAbs2()</code> the (squared) absolute momentum.</li>
+<li><code>theta()</code> the polar angle, in the range 0 through
+<ei>pi</ei>.</li>
+<li><code>phi()</code> the azimuthal angle, in the range <ei>-pi</ei>
+through <ei>pi</ei>.</li>
+<li><code>thetaXZ()</code> the angle in the <ei>xz</ei> plane, in the
+range <ei>-pi</ei> through <ei>pi</ei>, with 0 along the <ei>+z</ei>
+axis.</li>
+<li><code>pPlus(), pMinus()</code> the combinations <ei>E+-p_z</ei>.</li>
+</ul>
+
+<p/>
+There are also some <code>friend</code> methods that take two or three
+four-vectors as argument:
+<ul>
+<li><code>m(Vec4&, Vec4&), m2(Vec4&, Vec4&)</code> the (squared)
+invariant mass.</li>
+<li><code>dot3(Vec4&, Vec4&)</code> the three-product. </li>
+<li><code>cross3(Vec4&, Vec4&)</code> the cross-product.</li>
+<li><code>theta(Vec4&, Vec4&), costheta(Vec4&, Vec4&)</code> the
+(cosine) of the opening angle between the vectors.</li>
+<li><code>phi(Vec4&, Vec4&), cosphi(Vec4&, Vec4&)</code> the
+(cosine) of the azimuthal angle between the vectors around the
+<ei>z</ei> axis, in the range 0 through <ei>pi</ei>.</li>
+<li><code>phi(Vec4&, Vec4&, Vec4&), cosphi(Vec4&, Vec4&, Vec4&)</code>
+the (cosine) of the azimuthal angle between the first two vectors
+around the direction of the third, in the range 0 through <ei>pi</ei>.</li>
+</ul>
+
+<p/>
+Some member functions can be used to modify vectors, including some
+for rotations and boosts:
+<ul>
+<li><code>rescale3(factor), rescale4(factor)</code> multiply the
+three-vector or all components by this factor.</li>
+<li><code>flip3(), flip4()</code> flip the sign of the
+three-vector or all components.</li>
+<li><code>rot(theta, phi)</code> rotate by this polar and azimuthal
+angle.</li>
+<li><code>rotaxis(phi, nx, ny, nz), rotaxis(phi, n)</code> rotate
+by this azimuthal angle around the axis provided either by the
+three-vector <code>(nx, ny, nz)</code> or the four-vector
+<code>n</code>.</li>
+<li><code>bst(betaX, betaY, betaZ), bst(betaX, betaY, betaZ, gamma)</code>
+boost the particle by this <ei>beta</ei> vector. Sometimes it may be
+convenient also to provide the <ei>gamma</ei> value, especially for large
+boosts where numerical accuracy may suffer.</li>
+<li><code>bst(Vec4&), bstback(Vec4&)</code> boost with a
+<ei>beta = p/E</ei> or <ei>beta = -p/E</ei>, respectively.
+</ul>
+
+<p/>
+For a longer sequence of rotations and boosts, and where several
+<code>Vec4</code> are to be rotated and boosted in the same way,
+a more efficient approach is to define a <code>RotBstMatrix</code>,
+which forms a separate auxiliary class. You can build up this matrix
+by successive calls to the methods
+<ul>
+<li><code>rot(theta, phi)</code> rotate by this polar and azimuthal
+angle.</li>
+<li><code>rot(Vec4& p)</code> rotate so that a vector originally along
+the <ei>+z</ei> axis becomes parallel with <ei>p</ei>. More specifically,
+rotate by <ei>-phi</ei>, <ei>theta</ei> and <ei>phi</ei>, with angles
+defined by <ei>p</ei>.</li>
+<li><code>bst(betaX, betaY, betaZ)</code> boost the particle by this
+<ei>beta</ei> vector.</li>
+<li><code>bst(Vec4&), bstback(Vec4&)</code> boost with a
+<ei>beta = p/E</ei> or <ei>beta = -p/E</ei>, respectively. </li>
+<li><code>bst(Vec4& p1, Vec4& p2)</code> boost so that <ei>p_1</ei>
+is transformed to <ei>p_2</ei>. It is assumed that the two vectors
+obey <ei>p_1^2 = p_2^2</ei>.</li>
+<li><code>toCMframe(Vec4& p1, Vec4& p2)</code> boost and rotate to the
+rest frame of <ei>p_1</ei> and <ei>p_2</ei>, with <ei>p_1</ei> along
+the <ei>+z</ei> axis.</li>
+<li><code>fromCMframe(Vec4& p1, Vec4& p2)</code> rotate and boost from the
+rest frame of <ei>p_1</ei> and <ei>p_2</ei>, with <ei>p_1</ei> along
+the <ei>+z</ei> axis, to the actual frame of <ei>p_1</ei> and <ei>p_2</ei>,
+i.e. the inverse of the above.</li>
+<li><code>rotbst(RotBstMatrix&)</code> combine an existing matrix with
+another one.</li>
+<li><code>invert()</code> invert the matrix, which corresponds to an
+opposite sequence and sign of rotations and boosts.</li>
+<li><code>reset()</code> reset to no rotation/boost; default at
+creation.</li>
+</ul>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Fourth-Generation Processes">
+
+<h2>Fourth-Generation Processes</h2>
+
+A fourth generation could have been accommodated within the
+Standard Model, without the introduction of any new concepts.
+Given the experimental constraints, however, its existence by now
+is very unlikely. Nevertheless we offer a simple implementation,
+along the lines of the top, since it could be useful also as a
+template for studies of other new particles with similar
+characteristics.
+
+<p/>
+The fourth generation are given names as in the third, but with a prime,
+i.e. <ei>b'</ei> with PDG code 7, <ei>t'</ei> with code 8,
+<ei>tau'</ei> with code 17, and <ei>nu'_tau</ei> with code 18.
+Most important for you is to assign a mass hierarchy, to decide which
+fermions can decay into which. The current implementation assumes that
+mass splittings are big enough that fourth-generation fermions can
+decay to third-generation ones by the emission of an on-shell <ei>W</ei>.
+To this end, the standard three-generation CKM mixing matrix has been
+extended to include a fourth generation, see below. Since no mixing has
+been implemented in the neutrino sector it would be assumed that the
+lighter of <ei>tau'</ei> and <ei>nu'_tau</ei> is stable. No decay modes
+have been implemented that go beyond the Standard Model, so
+modifications would be needed if e.g. also SUSY is included in the game.
+
+<h3>Production processes</h3>
+
+<h4>1) <ei>b'</ei> processes</h4>
+
+Different ways to produce <ei>b'</ei> quarks, singly or in pairs.
+For a <ei>b' t'</ei> pair see section 3 below.
+
+<flag name="FourthBottom:all" default="off">
+Common switch for the group of <ei>b'</ei> production.
+Also includes the process <ei>f fbar' -> t' b'bar</ei> in section 3 below.
+</flag>
+
+<flag name="FourthBottom:gg2bPrimebPrimebar" default="off">
+Scatterings <ei>g g -> b' b'bar</ei>.
+Code 801.
+</flag>
+
+<flag name="FourthBottom:qqbar2bPrimebPrimebar" default="off">
+Scatterings <ei>q qbar -> b' b'bar</ei> by gluon exchange.
+Code 802.
+</flag>
+
+<flag name="FourthBottom:qq2bPrimeq(t:W)" default="off">
+Scatterings <ei>q q' -> b' q''</ei> by <ei>t</ei>-channel exchange
+of a <ei>W^+-</ei> boson.
+Code 803.
+</flag>
+
+<flag name="FourthBottom:ffbar2bPrimebPrimebar(s:gmZ)" default="off">
+Scatterings <ei>f fbar -> b' b'bar</ei> by <ei>s</ei>-channel exchange
+of a <ei>gamma^*/Z^0</ei> boson.
+Code 804.
+</flag>
+
+<flag name="FourthBottom:ffbar2bPrimeqbar(s:W)" default="off">
+Scatterings <ei>f fbar' -> b' qbar''</ei> by <ei>s</ei>-channel exchange
+of a <ei>W^+-</ei> boson. Here <ei>q''</ei> is either <ei>u</ei> or
+<ei>c</ei>.
+Code 805.
+</flag>
+
+<flag name="FourthBottom:ffbar2bPrimetbar(s:W)" default="off">
+Scatterings <ei>f fbar' -> b' tbar</ei> by <ei>s</ei>-channel exchange
+of a <ei>W^+-</ei> boson.
+Code 806.
+</flag>
+
+<h4>2) <ei>t'</ei> processes</h4>
+
+Different ways to produce <ei>t'</ei> quarks, singly or in pairs.
+For a <ei>b' t'</ei> pair see section 3 below.
+
+<flag name="FourthTop:all" default="off">
+Common switch for the group of <ei>t'</ei> production.
+Also includes the process <ei>f fbar' -> t' b'bar</ei> in section 3 below.
+</flag>
+
+<flag name="FourthTop:gg2tPrimetPrimebar" default="off">
+Scatterings <ei>g g -> t' t'bar</ei>.
+Code 821.
+</flag>
+
+<flag name="FourthTop:qqbar2tPrimetPrimebar" default="off">
+Scatterings <ei>q qbar -> t' t'bar</ei> by gluon exchange.
+Code 822.
+</flag>
+
+<flag name="FourthTop:qq2tPrimeq(t:W)" default="off">
+Scatterings <ei>q q' -> t' q''</ei> by <ei>t</ei>-channel exchange
+of a <ei>W^+-</ei> boson.
+Code 823.
+</flag>
+
+<flag name="FourthTop:ffbar2tPrimetPrimebar(s:gmZ)" default="off">
+Scatterings <ei>f fbar -> t' t'bar</ei> by <ei>s</ei>-channel exchange
+of a <ei>gamma^*/Z^0</ei> boson.
+Code 824.
+</flag>
+
+<flag name="FourthTop:ffbar2tPrimeqbar(s:W)" default="off">
+Scatterings <ei>f fbar' -> t' qbar''</ei> by <ei>s</ei>-channel exchange
+of a <ei>W^+-</ei> boson.
+Code 825.
+</flag>
+
+<h4>3) Pair-processes with different flavours</h4>
+
+Different ways to produce two different fourth-generation fermions.
+
+<flag name="FourthPair:ffbar2tPrimebPrimebar(s:W)" default="off">
+Scatterings <ei>f fbar' -> t' b'bar</ei> by <ei>s</ei>-channel exchange
+of a <ei>W^+-</ei> boson.
+Code 841.
+</flag>
+
+<flag name="FourthPair:ffbar2tauPrimenuPrimebar(s:W)" default="off">
+Scatterings <ei>f fbar' -> tau' nu'_taubar</ei> by <ei>s</ei>-channel
+exchange of a <ei>W^+-</ei> boson.
+Code 842.
+</flag>
+
+<p/>
+Missing in this list is scatterings <ei>q q' -> t' b'</ei> by
+<ei>t</ei>-channel exchange of a <ei>W^+-</ei> boson, since currently
+the matrix element for such processes have not been implemented for
+two massive particles in the final state. Since this process would
+involve two CKM-suppressed vertices it ought to be small.
+
+<h3>Parameters</h3>
+
+The Cabibbo-Kobayashi-Maskawa matrix is extended by seven further values.
+So as not to mess up the Standard Model, the normal 3 * 3 matrix is
+kept unitary, and so the new off-diagonal elements lead to a slight
+breaking of this. For exploratory studies this should be good enough;
+more detailed 4 * 4 tunes to data would only make sense the day there
+are evidence for the existence of a fourth generation.
+
+<parm name="FourthGeneration:VubPrime" default="0.001" min="0.0" max="1.0">
+The <ei>V_ub'</ei> matrix element in the 4 * 4 CKM matrix.
+</parm>
+
+<parm name="FourthGeneration:VcbPrime" default="0.01" min="0.0" max="1.0">
+The <ei>V_cb'</ei> matrix element in the 4 * 4 CKM matrix.
+</parm>
+
+<parm name="FourthGeneration:VtbPrime" default="0.1" min="0.0" max="1.0">
+The <ei>V_tb'</ei> matrix element in the 4 * 4 CKM matrix.
+</parm>
+
+<parm name="FourthGeneration:VtPrimed" default="0.001" min="0.0" max="1.0">
+The <ei>V_t'd</ei> matrix element in the 4 * 4 CKM matrix.
+</parm>
+
+<parm name="FourthGeneration:VtPrimes" default="0.01" min="0.0" max="1.0">
+The <ei>V_t's</ei> matrix element in the 4 * 4 CKM matrix.
+</parm>
+
+<parm name="FourthGeneration:VtPrimeb" default="0.1" min="0.0" max="1.0">
+The <ei>V_t'b</ei> matrix element in the 4 * 4 CKM matrix.
+</parm>
+
+<parm name="FourthGeneration:VtPrimebPrime" default="0.99" min="0.0" max="1.0">
+The <ei>V_t'b'</ei> matrix element in the 4 * 4 CKM matrix.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Fragmentation">
+
+<h2>Fragmentation</h2>
+
+Fragmentation in PYTHIA is based on the Lund string model
+<ref>And83, Sjo84</ref>. Several different aspects are involved in
+the physics description, which here therefore is split accordingly.
+This also, at least partly, reflect the set of classes involved in
+the fragmentation machinery.
+
+<p/>
+The variables collected here have a very wide span of usefulness.
+Some would be central in any hadronization tuning exercise, others
+should not be touched except by experts.
+
+<p/>
+The fragmentation flavour-choice machinery is also used in a few
+other places of the program, notably particle decays, and is thus
+described on the separate <aloc href="FlavourSelection">Flavour
+Selection</aloc> page.
+
+<h3>Fragmentation functions</h3>
+
+The <code>StringZ</code> class handles the choice of longitudinal
+lightcone fraction <ei>z</ei> according to one of two possible
+shape sets.
+
+<p/>
+The Lund symmetric fragmentation function <ref>And83</ref> is the
+only alternative for light quarks. It is of the form
+<eq>
+ f(z) = (1/z) * (1-z)^a * exp(-b m_T^2 / z)
+</eq>
+with the two main free parameters <ei>a</ei> and <ei>b</ei> to be
+tuned to data. They are stored in
+
+<parm name="StringZ:aLund" default="0.3" min="0.0" max="2.0">
+The <ei>a</ei> parameter of the Lund symmetric fragmentation function.
+</parm>
+
+<parm name="StringZ:bLund" default="0.58" min="0.2" max="2.0">
+The <ei>b</ei> parameter of the Lund symmetric fragmentation function.
+</parm>
+
+<p/>
+In principle, each flavour can have a different <ei>a</ei>. Then,
+for going from an old flavour <ei>i</ei> to a new <ei>j</ei> one
+the shape is
+<eq>
+ f(z) = (1/z) * z^{a_i} * ((1-z)/z)^{a_j} * exp(-b * m_T^2 / z)
+</eq>
+This is only implemented for diquarks relative to normal quarks:
+
+<parm name="StringZ:aExtraDiquark" default="0.5" min="0.0" max="2.0">
+allows a larger <ei>a</ei> for diquarks, with total
+<ei>a = aLund + aExtraDiquark</ei>.
+</parm>
+
+<p/>
+Finally, the Bowler modification <ref>Bow81</ref> introduces an extra
+factor
+<eq>
+ 1/z^{r_Q * b * m_Q^2}
+</eq>
+for heavy quarks. To keep some flexibility, a multiplicative factor
+<ei>r_Q</ei> is introduced, which ought to be unity (provided that
+quark masses were uniquely defined) but can be set in
+
+<parm name="StringZ:rFactC" default="1.0" min="0.0" max="2.0">
+<ei>r_c</ei>, i.e. the above parameter for <ei>c</ei> quarks.
+</parm>
+
+<parm name="StringZ:rFactB" default="1.0" min="0.0" max="2.0">
+<ei>r_b</ei>, i.e. the above parameter for <ei>b</ei> quarks.
+</parm>
+
+<parm name="StringZ:rFactH" default="1.0" min="0.0" max="2.0">
+<ei>r_h</ei>, i.e. the above parameter for heavier hypothetical quarks,
+or in general any new coloured particle long-lived enough to hadronize.
+</parm>
+
+<p/>
+As an alternative, it is possible to switch over to the
+Peterson/SLAC formula <ref>Pet83</ref>
+<eq>
+ f(z) = 1 / ( z * (1 - 1/z - epsilon/(1-z))^2 )
+</eq>
+for charm, bottom and heavier (defined as above) by the three flags
+
+<flag name="StringZ:usePetersonC" default="off">
+use Peterson for <ei>c</ei> quarks.
+</flag>
+
+<flag name="StringZ:usePetersonB" default="off">
+use Peterson for <ei>b</ei> quarks.
+</flag>
+
+<flag name="StringZ:usePetersonH" default="off">
+use Peterson for hypothetical heavier quarks.
+</flag>
+
+<p/>
+When switched on, the corresponding epsilon values are chosen to be
+
+<parm name="StringZ:epsilonC" default="0.05" min="0.01" max="0.25">
+<ei>epsilon_c</ei>, i.e. the above parameter for <ei>c</ei> quarks.
+</parm>
+
+<parm name="StringZ:epsilonB" default="0.005" min="0.001" max="0.025">
+<ei>epsilon_b</ei>, i.e. the above parameter for <ei>b</ei> quarks.
+</parm>
+
+<parm name="StringZ:epsilonH" default="0.005" min="0.0001" max="0.25">
+<ei>epsilon_h</ei>, i.e. the above parameter for hypothetical heavier
+quarks, normalized to the case where <ei>m_h = m_b</ei>. The actually
+used parameter is then <ei>epsilon = epsilon_h * (m_b^2 / m_h^2)</ei>.
+This allows a sensible scaling to a particle with an unknown higher
+mass without the need for a user intervention.
+</parm>
+
+<h3>Fragmentation <ei>pT</ei></h3>
+
+The <code>StringPT</code> class handles the choice of fragmentation
+<ei>pT</ei>. At each string breaking the quark and antiquark of the pair are
+supposed to receive opposite and compensating <ei>pT</ei> kicks according
+to a Gaussian distribution in <ei>p_x</ei> and <ei>p_y</ei> separately.
+Call <ei>sigma_q</ei> the width of the <ei>p_x</ei> and <ei>p_y</ei>
+distributions separately, i.e.
+<eq>
+ d(Prob) = exp( -(p_x^2 + p_y^2) / 2 sigma_q^2).
+</eq>
+Then the total squared width is
+<eq>
+ <pT^2> = <p_x^2> + <p_y^2> = 2 sigma_q^2 = sigma^2.
+</eq>
+It is this latter number that is stored in
+
+<parm name="StringPT:sigma" default="0.36" min="0.0" max="1.0">
+the width <ei>sigma</ei> in the fragmentation process.
+</parm>
+
+<p/>
+Since a normal hadron receives <ei>pT</ei> contributions for two string
+breakings, it has a <ei><p_x^2>_had = <p_y^2>_had = sigma^2</ei>,
+and thus <ei><pT^2>_had = 2 sigma^2</ei>.
+
+<p/>
+Some studies on isolated particles at LEP has indicated the need for
+a slightly enhanced rate in the high-<ei>pT</ei> tail of the above
+distribution. This would have to be reviewed in the context of a
+complete retune of parton showers and hadronization, but for the
+moment we stay with the current recipe, to boost the above <ei>pT</ei>
+by a factor <ei>enhancedWidth</ei> for a small fraction
+<ei>enhancedFraction</ei> of the breakups, where
+
+<parm name="StringPT:enhancedFraction" default="0.01" min="0.0" max="0.1">
+<ei>enhancedFraction</ei>,the fraction of string breaks with enhanced
+width.
+</parm>
+
+<parm name="StringPT:enhancedWidth" default="2.0" min="1.0" max="5.0">
+<ei>enhancedWidth</ei>,the enhancement of the width in this fraction.
+</parm>
+
+<h3>Jet joining procedure</h3>
+
+String fragmentation is carried out iteratively from both string ends
+inwards, which means that the two chains of hadrons have to be joined up
+somewhere in the middle of the event. This joining is described by
+parameters that in principle follows from the standard fragmentation
+parameters, but in a way too complicated to parametrize. The dependence
+is rather mild, however, so for a sensible range of variation the
+parameters in this section should not be touched.
+
+<parm name="StringFragmentation:stopMass" default="1.0" min="0.0" max="2.0">
+Is used to define a <ei>W_min = m_q1 + m_q2 + stopMass</ei>,
+where <ei>m_q1</ei> and <ei>m_q2</ei> are the masses of the two
+current endpoint quarks or diquarks.
+</parm>
+
+<parm name="StringFragmentation:stopNewFlav" default="2.0" min="0.0" max="2.0">
+Add to <ei>W_min</ei> an amount <ei>stopNewFlav * m_q_last</ei>,
+where <ei>q_last</ei> is the last <ei>q qbar</ei> pair produced
+between the final two hadrons.
+</parm>
+
+<parm name="StringFragmentation:stopSmear" default="0.2" min="0.0" max="0.5">
+The <ei>W_min</ei> above is then smeared uniformly in the range
+<ei>W_min_smeared = W_min * [ 1 - stopSmear, 1 + stopSmear ]</ei>.
+</parm>
+
+<p/>
+This <ei>W_min_smeared</ei> is then compared with the current remaining
+<ei>W_transverse</ei> to determine if there is energy left for further
+particle production. If not, i.e. if
+<ei>W_transverse < W_min_smeared</ei>, the final two particles are
+produced from what is currently left, if possible. (If not, the
+fragmentation process is started over.)
+
+<h3>Simplifying systems</h3>
+
+There are a few situations when it is meaningful to simplify the
+original task, one way or another.
+
+<parm name="HadronLevel:mStringMin" default="1." min="0.5" max="1.5">
+Decides whether a partonic system should be considered as a normal
+string or a ministring, the latter only producing one or two primary
+hadrons. The system mass should be above <ei>mStringMin</ei> plus the
+sum of quark/diquark constituent masses for a normal string description,
+else the ministring scenario is used.
+</parm>
+
+<parm name="FragmentationSystems:mJoin" default="0.2" min="0.2" max="1.">
+When two colour-connected partons are very nearby, with at least
+one being a gluon, they can be joined into one, to avoid technical
+problems of very small string regions. The requirement for joining is
+that the invariant mass of the pair is below <ei>mJoin</ei>, where a
+gluon only counts with half its momentum, i.e. with its contribution
+to the string region under consideration. (Note that, for technical
+reasons, the 0.2 GeV lower limit is de facto hardcoded.)
+</parm>
+
+<parm name="FragmentationSystems:mJoinJunction" default="1.0"min="0.5" max="2.">
+When the invariant mass of two of the quarks in a three-quark junction
+string system becomes too small, the system is simplified to a
+quark-diquark simple string. The requirement for this simplification
+is that the diquark mass, minus the two quark masses, falls below
+<ei>mJoinJunction</ei>. Gluons on the string between the junction and
+the respective quark, if any, are counted as part of the quark
+four-momentum. Those on the two combined legs are clustered with the
+diquark when it is formed.
+</parm>
+
+<h3>Ministrings</h3>
+
+The <code>MiniStringFragmentation</code> machinery is only used when a
+string system has so small invariant mass that normal string fragmentation
+is difficult/impossible. Instead one or two particles are produced,
+in the former case shuffling energy-momentum relative to another
+colour singlet system in the event, while preserving the invariant
+mass of that system. With one exception parameters are the same as
+defined for normal string fragmentation, to the extent that they are
+at all applicable in this case.
+
+A discussion of the relevant physics is found in <ref>Nor00</ref>.
+The current implementation does not completely abide to the scheme
+presented there, however, but has in part been simplified. (In part
+for greater clarity, in part since the class is not quite finished yet.)
+
+<modeopen name="MiniStringFragmentation:nTry" default="2" min="1" max="10">
+Whenever the machinery is called, first this many attempts are made
+to pick two hadrons that the system fragments to. If the hadrons are
+too massive the attempt will fail, but a new subsequent try could
+involve other flavour and hadrons and thus still succeed.
+After <ei>nTry</ei> attempts, instead an attempt is made to produce a
+single hadron from the system. Should also this fail, some further
+attempts at obtaining two hadrons will be made before eventually
+giving up.
+</modeopen>
+
+<h3>Junction treatment</h3>
+
+A junction topology corresponds to an Y arrangement of strings
+i.e. where three string pieces have to be joined up in a junction.
+Such topologies can arise if several valence quarks are kicked out
+from a proton beam, or in baryon-number-violating SUSY decays.
+Special attention is necessary to handle the region just around
+the junction, where the baryon number topologically is located.
+The junction fragmentation scheme is described in <ref>Sjo03</ref>.
+The parameters in this section should not be touched except by experts.
+
+<parm name="StringFragmentation:eNormJunction" default="2.0" min="0.5" max="10">
+Used to find the effective rest frame of the junction, which is
+complicated when the three string legs may contain additional
+gluons between the junction and the endpoint. To this end,
+a pull is defined as a weighed sum of the momenta on each leg,
+where the weight is <ei>exp(- eSum / eNormJunction)</ei>, with
+<ei>eSum</ei> the summed energy of all partons closer to the junction
+than the currently considered one (in the junction rest frame).
+Should in principle be (close to) <ei>sqrt((1 + a) / b)</ei>, with
+<ei>a</ei> and <ei>b</ei> the parameters of the Lund symmetric
+fragmentation function.
+</parm>
+
+<parm name="StringFragmentation:eBothLeftJunction" default="1.0" min="0.5">
+Retry (up to 10 times) when the first two considered strings in to a
+junction both have a remaining energy (in the junction rest frame)
+above this number.
+</parm>
+
+<parm name="StringFragmentation:eMaxLeftJunction" default="10.0" min="0.">
+Retry (up to 10 times) when the first two considered strings in to a
+junction has a highest remaining energy (in the junction rest frame)
+above a random energy evenly distributed between
+<ei>eBothLeftJunction</ei> and
+<ei>eBothLeftJunction + eMaxLeftJunction</ei>
+(drawn anew for each test).
+</parm>
+
+<parm name="StringFragmentation:eMinLeftJunction" default="0.2" min="0.">
+Retry (up to 10 times) when the invariant mass-squared of the final leg
+and the leftover momentum of the first two treated legs falls below
+<ei>eMinLeftJunction</ei> times the energy of the final leg (in the
+junction rest frame).
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Front">
+
+<h1>PYTHIA 8</h1>
+
+<h2>Welcome to PYTHIA - The Lund Monte Carlo!</h2>
+
+<p/>
+PYTHIA 8 is the successor to PYTHIA 6, rewritten from scratch in C++.
+With the release of PYTHIA 8.1 it now becomes the official "current"
+PYTHIA version, although PYTHIA 6.4 will be supported in parallel
+with it for some time to come. Specifically, the new version has not
+yet been enough tested and tuned for it to have reached the same level
+of reliability as the older one. This testing will only happen if
+people begin to work with the program, however, which is why we
+encourage a gradual transition to the new version, starting now.
+There are some new physics features in PYTHIA 8.1, that would make
+use of it more attractive, but also some topics still missing, where
+6.4 would have to be used. Further, many obsolete features will not
+be carried over, so for some backwards compatibility studies again
+6.4 would be the choice.
+
+<h2>Documentation</h2>
+
+On these webpages you will find the up-to-date manual for PYTHIA 8.1.
+Use the left-hand index to navigate this documentation of program
+elements, especially of all possible program settings. All parameters
+are provided with sensible default values, however, so you need only
+change those of relevance to your particular study, such as choice of
+beams, processes and phase space cuts. The pages also contain a fairly
+extensive overview of all methods available to the user, e.g. to study
+the produced events. What is lacking on these webpages is an overview,
+on the one hand, and an in-depth physics description, on the other.
+
+<p/>
+The overview can be found in the attached PDF file
+<br/><a href="pythia8100.pdf" target="page"><b>A Brief Introduction
+to PYTHIA 8.1</b></a>
+<br/>T. Sjöstrand, S. Mrenna and P. Skands, arXiv:0710.3820,
+to appear in Computer Physics Communications.
+<br/>You are strongly recommended to read this summary when you
+start out to learn how to use PYTHIA 8.1.
+
+<p/>
+For the physics description we refer to the complete
+<br/><b>PYTHIA 6.4 Physics and Manual</b>
+<br/>T. Sjöstrand, S. Mrenna and P. Skands, JHEP05 (2006) 026,
+<br/>which in detail describes the physics (largely) implemented also in
+PYTHIA 8, and also provides a more extensive bibliography than found
+here.
+
+<p/>
+When you use PYTHIA 8.1, you should therefore cite both, e.g. like
+<br/><b>T. Sjöstrand, S. Mrenna and P. Skands, JHEP05 (2006) 026,
+arXiv:0710.3820</b>.
+
+<h2>Program Authors and Licence</h2>
+
+<p/>
+Main author: <b>Torbjörn Sjöstrand</b><br/>
+Department of Theoretical Physics, Lund University,
+SE-223 62 Lund, Sweden<br/>
+phone: + 46 - 46 - 222 48 16, e-mail: torbjorn@thep.lu.se
+
+<p/>
+Author: <b>Stephen Mrenna</b><br/>
+Computing Division, Simulations Group,
+Fermi National Accelerator Laboratory,<br/>
+MS 234, Batavia, IL 60510, USA<br/>
+phone: + 1 - 630 - 840 - 2556, e-mail: mrenna@fnal.gov
+
+<p/>
+Author: <b>Peter Skands</b><br/>
+CERN/PH, CH-1211 Geneva, Switzerland, and<br/>
+Theoretical Physics Department,
+Fermi National Accelerator Laboratory,<br/>
+MS 106, Batavia, IL 60510, USA<br/>
+phone: + 41 - 22 - 767 24 59, e-mail: skands@fnal.gov
+
+<p/>
+Makefiles, configure scripts and HepMC interface by <b>Mikhail Kirsanov</b>.
+<br/>Conversion of XML files to PHP ones by <b>Ben Lloyd</b>.
+<br/>Simple Makefile for Win32/NMAKE by <b>Bertrand Bellenot</b>.
+<br/>Extended Higgs sector partly implemented by <b>Marc Montull</b>.
+<br/>Parts of charm and bottom decay tables courtesy <b>DELPHI</b> and
+<b>LHCb</b> collaborations.
+
+<p/>
+PYTHIA 8 is licensed under the
+<a href="COPYING" target="page"><b>GNU General Public Licence
+version 2</b></a>.
+<br/>Please respect the
+<a href="GUIDELINES" target="page"><b>MCnet Guidelines</b></a>
+for Event Generator Authors and Users.
+
+<p/>
+The program and the documentation is
+Copyright © 2008 Torbjörn Sjöstrand
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Glossary">
+
+<h2>Glossary</h2>
+
+<dl>
+
+<dt>BR</dt>
+<dd>Beam Remnants; not much used since it may be confused with
+Branching Ratio</dd>
+
+<dt>BSM</dt>
+<dd>Beyond-the-Standard-Model physics, as a generic term for anything
+not contained within the SM</dd>
+
+<dt>FSR</dt>
+<dd>Final-State Radiation, implemented in terms of timelike showers</dd>
+
+<dt>LHA</dt>
+<dd>Les Houches Accord for user processes, describing which process-level
+information should be stored to allow further showering and hadronization
+of "skeleton" hard processes</dd>
+
+<dt>LHAPDF</dt>
+<dd>Les Houches Accord Parton Distribution Functions, originally a standard
+format for defining PDF's and later a library with such PDF's</dd>
+
+<dt>LHEF</dt>
+<dd>Les Houches Event File(s), a file format for storing LHA process and
+event information</dd>
+
+<dt>ISR</dt>
+<dd>Initial-State Radiation, implemented in terms of spacelike showers</dd>
+
+<dt>MI</dt>
+<dd>Multiple Interactions, i.e. several (more or less) independent
+parton-parton subcollisions as part of a hadron-hadron event (sometimes
+also called MPI, with P for parton or parton-parton)</dd>
+
+<dt>MSSM</dt>
+<dd>Minimal Supersymmetric extension of the Standard Model</dd>
+
+<dt>PDF</dt>
+<dd>Parton Distribution Function (alternatively Parton Density
+Function)</dd>
+
+<dt>PDG code</dt>
+<dd>a scheme for assigning unique integers, particle identity codes,
+to known and hypothetical particles; code rules and tables are published
+in the RPP (see below).</dd>
+
+<dt>pileup</dt>
+<dd>several hadron-hadron collisions in a bunch crossing; not to
+be confused with MI</dd>
+
+<dt>RPP</dt>
+<dd>Review of Particle Physics, the biannual review by the ParticleData Group
+(PDG) from which many Standard-Model parameter values and much particle data
+has been taken (but, given the poor data on many hadron resonances, a lot of
+extra (guess)work is needed)</dd>
+
+<dt>setting</dt>
+<dd>collectively used to denote all the boolean <code>flag</code>,
+integer <code>mode</code>, double-precision <code>parm</code>
+and string <code>word</code> variables that can be set by the user
+to steer the behaviour of a run; normally particle data are considered
+separately but clearly are closely related</dd>
+
+<dt>SLHA</dt>
+<dd>SUSY Les Houchs Accord for interchange of mass and coupling information
+in SUSY scenarios, via a well-defined file format</dd>
+
+<dt>SM</dt>
+<dd>the Standard Model of particle physics</dd>
+
+<dt>SUSY</dt>
+<dd>SUperSYmmetry</dd>
+
+<dt>units</dt>
+<dd>Normal PYTHIA input, internal operations and output is based on a set of
+standard units, such as:
+<br/>GeV for all energies, momenta and masses, always with <ei>c = 1</ei>;
+<br/>mm for all distances and mm/<ei>c</ei> for all times,
+so that again they match for <ei>c = 1</ei>;
+<br/>mb for all cross sections (but input or output via the Les Houches
+Accord takes into account that the unit there is pb)
+</dd>
+
+</dl>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Hadron-Level Standalone">
+
+<h2>Hadron-Level Standalone</h2>
+
+The Les Houches Accord allows external process-level configurations
+to be fed in, for subsequent parton-level and hadron-level generation
+to be handled internally by PYTHIA. There is no correspondingly
+standardized interface if you have external events that have also
+been generated through the parton-level stage, so that only the
+hadron-level remains to be handled. A non-standard way to achieve this
+exists, however, and can be useful both for real applications and
+for various tests of the hadronization model on its own.
+
+<p/>
+The key trick is to set the flag <code>ProcessLevel:all = off</code>.
+When <code>pythia.next()</code> is called it then does not try to
+generate a hard process, and therefore also cannot do anything on the
+parton level. Instead only the <code>HadronLevel</code> methods are
+called, to take the current content of the event record stored in
+<code>pythia.event</code> as a starting point for any hadronization
+and decays that are allowed by the normal parameters of this step.
+Often the input would consist solely of partons grouped into colour
+singlets, but also (colour-singlet) particles are allowed.
+
+<p/>
+To set up all the parameters, a <code>pythia.init()</code> call has
+to be used, without any arguments. In brief, the structure of the
+main program therefore should be something like
+<pre>
+ Pythia pythia; // Declare generator.
+ Event& event = pythia.event // Convenient shorthand.
+ pythia.readString("ProcessLevel:all = off"); // The trick!
+ pythia.init(); // Initialization.
+ for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
+ // Insert filling of event here!
+ pythia.next(); // Do the hadron level.
+ }
+</pre>
+Of course this should be supplemented by analysis of events, error checks,
+and so on, as for a normal PYTHIA run. The unique aspect is how to fill
+the <code>event</code> inside the loop, before <code>pythia.next()</code>
+is called.
+
+<h3>Input configuration</h3>
+
+To set up a new configuration the first step is to throw away the current
+one, with <code>event.reset()</code>. This routine will also reserve
+the zeroth entry in the even record to represent the event as a whole.
+
+<p/>
+With the <code>event.append(...)</code> methods a new entry is added at the
+bottom of the current record, i.e. the first time it is called entry
+number 1 is filled, and so on. The <code>append</code> method basically
+exists in four variants, either without or with history information,
+and with four-momentum provided either as a <code>Vec4</code> four-vector
+or as four individual components:
+<pre>
+ append( id, status, col, acol, p, m)
+ append( id, status, col, acol, px, py, pz, e, m)
+ append( id, status, mother1, mother2, daughter1, daughter2, col, acol, p, m)
+ append( id, status, mother1, mother2, daughter1, daughter2, col, acol, px, py, pz, e, m)
+</pre>
+The methods return the index at which the entry has been stored,
+but normally you would not use this feature.
+
+<p/>
+You can find descriptions of the input variables
+<aloc href="ParticleProperties">here</aloc>.
+The PDG particle code <code>id</code> and the Les Houches Accord colour
+<code>col</code> and anticolour <code>acol</code> tags must be set
+correctly. The four-momentum and mass have to be provided in units of GeV;
+if you omit the mass it defaults to 0.
+
+<p/>
+The status code can normally be simplified, however; you only need to recall
+that positive numbers correspond to particles that are still around, while
+negative numbers denote ones that already hadronized or decayed, so usually
+<ei>+-1</ei> is good enough. When <code>pythia.next()</code> is called
+those positive-status particles that hadronize/decay get the sign of the
+status code flipped to negative but the absolute value is retained. The
+new particles are added with normal PYTHIA status codes.
+
+<p/>
+For normal hadronization/decays in <code>pythia.next()</code> the
+history encoded in the mother and daughter indices is not used.
+Therefore the first two <code>append</code> methods, which set all these
+indices vanishing, should suffice. The subsequent hadronization/decays
+will still be properly documented.
+
+<p/>
+The exception is when you want to include junctions in your string
+topology, i.e. have three string pieces meet. Then you must insert in
+your event record the (decayed) particle that is the reason for the
+presence of a junction, e.g. a baryon beam remnant from which several
+valence quarks have been kicked out, or a neutralino that underwent a
+baryon-number-violating decay. This particle must have as daughters
+the three partons that together carry the baryon number.
+
+<p/>
+The sample program in <code>main21.cc</code> illustrates how you can work
+with this facility, both for simple parton configurations and for more
+complicated ones with junctions.
+
+<h3>Repeated hadronization or decay</h3>
+
+An alternative approach is possible with the
+<code>pythia.forceHadronLevel()</code> routine. This method does
+a call to the <code>HadronLevel</code> methods, irrespective of the
+value of the <code>HadronLevel:all</code> flag. If you hadronize
+externally generated events it is equivalent to a
+<code>pythia.next()</code> call with
+<code>ProcessLevel:all = off</code>.
+
+<p/>
+The real application instead is for repeated hadronization of the same
+PYTHIA process- and parton-level event. This may for some studies
+help to save time, given that these two first step are more
+time-consuming than the hadronization one.
+
+<p/>
+For repeated hadronization you should first generate an event as usual,
+but with <code>HadronLevel:all = off</code>. This event you can save
+in a temporary copy, e.g. <code>Event savedEvent = pythia.event</code>.
+Inside a loop you copy back with <code>pythia.event = savedEvent</code>,
+and call <code>pythia.forceHadronLevel()</code> to obtain a new
+hadronization history.
+
+<p/>
+A more limited form of repetition is if you want to decay a given kind
+of particle repeatedly, without having to generate the rest of the event
+anew. This could be the case e.g. in <ei>B</ei> physics applications.
+Then you can use the <code>pythia.moreDecays()</code> method, which
+decays all particles in the event record that have not been decayed
+but should have been done so. The
+<code>ParticleDataTable::mayDecay( id, false/true)</code> method
+may be used to switch off/on the decays of a particle species
+<code>id</code>, so that it is not decayed in the
+<code>pythia.next()</code> call but only inside a loop over a number of
+tries.
+
+<p/>
+Between each loop the newly produced decay products must be
+removed and the decayed particle status restored to undecayed.
+The former is simple, since the new products are appended to the
+end of the event record: <code>event.saveSize()</code> saves the
+initial size of the event record, and <code>event.restoreSize()</code>
+can later be used repeatedly to restore this original size, which means
+that the new particles at the end are thrown away. The latter is more
+complicated, and requires the user to identify the positions of all
+particles of the species and restore a positive status code with
+<code>event[i].statusPos()</code>.
+
+<p/>
+The <code>main15.cc</code> program illustrates both these methods,
+i.e. either repeated hadronization or repeated decay of PYTHIA
+events.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="HepMC Interface">
+
+<h2>HepMC Interface</h2>
+
+An interface to the HepMC <ref>Dob01</ref> standard event record
+format has been provided by M. Kirsanov. To use it, the relevant
+libraires need to be linked, as explained in the <code>README</code>
+file. Only version 2 of HepMC is supported. (Version 1 requires
+a different interface structure, which was only supported up until
+Pythia 8.107.)
+
+<p/>
+The (simple) procedure to translate PYTHIA 8 events into HepMC ones
+is illustrated in the <code>main31.cc</code>, <code>main32.cc</code>
+and <code>main54.cc</code> main programs. At the core is a call to
+the
+<pre>
+HepMC::I_Pythia8::fill_next_event( pythia, hepmcevt, ievnum = -1, convertGluonTo0 = false )
+</pre>
+which takes a reference of the generator object and uses it, on the one
+hand, to read out and covert the event record in <code>pythia.event</code>
+and, on the other hand, to extract and store parton-density (PDF)
+information for the hard subprocess from <code>pythia.info</code>.
+The optional last argument, if <code>true</code>, allows you to store
+gluons as "PDG" code 0 rather than the normal 21; this only applies to
+the PDF information, not the event record.
+
+<p/>
+The earlier version of this routine,
+<pre>
+HepMC::I_Pythia8::fill_next_event( pythia.event, hepmcevt, ievnum = -1 )
+</pre>
+is retained (for now) for backwards compatibility. It takes a PYTHIA event
+as input and returns a HepMC one, but without storing the PDF information.
+The latter could then instead be stored by a separate call
+<pre>
+HepMC::I_Pythia8::pdf_put_info( hepmcevt, pythia, convertGluonTo0 = false )
+</pre>
+or not, as wished.
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Higgs Processes">
+
+<h2>Higgs Processes</h2>
+
+This page documents Higgs production within and beyond the Standard Model
+(SM and BSM for short). This includes several different processes and,
+for the BSM scenarios, a large set of parameters that would only be fixed
+within a more specific framework such as MSSM. Two choices can be made
+irrespective of the particular model:
+
+<flag name="Higgs:cubicWidth" default="off">
+The partial width of a Higgs particle to a pair of gauge bosons,
+<ei>W^+ W^-</ei> or <ei>Z^0 Z^0</ei>, depends cubically on the
+Higgs mass. When selecting the Higgs according to a Breit-Wigner,
+so that the actual mass <ei>mHat</ei> does not agree with the
+nominal <ei>m_Higgs</ei> one, an ambiguity arises which of the
+two to use <ref>Sey95</ref>. The default is to use a linear
+dependence on <ei>mHat</ei>, i.e. a width proportional to
+<ei>m_Higgs^2 * mHat</ei>, while <code>on</code> gives a
+<ei>mHat^3</ei> dependence. This does not affect the widths to
+fermions, which only depend linearly on <ei>mHat</ei>.
+This flag is used both for SM and BSM Higgses.
+</flag>
+
+<flag name="Higgs:runningLoopMass" default="on">
+The partial width of a Higgs particle to a pair of gluons or photons,
+or a <ei>gamma Z^0</ei> pair, proceeds in part through quark loops,
+mainly <ei>b</ei> and <ei>t</ei>. There is some ambiguity what kind
+of masses to use. Default is running MSbar ones, but alternatively
+fixed pole masses are allowed (as was standard in PYTHIA 6), which
+typically gives a noticeably higher cross section for these channels.
+(For a decay to a pair of fermions, such as top, the running mass is
+used for couplings and the fixed one for phase space.)
+</flag>
+
+<h3>Standard-Model Higgs, basic processes</h3>
+
+This section provides the standard set of processes that can be
+run together to provide a reasonably complete overview of possible
+production channels for a single SM Higgs.
+The main parameter is the choice of Higgs mass, which can be set in the
+normal <code>ParticleDataTable</code> database; thereafter the properties
+within the SM are essentially fixed.
+
+<flag name="HiggsSM:all" default="off">
+Common switch for the group of Higgs production within the Standard Model.
+</flag>
+
+<flag name="HiggsSM:ffbar2H" default="off">
+Scattering <ei>f fbar -> H^0</ei>, where <ei>f</ei> sums over available
+flavours except top. Related to the mass-dependent Higgs point coupling
+to fermions, so at hadron colliders the bottom contribution will
+dominate.
+Code 901.
+</flag>
+
+<flag name="HiggsSM:gg2H" default="off">
+Scattering <ei>g g -> H^0</ei> via loop contributions primarily from
+top.
+Code 902.
+</flag>
+
+<flag name="HiggsSM:gmgm2H" default="off">
+Scattering <ei>gamma gamma -> H^0</ei> via loop contributions primarily
+from top and <ei>W</ei>.
+Code 903.
+</flag>
+
+<flag name="HiggsSM:ffbar2HZ" default="off">
+Scattering <ei>f fbar -> H^0 Z^0</ei> via <ei>s</ei>-channel <ei>Z^0</ei>
+exchange.
+Code 904.
+</flag>
+
+<flag name="HiggsSM:ffbar2HW" default="off">
+Scattering <ei>f fbar -> H^0 W^+-</ei> via <ei>s</ei>-channel <ei>W^+-</ei>
+exchange.
+Code 905.
+</flag>
+
+<flag name="HiggsSM:ff2Hff(t:ZZ)" default="off">
+Scattering <ei>f f' -> H^0 f f'</ei> via <ei>Z^0 Z^0</ei> fusion.
+Code 906.
+</flag>
+
+<flag name="HiggsSM:ff2Hff(t:WW)" default="off">
+Scattering <ei>f_1 f_2 -> H^0 f_3 f_4</ei> via <ei>W^+ W^-</ei> fusion.
+Code 907.
+</flag>
+
+<flag name="HiggsSM:gg2Httbar" default="off">
+Scattering <ei>g g -> H^0 t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 908.
+</flag>
+
+<flag name="HiggsSM:qqbar2Httbar" default="off">
+Scattering <ei>q qbar -> H^0 t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 909.
+</flag>
+
+<h3>Standard-Model Higgs, further processes</h3>
+
+A number of further production processes has been implemented, that
+are specializations of some of the above ones to the high-<ei>pT</ei>
+region. The sets therefore could not be used simultaneously
+without unphysical doublecounting, as further explained below.
+They are not switched on by the <code>HiggsSM:all</code> flag, but
+have to be switched on for each separate process after due consideration.
+
+<p/>
+The first three processes in this section are related to the Higgs
+point coupling to fermions, and so primarily are of interest for
+<ei>b</ei> quarks. It is here useful to begin by reminding that
+a process like <ei>b bbar -> H^0</ei> implies that a <ei>b/bbar</ei>
+is taken from each incoming hadron, leaving behind its respective
+antiparticle. The initial-state showers will then add one
+<ei>g -> b bbar</ei> branching on either side, so that effectively
+the process becomes <ei>g g -> H0 b bbar</ei>. This would be the
+same basic process as the <ei>g g -> H^0 t tbar</ei> one used for top.
+The difference is that (a) no PDF's are defined for top and
+(b) the shower approach would not be good enough to provide sensible
+kinematics for the <ei>H^0 t tbar</ei> subsystem. By contrast, owing
+to the <ei>b</ei> being much lighter than the Higgs, multiple
+gluon emissions must be resummed for <ei>b</ei>, as is done by PDF's
+and showers, in order to obtain a sensible description of the total
+production rate, when the <ei>b</ei> quarks predominantly are produced
+at small <ei>pT</ei> values.
+
+<flag name="HiggsSM:qg2Hq" default="off">
+Scattering <ei>q g -> H^0 q</ei>. This process gives first-order
+corrections to the <ei>f fbar -> H^0</ei> one above, and should only be
+used to study the high-<ei>pT</ei> tail, while <ei>f fbar -> H^0</ei>
+should be used for inclusive production. Only the dominant <ei>c</ei>
+and <ei>b</ei> contributions are included, and generated separately
+for technical reasons. Note that another first-order process would be
+<ei>q qbar -> H^0 g</ei>, which is not explicitly implemented here,
+but is obtained from showering off the lowest-order process. It does not
+contain any <ei>b</ei> at large <ei>pT</ei>, however, so is less
+interesting for many applications.
+Code 911.
+
+</flag>
+<flag name="HiggsSM:gg2Hbbbar" default="off">
+Scattering <ei>g g -> H^0 b bbar</ei>. This process is yet one order
+higher of the <ei>b bbar -> H^0</ei> and <ei>b g -> H^0 b</ei> chain,
+where now two quarks should be required above some large <ei>pT</ei>
+threshold.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 912.
+</flag>
+
+<flag name="HiggsSM:qqbar2Hbbbar" default="off">
+Scattering <ei>q qbar -> H^0 b bbar</ei> via an <ei>s</ei>-channel
+gluon, so closely related to the previous one, but typically less
+important owing to the smaller rate of (anti)quarks relative to
+gluons.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 913.
+</flag>
+
+<p/>
+The second set of processes are predominantly first-order corrections
+to the <ei>g g -> H^0</ei> process, again dominated by the top loop.
+We here only provide the kinematical expressions obtained in the
+limit that the top quark goes to infinity, but scaled to the
+finite-top-mass coupling in <ei>g g -> H^0</ei>. (Complete loop
+expressions are available e.g. in PYTHIA 6.4 but are very lengthy.)
+This provides a reasonably accurate description for "intermediate"
+<ei>pT</ei> values, but fails when the <ei>pT</ei> scale approaches
+the top mass.
+
+<flag name="HiggsSM:gg2Hg(l:t)" default="off">
+Scattering <ei>g g -> H^0 g</ei> via loop contributions primarily
+from top.
+Code 914.
+</flag>
+
+<flag name="HiggsSM:qg2Hq(l:t)" default="off">
+Scattering <ei>q g -> H^0 q</ei> via loop contributions primarily
+from top. Not to be confused with the <code>HiggsSM:bg2Hb</code>
+process above, with its direct fermion-to-Higgs coupling.
+Code 915.
+</flag>
+
+<flag name="HiggsSM:qqbar2Hg(l:t)" default="off">
+Scattering <ei>q qbar -> H^0 g</ei> via an <ei>s</ei>-channel gluon
+and loop contributions primarily from top. Is strictly speaking a
+"new" process, not directly derived from <ei>g g -> H^0</ei>, and
+could therefore be included in the standard mix without doublecounting,
+but is numerically negligible.
+Code 916.
+</flag>
+
+<h3>Beyond-the-Standard-Model Higgs, introduction</h3>
+
+Further Higgs multiplets arise in a number of scenarios. We here
+concentrate on the MSSM scenario with two Higgs doublets, but with
+flexibility enough that also other two-Higgs-doublet scenarios could
+be represented by a suitable choice of parameters. Conventionally the
+Higgs states are labelled <ei>h^0, H^0, A^0</ei> and <ei>H^+-</ei>.
+If the scalar and pseudocalar states mix the resulting states are
+labelled <ei>H_1^0, H_2^0, H_3^0</ei>. In process names and parameter
+explanations both notations will be used, but for settings labels
+we have adapted the shorthand hybrid notation <code>H1</code> for
+<ei>h^0(H_1^0)</ei>, <code>H2</code> for <ei>H^0(H_2^0)</ei> and
+<code>A3</code> for <ei>A^0(H_3^0)</ei>. (Recall that the
+<code>Settings</code> database does not distinguish upper- and lowercase
+characters, so that the user has one thing less to worry about, but here
+it causes probles with <ei>h^0</ei> vs. <ei>H^0</ei>.) We leave the issue
+of mass ordering between <ei>H^0</ei> and <ei>A^0</ei> open, and thereby
+also that of <ei>H_2^0</ei> and <ei>H_3^0</ei>.
+
+<flag name="Higgs:useBSM" default="off">
+Master switch to initialize and use the two-Higgs-doublet states.
+If off, only the above SM Higgs processes can be used, with couplings
+as predicted in the SM. If on, only the below BSM Higgs processes can
+be used, with couplings that can be set freely, also found further down
+on this page.
+</flag>
+
+<h3>Beyond-the-Standard-Model Higgs, basic processes</h3>
+
+This section provides the standard set of processes that can be
+run together to provide a reasonably complete overview of possible
+production channels for a single neutral Higgs state in a two-doublet
+scenarios such as MSSM. The list of processes for neutral states closely
+mimics the one found for the SM Higgs. Some of the processes
+vanish for a pure pseudoscalar <ei>A^0</ei>, but are kept for flexiblity
+in cases of mixing with the scalar <ei>h^0</ei> and <ei>H^0</ei> states,
+or for use in the context of non-MSSM models. This should work well to
+represent e.g. that a small admixture of the "wrong" parity would allow
+a process such as <ei>q qbar -> A^0 Z^0</ei>, which otherwise is forbidden.
+However, note that the loop integrals e.g. for <ei>g g -> h^0/H^0/A^0</ei>
+are hardcoded to be for scalars for the former two particles and for a
+pseudoscalar for the latter one, so absolute rates would not be
+correctly represented in the case of large scalar/pseudoscalar mixing.
+
+<flag name="HiggsBSM:all" default="off">
+Common switch for the group of Higgs production beyond the Standard Model,
+as listed below.
+</flag>
+
+<h4>1) <ei>h^0(H_1^0)</ei> processes</h4>
+
+<flag name="HiggsBSM:allH1" default="off">
+Common switch for the group of <ei>h^0(H_1^0)</ei> production processes.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H1" default="off">
+Scattering <ei>f fbar -> h^0(H_1^0)</ei>, where <ei>f</ei> sums over available
+flavours except top.
+Code 1001.
+</flag>
+
+<flag name="HiggsBSM:gg2H1" default="off">
+Scattering <ei>g g -> h^0(H_1^0)</ei> via loop contributions primarily from
+top.
+Code 1002.
+</flag>
+
+<flag name="HiggsBSM:gmgm2H1" default="off">
+Scattering <ei>gamma gamma -> h^0(H_1^0)</ei> via loop contributions primarily
+from top and <ei>W</ei>.
+Code 1003.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H1Z" default="off">
+Scattering <ei>f fbar -> h^0(H_1^0) Z^0</ei> via <ei>s</ei>-channel <ei>Z^0</ei>
+exchange.
+Code 1004.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H1W" default="off">
+Scattering <ei>f fbar -> h^0(H_1^0) W^+-</ei> via <ei>s</ei>-channel <ei>W^+-</ei>
+exchange.
+Code 1005.
+</flag>
+
+<flag name="HiggsBSM:ff2H1ff(t:ZZ)" default="off">
+Scattering <ei>f f' -> h^0(H_1^0) f f'</ei> via <ei>Z^0 Z^0</ei> fusion.
+Code 1006.
+</flag>
+
+<flag name="HiggsBSM:ff2H1ff(t:WW)" default="off">
+Scattering <ei>f_1 f_2 -> h^0(H_1^0) f_3 f_4</ei> via <ei>W^+ W^-</ei> fusion.
+Code 1007.
+</flag>
+
+<flag name="HiggsBSM:gg2H1ttbar" default="off">
+Scattering <ei>g g -> h^0(H_1^0) t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1008.
+</flag>
+
+<flag name="HiggsBSM:qqbar2H1ttbar" default="off">
+Scattering <ei>q qbar -> h^0(H_1^0) t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1009.
+
+
+<h4>2) <ei>H^0(H_2^0)</ei> processes</h4>
+
+<flag name="HiggsBSM:allH2" default="off">
+Common switch for the group of <ei>H^0(H_2^0)</ei> production processes.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H2" default="off">
+Scattering <ei>f fbar -> H^0(H_2^0)</ei>, where <ei>f</ei> sums over available
+flavours except top.
+Code 1021.
+</flag>
+
+<flag name="HiggsBSM:gg2H2" default="off">
+Scattering <ei>g g -> H^0(H_2^0)</ei> via loop contributions primarily from
+top.
+Code 1022.
+</flag>
+
+<flag name="HiggsBSM:gmgm2H2" default="off">
+Scattering <ei>gamma gamma -> H^0(H_2^0)</ei> via loop contributions primarily
+from top and <ei>W</ei>.
+Code 1023.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H2Z" default="off">
+Scattering <ei>f fbar -> H^0(H_2^0) Z^0</ei> via <ei>s</ei>-channel <ei>Z^0</ei>
+exchange.
+Code 1024.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H2W" default="off">
+Scattering <ei>f fbar -> H^0(H_2^0) W^+-</ei> via <ei>s</ei>-channel <ei>W^+-</ei>
+exchange.
+Code 1025.
+</flag>
+
+<flag name="HiggsBSM:ff2H2ff(t:ZZ)" default="off">
+Scattering <ei>f f' -> H^0(H_2^0) f f'</ei> via <ei>Z^0 Z^0</ei> fusion.
+Code 1026.
+</flag>
+
+<flag name="HiggsBSM:ff2H2ff(t:WW)" default="off">
+Scattering <ei>f_1 f_2 -> H^0(H_2^0) f_3 f_4</ei> via <ei>W^+ W^-</ei> fusion.
+Code 1027.
+</flag>
+
+<flag name="HiggsBSM:gg2H2ttbar" default="off">
+Scattering <ei>g g -> H^0(H_2^0) t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1028.
+</flag>
+
+<flag name="HiggsBSM:qqbar2H2ttbar" default="off">
+Scattering <ei>q qbar -> H^0(H_2^0) t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1029.
+
+<h4>3) <ei>A^0(H_3^0)</ei> processes</h4>
+
+<flag name="HiggsBSM:allA3" default="off">
+Common switch for the group of <ei>A^0(H_3^0)</ei> production processes.
+</flag>
+
+<flag name="HiggsBSM:ffbar2A3" default="off">
+Scattering <ei>f fbar -> A^0(H_3^0)</ei>, where <ei>f</ei> sums over available
+flavours except top.
+Code 1041.
+</flag>
+
+<flag name="HiggsBSM:gg2A3" default="off">
+Scattering <ei>g g -> A^0(A_3^0)</ei> via loop contributions primarily from
+top.
+Code 1042.
+</flag>
+
+<flag name="HiggsBSM:gmgm2A3" default="off">
+Scattering <ei>gamma gamma -> A^0(A_3^0)</ei> via loop contributions primarily
+from top and <ei>W</ei>.
+Code 1043.
+</flag>
+
+<flag name="HiggsBSM:ffbar2A3Z" default="off">
+Scattering <ei>f fbar -> A^0(A_3^0) Z^0</ei> via <ei>s</ei>-channel <ei>Z^0</ei>
+exchange.
+Code 1044.
+</flag>
+
+<flag name="HiggsBSM:ffbar2A3W" default="off">
+Scattering <ei>f fbar -> A^0(A_3^0) W^+-</ei> via <ei>s</ei>-channel <ei>W^+-</ei>
+exchange.
+Code 1045.
+</flag>
+
+<flag name="HiggsBSM:ff2A3ff(t:ZZ)" default="off">
+Scattering <ei>f f' -> A^0(A_3^0) f f'</ei> via <ei>Z^0 Z^0</ei> fusion.
+Code 1046.
+</flag>
+
+<flag name="HiggsBSM:ff2A3ff(t:WW)" default="off">
+Scattering <ei>f_1 f_2 -> A^0(A_3^0) f_3 f_4</ei> via <ei>W^+ W^-</ei> fusion.
+Code 1047.
+</flag>
+
+<flag name="HiggsBSM:gg2A3ttbar" default="off">
+Scattering <ei>g g -> A^0(A_3^0) t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1048.
+</flag>
+
+<flag name="HiggsBSM:qqbar2A3ttbar" default="off">
+Scattering <ei>q qbar -> A^0(A_3^0) t tbar</ei> via <ei>t tbar</ei> fusion
+(or, alternatively put, Higgs radiation off a top line).
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1049.
+
+<h4>4) <ei>H+-</ei> processes</h4>
+
+<flag name="HiggsBSM:allH+-" default="off">
+Common switch for the group of <ei>H^+-</ei> production processes.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H+-" default="off">
+Scattering <ei>f fbar' -> H^+-</ei>, where <ei>f, fbar'</ei> sums over
+available incoming flavours. Since couplings are assumed
+generation-diagonal, in practice this means <ei>c sbar -> H^+</ei>
+and <ei>s cbar -> H^-</ei>.
+Code 1061.
+</flag>
+
+<flag name="HiggsBSM:bg2H+-t" default="off">
+Scattering <ei>b g -> H^+ tbar</ei>. At hadron colliders this is the
+dominant process for single-charged-Higgs production.
+Code 1062.
+</flag>
+
+<h4>5) Higgs-pair processes</h4>
+
+<flag name="HiggsBSM:allHpair" default="off">
+Common switch for the group of Higgs pair-production processes.
+</flag>
+
+<flag name="HiggsBSM:ffbar2A3H1" default="off">
+Scattering <ei>f fbar -> A^0(H_3) h^0(H_1)</ei>.
+Code 1081.
+</flag>
+
+<flag name="HiggsBSM:ffbar2A3H2" default="off">
+Scattering <ei>f fbar -> A^0(H_3) H^0(H_2)</ei>.
+Code 1082.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H+-H1" default="off">
+Scattering <ei>f fbar -> H^+- h^0(H_1)</ei>.
+Code 1083.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H+-H2" default="off">
+Scattering <ei>f fbar -> H^+- H^0(H_2)</ei>.
+Code 1084.
+</flag>
+
+<flag name="HiggsBSM:ffbar2H+H-" default="off">
+Scattering <ei>f fbar -> H+ H-</ei>.
+Code 1085.
+</flag>
+
+<h3>Beyond-the-Standard-Model Higgs, further processes</h3>
+
+This section mimics the above section on "Standard-Model Higgs,
+further processes", i.e. it contains higher-order corrections
+to the processes already listed. The two sets therefore could not
+be used simultaneously without unphysical doublecounting.
+They are not controlled by any group flag, but have to be switched
+on for each separate process after due consideration. We refer to
+the standard-model description for a set of further comments on
+the processes.
+
+<h4>1) <ei>h^0(H_1^0)</ei> processes</h4>
+
+<flag name="HiggsBSM:qg2H1q" default="off">
+Scattering <ei>q g -> h^0 q</ei>. This process gives first-order
+corrections to the <ei>f fbar -> h^0</ei> one above, and should only be
+used to study the high-<ei>pT</ei> tail, while <ei>f fbar -> h^0</ei>
+should be used for inclusive production. Only the dominant <ei>c</ei>
+and <ei>b</ei> contributions are included, and generated separately
+for technical reasons. Note that another first-order process would be
+<ei>q qbar -> h^0 g</ei>, which is not explicitly implemented here,
+but is obtained from showering off the lowest-order process. It does not
+contain any <ei>b</ei> at large <ei>pT</ei>, however, so is less
+interesting for many applications.
+Code 1011.
+</flag>
+
+<flag name="HiggsBSM:gg2H1bbbar" default="off">
+Scattering <ei>g g -> h^0 b bbar</ei>. This process is yet one order
+higher of the <ei>b bbar -> h^0</ei> and <ei>b g -> h^0 b</ei> chain,
+where now two quarks should be required above some large <ei>pT</ei>
+threshold.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1012.
+</flag>
+
+<flag name="HiggsBSM:qqbar2H1bbbar" default="off">
+Scattering <ei>q qbar -> h^0 b bbar</ei> via an <ei>s</ei>-channel
+gluon, so closely related to the previous one, but typically less
+important owing to the smaller rate of (anti)quarks relative to
+gluons.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1013.
+</flag>
+
+<flag name="HiggsBSM:gg2H1g(l:t)" default="off">
+Scattering <ei>g g -> h^0 g</ei> via loop contributions primarily
+from top.
+Code 1014.
+</flag>
+
+<flag name="HiggsBSM:qg2H1q(l:t)" default="off">
+Scattering <ei>q g -> h^0 q</ei> via loop contributions primarily
+from top. Not to be confused with the <code>HiggsBSM:bg2H1b</code>
+process above, with its direct fermion-to-Higgs coupling.
+Code 1015.
+</flag>
+
+<flag name="HiggsBSM:qqbar2H1g(l:t)" default="off">
+Scattering <ei>q qbar -> h^0 g</ei> via an <ei>s</ei>-channel gluon
+and loop contributions primarily from top. Is strictly speaking a
+"new" process, not directly derived from <ei>g g -> h^0</ei>, and
+could therefore be included in the standard mix without doublecounting,
+but is numerically negligible.
+Code 1016.
+</flag>
+
+<h4>2) <ei>H^0(H_2^0)</ei> processes</h4>
+
+<flag name="HiggsBSM:qg2H2q" default="off">
+Scattering <ei>q g -> H^0 q</ei>. This process gives first-order
+corrections to the <ei>f fbar -> H^0</ei> one above, and should only be
+used to study the high-<ei>pT</ei> tail, while <ei>f fbar -> H^0</ei>
+should be used for inclusive production. Only the dominant <ei>c</ei>
+and <ei>b</ei> contributions are included, and generated separately
+for technical reasons. Note that another first-order process would be
+<ei>q qbar -> H^0 g</ei>, which is not explicitly implemented here,
+but is obtained from showering off the lowest-order process. It does not
+contain any <ei>b</ei> at large <ei>pT</ei>, however, so is less
+interesting for many applications.
+Code 1031.
+</flag>
+
+<flag name="HiggsBSM:gg2H2bbbar" default="off">
+Scattering <ei>g g -> H^0 b bbar</ei>. This process is yet one order
+higher of the <ei>b bbar -> H^0</ei> and <ei>b g -> H^0 b</ei> chain,
+where now two quarks should be required above some large <ei>pT</ei>
+threshold.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1032.
+</flag>
+
+<flag name="HiggsBSM:qqbar2H2bbbar" default="off">
+Scattering <ei>q qbar -> H^0 b bbar</ei> via an <ei>s</ei>-channel
+gluon, so closely related to the previous one, but typically less
+important owing to the smaller rate of (anti)quarks relative to
+gluons.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1033.
+</flag>
+
+<flag name="HiggsBSM:gg2H2g(l:t)" default="off">
+Scattering <ei>g g -> H^0 g</ei> via loop contributions primarily
+from top.
+Code 1034.
+</flag>
+
+<flag name="HiggsBSM:qg2H2q(l:t)" default="off">
+Scattering <ei>q g -> H^0 q</ei> via loop contributions primarily
+from top. Not to be confused with the <code>HiggsBSM:bg2H1b</code>
+process above, with its direct fermion-to-Higgs coupling.
+Code 1035.
+</flag>
+
+<flag name="HiggsBSM:qqbar2H2g(l:t)" default="off">
+Scattering <ei>q qbar -> H^0 g</ei> via an <ei>s</ei>-channel gluon
+and loop contributions primarily from top. Is strictly speaking a
+"new" process, not directly derived from <ei>g g -> H^0</ei>, and
+could therefore be included in the standard mix without doublecounting,
+but is numerically negligible.
+Code 1036.
+</flag>
+
+<h4>3) <ei>A^0(H_3^0)</ei> processes</h4>
+
+<flag name="HiggsBSM:qg2A3q" default="off">
+Scattering <ei>q g -> A^0 q</ei>. This process gives first-order
+corrections to the <ei>f fbar -> A^0</ei> one above, and should only be
+used to study the high-<ei>pT</ei> tail, while <ei>f fbar -> A^0</ei>
+should be used for inclusive production. Only the dominant <ei>c</ei>
+and <ei>b</ei> contributions are included, and generated separately
+for technical reasons. Note that another first-order process would be
+<ei>q qbar -> A^0 g</ei>, which is not explicitly implemented here,
+but is obtained from showering off the lowest-order process. It does not
+contain any <ei>b</ei> at large <ei>pT</ei>, however, so is less
+interesting for many applications.
+Code 1051.
+</flag>
+
+<flag name="HiggsBSM:gg2A3bbbar" default="off">
+Scattering <ei>g g -> A^0 b bbar</ei>. This process is yet one order
+higher of the <ei>b bbar -> A^0</ei> and <ei>b g -> A^0 b</ei> chain,
+where now two quarks should be required above some large <ei>pT</ei>
+threshold.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1052.
+</flag>
+
+<flag name="HiggsBSM:qqbar2A3bbbar" default="off">
+Scattering <ei>q qbar -> A^0 b bbar</ei> via an <ei>s</ei>-channel
+gluon, so closely related to the previous one, but typically less
+important owing to the smaller rate of (anti)quarks relative to
+gluons.
+Warning: unfortunately this process is rather slow, owing to a
+lengthy cross-section expression and inefficient phase-space selection.
+Code 1053.
+</flag>
+
+<flag name="HiggsBSM:gg2A3g(l:t)" default="off">
+Scattering <ei>g g -> A^0 g</ei> via loop contributions primarily
+from top.
+Code 1054.
+</flag>
+
+<flag name="HiggsBSM:qg2A3q(l:t)" default="off">
+Scattering <ei>q g -> A^0 q</ei> via loop contributions primarily
+from top. Not to be confused with the <code>HiggsBSM:bg2H1b</code>
+process above, with its direct fermion-to-Higgs coupling.
+Code 1055.
+</flag>
+
+<flag name="HiggsBSM:qqbar2A3g(l:t)" default="off">
+Scattering <ei>q qbar -> A^0 g</ei> via an <ei>s</ei>-channel gluon
+and loop contributions primarily from top. Is strictly speaking a
+"new" process, not directly derived from <ei>g g -> A^0</ei>, and
+could therefore be included in the standard mix without doublecounting,
+but is numerically negligible.
+Code 1056.
+</flag>
+
+<h3>Parameters for Beyond-the-Standard-Model Higgs production and decay</h3>
+
+This section offers a big flexibility to set couplings of the various
+Higgs states to fermions and gauge bosons, and also to each other.
+The intention is that, for scenarios like MSSM, you should use standard
+input from the <aloc href="SUSYLesHouchesAccord">SUSY Les Houches
+Accord</aloc>, rather than having to set it all yourself. In other cases,
+however, the freedom is there for you to use. Kindly note that some
+of the internal calculations of partial widths from the parameters provided
+do not include mixing between the scalar and pseudoscalar states.
+
+<p/>
+Masses would be set in the <code>ParticleDataTable</code> database,
+while couplings are set below. When possible, the couplings of the Higgs
+states are normalized to the corresponding coupling within the SM.
+When not, their values within the MSSM are indicated, from which
+it should be straightforward to understand what to use instead.
+The exception is some couplings that vanish also in the MSSM, where the
+normalization has been defined in close analogy with nonvanishing ones.
+Some parameter names are asymmetric but crossing can always be used,
+i.e. the coupling for <ei>A^0 -> H^0 Z^0</ei> obviously is also valid
+for <ei>H^0 -> A^0 Z^0</ei> and <ei>Z^0 -> H^0 A^0</ei>.
+Note that couplings usually appear quadratically in matrix elements.
+
+<parm name="HiggsH1:coup2d" default="1.">
+The <ei>h^0(H_1^0)</ei> coupling to down-type quarks.
+</parm>
+
+<parm name="HiggsH1:coup2u" default="1.">
+The <ei>h^0(H_1^0)</ei> coupling to up-type quarks.
+</parm>
+
+<parm name="HiggsH1:coup2l" default="1.">
+The <ei>h^0(H_1^0)</ei> coupling to (charged) leptons.
+</parm>
+
+<parm name="HiggsH1:coup2Z" default="1.">
+The <ei>h^0(H_1^0)</ei> coupling to <ei>Z^0</ei>.
+</parm>
+
+<parm name="HiggsH1:coup2W" default="1.">
+The <ei>h^0(H_1^0)</ei> coupling to <ei>W^+-</ei>.
+</parm>
+
+<parm name="HiggsH1:coup2Hchg" default="0.">
+The <ei>h^0(H_1^0)</ei> coupling to <ei>H^+-</ei> (in loops).
+Is <ei>sin(beta - alpha) + cos(2 beta) sin(beta + alpha) /
+(2 cos^2theta_W)</ei> in the MSSM.
+</parm>
+
+<parm name="HiggsH2:coup2d" default="1.">
+The <ei>H^0(H_2^0)</ei> coupling to down-type quarks.
+</parm>
+
+<parm name="HiggsH2:coup2u" default="1.">
+The <ei>H^0(H_2^0)</ei> coupling to up-type quarks.
+</parm>
+
+<parm name="HiggsH2:coup2l" default="1.">
+The <ei>H^0(H_2^0)</ei> coupling to (charged) leptons.
+</parm>
+
+<parm name="HiggsH2:coup2Z" default="1.">
+The <ei>H^0(H_2^0)</ei> coupling to <ei>Z^0</ei>.
+</parm>
+
+<parm name="HiggsH2:coup2W" default="1.">
+The <ei>H^0(H_2^0)</ei> coupling to <ei>W^+-</ei>.
+</parm>
+
+<parm name="HiggsH2:coup2Hchg" default="0.">
+The <ei>H^0(H_2^0)</ei> coupling to <ei>H^+-</ei> (in loops).
+Is <ei>cos(beta - alpha) + cos(2 beta) cos(beta + alpha) /
+(2 cos^2theta_W)</ei> in the MSSM.
+</parm>
+
+<parm name="HiggsH2:coup2H1H1" default="1.">
+The <ei>H^0(H_2^0)</ei> coupling to a <ei>h^0(H_1^0)</ei> pair.
+Is <ei>cos(2 alpha) cos(beta + alpha) - 2 sin(2 alpha)
+sin(beta + alpha)</ei> in the MSSM.
+</parm>
+
+<parm name="HiggsH2:coup2A3A3" default="1.">
+The <ei>H^0(H_2^0)</ei> coupling to an <ei>A^0(H_3^0)</ei> pair.
+Is <ei>cos(2 beta) cos(beta + alpha)</ei> in the MSSM.
+</parm>
+
+<parm name="HiggsH2:coup2H1Z" default="0.">
+The <ei>H^0(H_2^0)</ei> coupling to a <ei>h^0(H_1^0) Z^0</ei> pair.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsH2:coup2A3H1" default="0.">
+The <ei>H^0(H_2^0)</ei> coupling to an <ei>A^0(H_3^0) h^0(H_1^0)</ei> pair.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsH2:coup2HchgW" default="0.">
+The <ei>H^0(H_2^0)</ei> coupling to a <ei>H^+- W-+</ei> pair.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsA3:coup2d" default="1.">
+The <ei>A^0(H_3^0)</ei> coupling to down-type quarks.
+</parm>
+
+<parm name="HiggsA3:coup2u" default="1.">
+The <ei>A^0(H_3^0)</ei> coupling to up-type quarks.
+</parm>
+
+<parm name="HiggsA3:coup2l" default="1.">
+The <ei>A^0(H_3^0)</ei> coupling to (charged) leptons.
+</parm>
+
+<parm name="HiggsA3:coup2H1Z" default="1.">
+The <ei>A^0(H_3^0)</ei> coupling to a <ei>h^0(H_1^0) Z^0</ei> pair.
+Is <ei>cos(beta - alpha)</ei> in the MSSM.
+</parm>
+
+<parm name="HiggsA3:coup2H2Z" default="1.">
+The <ei>A^0(H_3^0)</ei> coupling to a <ei>H^0(H_2^0) Z^0</ei> pair.
+Is <ei>sin(beta - alpha)</ei> in the MSSM.
+</parm>
+
+<parm name="HiggsA3:coup2Z" default="0.">
+The <ei>A^0(H_3^0)</ei> coupling to <ei>Z^0</ei>.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsA3:coup2W" default="0.">
+The <ei>A^0(H_3^0)</ei> coupling to <ei>W^+-</ei>.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsA3:coup2H1H1" default="0.">
+The <ei>A^0(H_3^0)</ei> coupling to a <ei>h^0(H_1^0)</ei> pair.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsA3:coup2Hchg" default="0.">
+The <ei>A^0(H_3^0)</ei> coupling to <ei>H^+-</ei>.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsA3:coup2HchgW" default="0.">
+The <ei>A^0(H_3^0)</ei> coupling to a <ei>H^+- W-+</ei> pair.
+Vanishes in the MSSM.
+</parm>
+
+<parm name="HiggsHchg:tanBeta" default="5.">
+The <ei>tan(beta)</ei> value, which leads to an enhancement of the
+<ei>H^+-</ei> coupling to down-type fermions and suppression to
+up-type ones. The same angle also appears in many other places,
+but this particular parameter is only used for the charged-Higgs case.
+</parm>
+
+<parm name="HiggsHchg:coup2H1W" default="1.">
+The <ei>H^+-</ei> coupling to a <ei>h^0(H_1^0) W^+-</ei> pair.
+Is <ei>cos(beta - alpha)</ei> in the MSSM.
+</parm>
+
+<parm name="HiggsHchg:coup2H2W" default="0.">
+The <ei>H^+-</ei> coupling to a <ei>H^0(H_2^0) W^+-</ei> pair.
+Is <ei>1 - cos(beta - alpha)</ei> in the MSSM.
+</parm>
+
+<p/>
+Another set of parameters are not used in the production stage but
+exclusively for the description of angular distributions in decays.
+
+<modepick name="HiggsH1:parity" default="1" min="0" max="3">
+possibility to modify angular decay correlations in the decay of a
+<ei>h^0(H_1)</ei> decay <ei>Z^0 Z^0</ei> or <ei>W^+ W^-</ei> to four
+fermions. Currently it does not affect the partial width of the
+channels, which is only based on the above parameters.
+<option value="0">isotropic decays.</option>
+<option value="1">assuming the <ei>h^0(H_1)</ei> is a pure scalar
+(CP-even), as in the MSSM.</option>
+<option value="2">assuming the <ei>h^0(H_1)</ei> is a pure pseudoscalar
+(CP-odd).</option>
+<option value="3">assuming the <ei>h^0(H_1)</ei> is a mixture of the two,
+including the CP-violating interference term. The parameter
+<ei>eta</ei>, see below, sets the strength of the CP-odd admixture,
+with the interference term being proportional to <ei>eta</ei>
+and the CP-odd one to <ei>eta^2</ei>.</option>
+</modepick>
+
+<parm name="HiggsH1:etaParity" default="0.">
+The <ei>eta</ei> value of CP-violation in the
+<code>HiggsSM:parity = 3</code> option.
+</parm>
+
+<modepick name="HiggsH2:parity" default="1" min="0" max="3">
+possibility to modify angular decay correlations in the decay of a
+<ei>H^0(H_2)</ei> decay <ei>Z^0 Z^0</ei> or <ei>W^+ W^-</ei> to four
+fermions. Currently it does not affect the partial width of the
+channels, which is only based on the above parameters.
+<option value="0">isotropic decays.</option>
+<option value="1">assuming the <ei>H^0(H_2)</ei> is a pure scalar
+(CP-even), as in the MSSM.</option>
+<option value="2">assuming the <ei>H^0(H_2)</ei> is a pure pseudoscalar
+(CP-odd).</option>
+<option value="3">assuming the <ei>H^0(H_2)</ei> is a mixture of the two,
+including the CP-violating interference term. The parameter
+<ei>eta</ei>, see below, sets the strength of the CP-odd admixture,
+with the interference term being proportional to <ei>eta</ei>
+and the CP-odd one to <ei>eta^2</ei>.</option>
+</modepick>
+
+<parm name="HiggsH2:etaParity" default="0.">
+The <ei>eta</ei> value of CP-violation in the
+<code>HiggsSM:parity = 3</code> option.
+</parm>
+
+<modepick name="HiggsA3:parity" default="2" min="0" max="3">
+possibility to modify angular decay correlations in the decay of a
+<ei>A^0(H_3)</ei> decay <ei>Z^0 Z^0</ei> or <ei>W^+ W^-</ei> to four
+fermions. Currently it does not affect the partial width of the
+channels, which is only based on the above parameters.
+<option value="0">isotropic decays.</option>
+<option value="1">assuming the <ei>A^0(H_3)</ei> is a pure scalar
+(CP-even).</option>
+<option value="2">assuming the <ei>A^0(H_3)</ei> is a pure pseudoscalar
+(CP-odd), as in the MSSM.</option>
+<option value="3">assuming the <ei>A^0(H_3)</ei> is a mixture of the two,
+including the CP-violating interference term. The parameter
+<ei>eta</ei>, see below, sets the strength of the CP-odd admixture,
+with the interference term being proportional to <ei>eta</ei>
+and the CP-odd one to <ei>eta^2</ei>.</option>
+</modepick>
+
+<parm name="HiggsA3:etaParity" default="0.">
+The <ei>eta</ei> value of CP-violation in the
+<code>HiggsSM:parity = 3</code> option.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Histograms">
+
+<h2>Histograms</h2>
+
+The <code>Hist</code> class gives a simple implementation of
+one-dimensional histograms, useful for quick-and-dirty testing,
+without the need to link to more sophisticated packages.
+For this reson it is used in many of the sample main programs
+found in the <code>examples</code> subdirectory.
+
+
+<p/>
+A Histogram is declared by a
+<class name="Hist name( title, numberOfBins, xMin, xMax)">
+where
+<argument name="title">
+is a string with the title of the histogram at output,
+</argument>
+<argument name="numberOfBins">
+is the number of bin the <ei>x</ei> range will be subdivided into,
+</argument>
+<argument name="xMin">
+is the lower edge of the histogram,
+</argument>
+<argument name="xMax">
+is the upper edge of the histogram.
+</argument>
+</class>
+
+<p/>
+For instance
+<pre>
+ Hist ZpT( "Z0 pT spectrum", 100, 0., 100.);
+</pre>
+Alternatively you can first declare it and later define it:
+<pre>
+ Hist ZpT;
+ ZpT.book( "Z0 pT spectrum", 100, 0., 100.);
+</pre>
+
+Once declared, its contents can be added by repeated calls to
+<code>fill</code>
+<method name="fill( xValue, weight)">
+where
+<argument name="xValue">
+is the <ei>x</ei> position where the filling should occur, and
+</argument>
+<argument name="weight" default="1.">
+is the amount of weight to be added at this <ei>x</ei> value.
+</argument>
+</method>
+
+<p/>
+For instance
+<pre>
+ ZpT.fill( 22.7, 1.);
+</pre>
+Since the weight defaults to 1 the last argument could have been
+omitted in this case.
+
+<p/>
+A set of overloaded operators have been defined, so that histograms
+can be added, subtracted, divided or multiplied by each other. Then the
+contents are modified accordingly bin by bin. Thus the relative
+deviation between two histograms can be found as
+<pre>
+ diff = (data - theory) / (data + theory);
+</pre>
+assuming that <code>diff</code>, <code>data</code> and <code>theory</code>
+have been booked with the same number of bins and <ei>x</ei> range. That
+responsibility rests on the user; some checks are made for compatibility,
+but not enough to catch all possible mistakes.
+
+<p/>
+Also overloaded operations with double real numbers are available.
+Again these four operations are defined bin by bin, i.e. the
+corresponding amount is added to, subtracted from, multiplied by or
+divided by each bin. The double number can come before or after the
+histograms, with obvious results. Thus the inverse of a histogram
+<code>result</code> is given by <code>1. / result</code>.
+The two kind of operations can be combined, e.g.
+<pre>
+ allpT = ZpT + 2. * WpT
+</pre>
+Finally, also the <code>+=, -+, *=, /=</code> are overloaded, with
+the right-hand side being either a histogram or a real number.
+
+<p/>
+A histogram can be printed by making use of the overloaded <<
+operator, e.g.:
+<pre>
+ cout << ZpT;
+</pre>
+The printout format is inspired by the old HBOOK one. To understand
+how to read this format, consider the simplified example
+<pre>
+
+ 3.50*10^ 2 9
+ 3.00*10^ 2 X 7
+ 2.50*10^ 2 X 1X
+ 2.00*10^ 2 X6 XX
+ 1.50*10^ 2 XX5XX
+ 1.00*10^ 2 XXXXX
+ 0.50*10^ 2 XXXXX
+
+ Contents
+ *10^ 2 31122
+ *10^ 1 47208
+ *10^ 0 79373
+
+ Low edge --
+ *10^ 1 10001
+ *10^ 0 05050
+</pre>
+The key feature is that the <code>Contents</code> and
+<code>Low edge</code> have to be read vertically. For instance,
+the first bin has the contents
+<code>3 * 10^2 + 4 * 10^1 + 7 * 10^0 = 347</code>. Correspondingly,
+the other bins have contents 179, 123, 207 and 283. The first bin
+stretches from <code>-(1 * 10^1 + 0 * 10^0) = -10</code> to the
+beginning of the second bin, at <code>-(0 * 10^1 + 5 * 10^0) = -5</code>.
+
+<p/>
+The visual representation above the contents give a simple impression
+of the shape. An <code>X</code> means that the contents are filled up
+to this level, a digit in the topmost row the fraction to which the
+last level is filled. So the 9 of the first column indicates this bin
+is filled 9/10 of the way from <code>3.00*10^2 = 300</code> to
+<code>3.50*10^2 = 350</code>, i.e. somewhere close to 345,
+or more precisely in the range 342.5 to 347.5.
+
+<p/>
+The printout also provides some other information, such as the
+number of entries, i.e. how many times the histogram has been filled,
+the total weight inside the histogram, the total weight in underflow
+and overflow, and the mean value and root-mean-square width (disregarding
+underflow and overflow). The mean and width assumes that all the
+contents is in the middle of the respective bin. This is especially
+relevant when you plot a integer quantity, such as a multiplicity.
+Then it makes sense to book with limits that are half-integers, e.g.
+<pre>
+ Hist multMI( "number of multiple interactions", 20, -0.5, 19.5);
+</pre>
+so that the bins are centered at 0, 1, 2, ..., respectively. This also
+avoids ambiguities which bin gets to be filled if entries are
+exactly at the border between two bins. Also note that the
+<code>fill( xValue)</code> method automatically performs a cast
+to double precision where necessary, i.e. <code>xValue</code>
+can be an integer.
+
+<p/>
+Some further metods are:
+<ul>
+<li><code>getBinContent(iBin)</code> returns the value in bin
+<code>iBin</code>, ranging from 1 through <code>nBin</code>,
+with <code>0</code> for underflow and <code>nBin + 1</code> for
+overflow.</li>
+<li><code>getEntries()</code> returns the number of entries.</li>
+<li><code>table(ostream& = cout)</code> prints a two-column table,
+where the first gives the center of each bin and the second the
+corresponding bin contents. This may be useful for plotting e.g. with
+Gnuplot.</li>
+<li><code>null()</code> resets bin contents.</li>
+<li><code>name( title)</code> resets the title to the new string.</li>
+<li><code>sameSize( Hist&)</code> checks that the number of bins and
+upper and lower limits are the same as in the histogram in the
+argument.</li>
+<li><code>takeLog(true)</code> take 10-logarithm of contents
+bin by bin.</li>
+<li><code>takeLog(false)</code> take <ei>e</ei>-logarithm of contents
+bin by bin.</li>
+</ul>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Implement New Showers">
+
+<h2>Implement New Showers</h2>
+
+In case you want to replace the PYTHIA initial- and final-state
+showers by your own, it is possible but not trivial. The point is
+that multiple interactions (MI), initial-state radiation (ISR) and
+final-state radiation (FSR) in general appear in one single
+interleaved sequence of decreasing <ei>pT</ei> values. Therefore
+shower replacements would have to be able to play the game by such
+rules, as we will outline further below. Of course, this still
+leaves the field open exactly how to define what to mean by
+<ei>pT</ei>, how to handle recoil effects, how the colour flow is
+affected, and so on, so there is certainly room for alternative
+showers.
+
+<p/>
+For the moment we assume you want to keep the MI part of the story
+unchanged, and make use of the existing beam-remnants (BR) machinery.
+If you want to replace both MI, ISR, FSR and BR then you had better
+replace the whole <code>PartonLevel</code> module of the code.
+If, in addition, you want to produce your own hard processes,
+then you only need the
+<aloc href="HadronLevelStandalone">hadron-level standalone</aloc>
+part of the machinery.
+
+<p/>
+In order to write replacement codes for ISR and/or FSR it is useful
+to be aware of which information has to be shared between the
+different components, and which input/output structure is required
+of the relevant methods. For details, nothing beats studying the
+existing code. However, here we provide an overview, that should
+serve as a useful introduction.
+
+<p/>
+It should be noted that we here primarily address the problem in
+its full generality, with interleaved MI, ISR and FSR. There exists
+an option <code>TimeShower:interleave = off</code> where only
+MI and ISR would be interleaved and FSR be considered after these
+two, but still before BR. Most of the aspects described here would
+apply also for that case. By contrast, resonance decays are only
+considered after all the four above components, and timelike
+showers in those decays would never be interleaved with anything
+else, so are much simpler to administrate.
+
+<p/>
+Therefore the <aloc href="ProgramFlow">
+<code>pythia.setShowerPtr( timesDecPtr, timesPtr, spacePtr)</code></aloc>
+method allows two separate pointers to be set to instances of
+derived <code>TimeShower</code> classes. The first is only required
+to handle decays, say of <ei>Z^0</ei> or <ei>Upsilon</ei>, with no
+dependence on beam remnants or ISR. The second, as well as
+<code>spacePtr</code>, has to handle the interleaved evolution of MI,
+ISR and FSR. Therefore you are free to implement only the first, and
+let the PYTHIA default showers take care of the latter two. But, if
+you wanted to, you could also set <code>timesDecPtr = 0</code> and
+only provide a <code>timesPtr</code>, or only a <code>spacePtr</code>.
+If your timelike shower does both cases, the first two pointers
+can agree. The only tiny point to take into account then is that
+<code>init( beamAPtr, beamBPtr)</code> is called twice, a first time
+to <code>timesDecPtr</code> with beam pointers 0, and a second time
+to <code>timesPtr</code> with nonvanishing beam pointers.
+
+<h3>The event record</h3>
+
+Obviously the main place for sharing information is the event
+record, specifically the <code>Event event</code> member of
+<code>Pythia</code>, passed around as a reference. It is
+assumed you already studied how it works, so here we only draw
+attention to a few aspects of special relevance.
+
+<p/>
+One basic principle is that existing partons should not be
+overwritten. Instead new partons should be created, even when a
+parton only receives a slightly shifted momentum and for the rest
+stays the same. Such "carbon copies" by final-state branchings
+should be denoted by both daughter indices of the original parton
+pointing to the copy, and both mother indices of the copy to the
+original. If the copy instead is intended to represent an earlier
+step, e.g. in ISR backwards evolution, the role of mothers and
+daughters is interchanged. The
+<code>event.copy( iCopy, newStatus)</code>
+routine can take care of this tedious task; the sign of
+<code>newStatus</code> tells the program which case to assume.
+
+<p/>
+To make the event record legible it is essential that the
+<aloc href="ParticleProperties">status codes</aloc>
+are selected appropriately to represent the reason why each new
+parton is added to the record. Also remember to change the
+status of a parton to be negative whenever an existing parton
+is replaced by a set of new daughter partons.
+
+<p/>
+Another important parton property is <code>scale()</code>,
+which does not appear in the normal event listing, but only
+if you use the extended
+<code>Event:listScaleAndVertex = on</code> option.
+This property is supposed to represent the production scale
+(in GeV) of a parton. In the current FSR and ISR algorithms
+it is used to restrict from above the allowed <ei>pT</ei>
+values for branchings of this particular parton.
+Beam remnants and other partons that should not radiate are
+assigned scale 0.
+
+<h3>The subsystems</h3>
+
+One aspect that complicates administration is that an event
+can contain several subsystems, consisting of one MI and its
+associated ISR and FSR, which to first approximation are assumed
+to evolve independently, but to second are connected by the
+interleaved evolution. The partons of a given subsystem
+therefore do not have to be stored consecutively. Some simple
+vectors put inside the event record can be used to keep track of
+the current position, i.e. index <code>iPos</code> for parton
+<code>event[iPos]</code>, of all partons of all systems.
+
+<p/>
+The number of systems is given by <code>sizeSystems()</code>,
+with systems numbered 0 through <code>sizeSystems() - 1</code>.
+The size of a given subsystem <code>iSys</code> is given by
+<code>sizeSystem(iSys)</code>, with analogous numbering.
+The method <code>getInSystem( iSys, iMem)</code> returns the
+position <code>iPos</code> of the <code>iMem</code>'th member of
+the <code>iSys</code>'th system. For each system, the slots
+<code>iMem =</code> 0 and 1 are intended for the incoming partons
+from beam A and B, respectively. If there are no beams, such as
+in resonance decays, these should be assigned value 0.
+Slots 2 onwards are intended for all the outgoing partons. These
+latter partons are not guaranteed to appear in any particular order.
+
+<p/>
+New systems are created from the hard process and by the MI,
+not from any of the other components, by the <code>newSystem()</code>
+method, which returns the <code>iSys</code> code of the new system.
+Both FSR and ISR modify the position of partons, however.
+Since an FSR or ISR branching typically implies a new state with
+one more parton than before, the method
+<code>addToSystem( iSys, iPos)</code> appends a new slot to the
+given system and stores the <code>iPos</code> value there. Furthermore,
+in a branching, several existing partons may also be moved to new
+slots. The method <code>setInSystem( iSys, iMem, iPos)</code>
+replaces the current <code>iPos</code> value in the given slot
+by the provided one. If you do not know the <code>iMem</code> value,
+<code>replaceInSystem( iSys, iPosOld, iPosNew)</code>
+will replace any ocurence of <code>iPosOld</code> by
+<code>iPosNew</code> wherever it is found in the
+<code>iSys</code>'th system. In a FSR <ei>1 -> 2</ei> branching
+it is irrelevant which parton position you let overwrite the
+existing slot and which is added to the end of the system.
+
+<p/>
+Finally, <code>clearSystems()</code> empties the information, and
+<code>listSystems()</code> provides a simple listing of all the
+<code>iPos</code> values by system, intended for debugging purposes only.
+
+<p/>
+The system information must be kept up-to-date. The MI component only
+writes, but both ISR, FSR and BR make extensive use of the existing
+information. As an example, the introduction of primordial <ei>kT</ei>
+in the beam remnants will fail if the information on which
+final-state partons belong to which system is out-of-date.
+
+<p/>
+Currently the system information is kept throughout the continued
+history of the event. Resonance decays create new systems, appended
+to the existing ones. This could be useful during the hadronization
+stage, to collect the partons that belong to a resonace with
+preserved mass when a small string collapses to one particle,
+but is not yet used for that.
+
+<h3>The beams</h3>
+
+The different subsystems are tied together by them sharing the same
+initial beam particles, and thereby being restricted by energy-momentum
+and flavour conservation issues. The information stored in the two
+beam particles, here called <code>beamA</code> and <code>beamB</code>,
+is therefore as crucial to keep correct as the above subsystem list.
+
+<p/>
+Both beam objects are of the <code>BeamParticle</code> class.
+Each such object contains a vector with the partons extracted from it.
+The number of such partons, <code>beamX.size()</code> (X = A or B),
+of course is the same as the above number of subsystems in the event
+record. (The two diverge at the BR step, where further beam remnants
+are added to the beams without corresponding to new subsystems.)
+The individual partons are accessed by an overloaded indexing
+operator to a vector of <code>ResolvedParton</code> objects. The
+<code>iPos()</code> property corresponds to the <code>iPos</code>
+one above, i.e. providing the position in the main event record of
+a parton. In particular,
+<code>beamA[iSys].iPos() = event.getInSystem( iSys, 0)</code> and
+<code>beamB[iSys].iPos() = event.getInSystem( iSys, 1)</code>.
+Whereas thus the indices of the two incoming partons to a subsystem
+are stored in two places, the ones of the outgoing partons only
+appear in the system part of the <code>Event</code> class.
+
+<p/>
+Just as the subsystems in <code>Event</code> must be updated, so must
+the information in the two <code>BeamParticle</code>'s, e.g. with methods
+<code>beamX[iSys].iPos( iPosIn)</code> when an incoming parton is
+replaced by a new one in line <code>iPosIn</code>. Furthermore the new
+parton identity should be set by <code>beamX[iSys].id( idIn)</code>
+and the new <ei>x</ei> energy-momentum fraction by
+<code>beamX[iSys].x( xIn)</code>. The three can be combined in one go
+by <code>beamX[iSys].update( iPosIn, idIn, xIn)</code>.
+
+<p/>
+To be specific, it is assumed that, at each step, the two incoming
+partons are moving along the <ei>+-z</ei> axis and are massless.
+Since the event is constructed in the c.m. frame of the incoming
+beams this implies that <ei>x = 2 E / E_cm</ei>.
+If the <ei>x</ei> values are not defined accordingly or not kept
+up-to-date the BR treatment will not conserve energy-momentum.
+
+<p/>
+In return, the <code>BeamParticle</code> objects give access to some
+useful methods. The <code>beamX.xf( id, x, Q2)</code> returns the
+standard PDF weight <ei>x f_id(x, Q^2)</ei>. More intererstingly,
+<code>beamX.xfISR( iSys, id, x, Q2)</code> returns the modified weight
+required when several subsystems have to share the energy and flavours.
+Thus <code>iSys</code> is added as an extra argument, and the momentum
+already assigned to the other subsystems is not available for evolution,
+i.e. the maximal <ei>x</ei> is correspondingly smaller than unity.
+Also flavour issues are handled in a similar spirit.
+
+<p/>
+An additional complication is that a parton can be either valence or
+sea, and in the latter case the BR treatment also distinguishes
+companion quarks, i.e. quark-antiquark pairs that are assumed to
+come from the same original <ei>g -> q qbar</ei> branching, whether
+perturbative or not. This can be queried either with the
+<code>beamX[iSys].companion()</code> method, for detailed information,
+or with the <code>beamX[iSys].isValence()</code>,
+<code>beamX[iSys].isUnmatched()</code> and
+<code>beamX[iSys].isCompanion()</code> metods for yes/no answers
+whether a parton is valence, unmatched sea or matched sea.
+This choice should affect the ISR evolution; e.g., a valence quark
+cannot be constructed back to come from a gluon.
+
+<p/>
+To keep this info up-to-date, the <code>beamX.pickValSeaComp()</code>
+method should be called whenever a parton of a new flavour has been
+picked in the ISR backwards evolution, but not if the flavour has not
+been changed, since then one should not be allowed to switch back and
+forth between the same quark being considered as valence or as sea.
+Since the <code>pickValSeaComp()</code> method makes use of the
+current parton-density values, it should be preceded by a call
+to <code>beamX.xfISR( iSys, id, x, Q2)</code>, where the values in
+the call are the now finally accepted ones for the newly-found mother.
+(Such a call is likely to have been made before, during the evolution,
+but is not likely to be the most recent one, i.e. still in memory, and
+therefore had better be redone.)
+
+<p/>
+Most of the issues in this section are related to the ISR algorithm,
+i.e. it is possible to write an FSR algorithm that is completely
+decoupled. Alternatively the FSR may change the position where an
+incoming parton is stored, or its assumed momentum, e.g. by recoil
+effects inside dipoles stretched from the scattered back to the
+incoming partons. In that case some of the methods above would have
+to be used also inside the FSR algorithm.
+
+<h3>The TimeShower interface</h3>
+
+If you want to replace the <code>TimeShower</code> class this would
+involve replacing the following methods.
+
+<method name="TimeShower()">
+The constructor does not need to do anything.
+</method>
+
+<method name="void init( BeamParticle* beamAPtrIn = 0,
+BeamParticle* beamBPtrIn = 0)">
+You have to store your local copy of the pointers to these objects,
+since they have to be used during the generation, as explained above.
+The pointers could be zero; e.g. a local copy of <code>TimeShower</code>
+is created to handle showers in decays such as <ei>Upsilon -> q qbar</ei>
+from inside the <code>ParticleDecays class</code>. This is also the
+place to do initialization of whatever parameters you plan to use,
+e.g. by reading in them from a user-accessible database like the
+<code>Settings</code> one.
+</method>
+
+<method name="double enhancePTmax()">
+Relative to the default <ei>pT_max</ei> evolution scale of the process,
+it may still be convenient to vary the matching slightly for the hardest
+interaction in an event, to probe the sensitivity to such details. The
+base-class implementation returns the value of the
+<code>TimeShower:pTmaxFudge</code> parameter.
+</method>
+
+<method name="int shower( int iBeg, int iEnd, Event& event, double pTmax)">
+This is an all-in-one call for shower evolution, and as such cannot be
+used for the normal interleaved evolution, where only the routines below
+are used. It also cannot be used in resonance decays that form part of
+the hard process, since there the
+<aloc href="UserHooks">user hooks</aloc> insert a potential
+veto step. Currently this routine is therefore only used in the
+hadron-level decays, e.g. <ei>Upsilon -> g g g</ei>.
+<br/><code>iBeg</code> and <code>iEnd</code> is the position of the
+first and last parton of a separate system, typically produced by a
+resonance decay. Such a system only evolves in isolation, and in
+particular does not relate to the beams.
+<br/>The <code>pTmax</code> value sets the maximum scale for evolution,
+but normally you would restrict that further for each individual
+parton based on its respective scale value.
+<br/>The routine is expected to return the number of FSR branchings that
+were generated, but only for non-critical statistics purposes.
+<br/>Since the real action typically is delegated to the routines
+below, it may well be that the existing code need not be replaced.
+</method>
+
+<method name="void prepare( int iSys, Event& event)">
+This method is called immediately after a new interaction (or the
+products of a resonance decay) has been added, and should then be used
+to prepare the subsystem of partons for subsequent evolution. In
+the current code this involves identifying all colour and charge
+dipole ends: the position of radiating and recoiling partons, maximum
+<ei>pT</ei> scales, possible higher-order matrix elements matchings
+to apply, and so on.
+<br/>The <code>iSys</code> parameter specifies which parton system
+is to be prepared. It is used to extract the set of partons to be
+treated, with rules as described in the above section on subsystems.
+Specifically, the first two partons represent the incoming state,
+or are 0 for resonance decays unrelated to the beams, while the
+rest are not required to be in any particular order.
+</method>
+
+<method name="void update( int iSys, Event& event)">
+This method is called immediately after a spacelike branching in the
+<code>iSys</code>'th subsystem. Thus the information for that system is
+out-of-date, while that of the others is unchanged. If you want, you are
+free to throw away all information for the affected subsystem and call
+<code>prepare( iSys, event)</code> to create new one. Alternatively
+you may choose only to update the information that has changed.
+</method>
+
+<method name="double pTnext( Event& event, double pTbegAll,
+double pTendAll)">
+This is the main driver routine for the downwards evolution. A new
+<ei>pT</ei> is to be selected based on the current information set up
+by the routines above, and along with that a branching parton or dipole.
+The <code>pTbegAll</code> scale is the maximum scale allowed, from which
+the downwards evolution should be begun (usually respecting the maximum
+scale of each individual parton). If no emission is found above
+<code>pTendAll</code> (and above the respective shower cutoff scales)
+then <code>0.</code> should be returned and no emissions will be allowed.
+Both scales can vary from one event to the next: if a scale has
+already been selected for MI or ISR it makes no sense to look for
+a scale smaller than that from FSR, since it would not be able to
+compete, so <code>pTendAll</code> is set correspondingly. As it happens,
+FSR is tried before ISR and MI in the interleaved evolution,
+but this is an implementational detail that could well change.
+<br/>Typically the implementation of this routine would be to set
+up a loop over all possible radiating objects (dipoles, dipole ends, ...),
+for each pick its possible branching scale and then pick the one
+with largest scale as possible winner. At this stage no branching should
+actually be carried out, since MI, ISR and FSR still have to be compared
+to assign the winner.
+</method>
+
+<method name="bool branch( Event& event)">
+This method will be called once FSR has won the competition with
+MI and ISR to do the next branching. The candidate branching found
+in the previous step should here be carried out in full. The
+pre-branching partons should get a negative status code and new
+replacement ones added to the end of the event record. Also the
+subsystem information should be updated, and possibly also the
+beams.
+<br/>Should some problem be encountered in this procedure, e.g. if
+some not-previously-considered kinematics requirement fails, it is
+allowed to return <code>false</code> to indicate that no branching
+could be carried out.
+</method>
+
+<method name="int system()">
+This method is not virtual. If a branching is constructed by the
+previous routine this tiny method should be able to return the number
+of the selected subsystem <code>iSysSel</code> where it occured,
+so that the spacelike shower can be told which system to update,
+if necessary. Therefore <code>iSysSel</code> must be set in
+<code>branch</code> (or already in <code>pTnext</code>).
+</method>
+
+<method name="void list( ostream& os = cout)">
+This method is not at all required. In the current implementation it
+outputs a list of all the dipole ends, with information on the
+respective dipole. The routine is not called anywhere in the public
+code, but has been inserted at various places during the
+development/debug phase.
+</method>
+
+<h3>The SpaceShower interface</h3>
+
+If you want to replace the <code>SpaceShower</code> class this would
+involve replacing the following methods. You will find that much of
+the story reminds of <code>TimeShower</code> above, and actually some
+cut-and-paste of text is involved. In some respects the description
+is simpler, since there are no special cases for resonance decays
+and non-interleaved evolution. Thus there is no correspondence to the
+<code>TimeShower::shower(...)</code> routine.
+
+<method name="SpaceShower()">
+The constructor does not need to do anything.
+</method>
+
+<method name="void init( BeamParticle* beamAPtrIn,
+BeamParticle* beamBPtrIn)">
+You have to store your local copy of the pointers to these objects,
+since they have to be used during the generation, as explained above.
+This is also the place to do initialization of whatever parameters
+you plan to use, e.g. by reading in them from a user-accessible
+database like the <code>Settings</code> one.
+</method>
+
+<method name="bool limitPTmax( Event& event, double Q2Fac = 0.,
+double Q2Ren = 0.)">
+The question is whether the ISR should be allowed to occur at larger
+scales than the hard process it surrounds. This is process-dependent.
+For instance, if the hard process is <ei>Z^0</ei> production we know
+that ISR should be allowed to go right up to the kinematical limit.
+If it is a <ei>2 -> 2</ei> QCD process the ISR should not exceed
+the scale of the hard process, since if so one would doublecount.
+The <code>SpaceShower:pTmaxMatch</code> switch allows you to force the
+behaviour, or else to program your own logic. The current implementation
+limits <ei>pT</ei> whenever the final state contains a quark (except top),
+gluon or photon, since then the danger of doublecounting is there.
+You may replace by your own logic, or leave as is.
+<br/>The internal PYTHIA implementation also allows intermediate options,
+where emissions can go up to the kinematical limit but be dampened above
+the factorization or renormalization scale. Therefore the (square of the)
+latter two are provided as optional input parameters.
+</method>
+
+<method name="double enhancePTmax()">
+When the above method limits <ei>pT_max</ei> to the scale of the process,
+it may still be convenient to vary the matching slightly for the hardest
+interaction in an event, to probe the sensitivity to such details. The
+base-class implementation returns the value of the
+<code>SpaceShower:pTmaxFudge</code> parameter.
+</method>
+
+<method name="void prepare( int iSys, Event& event,
+bool limitPTmax = true)">
+This method is called immediately after a new interaction has been
+added, and should then be used to prepare the subsystem of partons
+for subsequent evolution. In the current code this involves identifying
+the colour and charge dipole ends: the position of radiating and recoiling
+partons, maximum <ei>pT</ei> scales, and possible higher-order matrix
+elements matchings to apply. Depending on what you have in mind you may
+choose to store slightly different quantities. You have to use the
+subsystem information described above to find the positions of the two
+incoming partons (and the outgoing ones) of the system, and from there
+the scales at which they were produced.
+<br/> The <code>limitPTmax</code> input agrees with the output of the
+previous method for the hardest process, and is always true for
+subsequent MI, since there an unlimited <ei>pT</ei> for sure
+would lead to doublecounting.
+</method>
+
+<method name="void update( int iSys, Event& event)">
+This method is called immediately after a timelike branching in the
+<code>iSys</code>'th subsystem. Thus the information for that system may
+be out-of-date, and to be updated. For the standard PYTHIA showers
+this routine does not need to do anything, but that may be different
+in another implementation.
+</method>
+
+<method name="double pTnext(( Event& event, double pTbegAll,
+double pTendAll, int nRadIn = -1)">
+This is the main driver routine for the downwards evolution. A new
+<ei>pT</ei> is to be selected based on the current information set up
+by the routines above, and along with that a branching parton or dipole.
+The <code>pTbegAll</code> scale is the maximum scale allowed, from which
+the downwards evolution should be begun (usually respecting the maximum
+scale of each individual parton). If no emission is found above
+<code>pTendAll</code> (and above the respective shower cutoff scales)
+then <code>0.</code> should be returned and no emissions will be allowed.
+Both scales can vary from one event to the next: if a scale has
+already been selected for MI or ISR it makes no sense to look for
+a scale smaller than that from FSR, since it would not be able to
+compete, so <code>pTendAll</code> is set correspondingly. As it happens,
+FSR is tried before ISR and MI in the interleaved evolution,
+but this is an implementational detail that could well change.
+<br/>Typically the implementation of this routine would be to set
+up a loop over all possible radiating objects (dipoles, dipole ends, ...),
+for each pick its possible branching scale and then pick the one
+with largest scale as possible winner. At this stage no branching should
+actually be carried out, since MI, ISR and FSR still have to be compared
+to assign the winner.
+<br/>The final input <code>nRadIn</code> provides the total number of
+ISR and FSR emissions already generated in the event, and so allows a
+special treatment for the very first emission, if desired.
+</method>
+
+<method name="bool branch( Event& event)">
+This method will be called once FSR has won the competition with
+MI and ISR to do the next branching. The candidate branching found
+in the previous step should here be carried out in full. The
+pre-branching partons should get a negative status code and new
+replacement ones added to the end of the event record. Also the
+subsystem information should be updated, and possibly also the
+beams.
+<br/>Should some problem be encountered in this procedure, e.g. if
+some not-previously-considered kinematics requirement fails, it is
+allowed to return <code>false</code> to indicate that no branching
+could be carried out.
+</method>
+
+<method name="int system()">
+This method is not virtual. If a branching is constructed by the
+previous routine this tiny method should be able to return the number
+of the selected subsystem <code>iSysSel</code> where it occured,
+so that the spacelike shower can be told which system to update,
+if necessary. Therefore <code>iSysSel</code> must be set in
+<code>branch</code> (or already in <code>pTnext</code>).
+</method>
+
+<method name="void list( ostream& os = cout)">
+This method is not at all required. In the current implementation it
+outputs a list of all the dipole ends, with information on the
+respective dipole. The routine is not called anywhere in the public
+code, but has been inserted at various places during the
+development/debug phase.
+</method>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Index">
+
+<img src='pythia99.gif' alt='Pythia logo' hspace=10/>
+
+<h2>PYTHIA 8 Index</h2>
+
+<h4><a href="pythia8100.pdf" target="page">Brief Introduction</a> (pdf)</h4>
+
+<h4>Program Overview</h4>
+
+<aidx href="Frontpage">Frontpage</aidx><br/>
+<aidx href="ProgramFlow">Program Flow</aidx><br/>
+<aidx href="SettingsScheme">Settings Scheme</aidx><br/>
+<aidx href="ParticleDataScheme">Particle Data Scheme</aidx><br/>
+<aidx href="ProgramFiles">Program Files</aidx><br/>
+<aidx href="SampleMainPrograms">Sample Main Programs</aidx><br/>
+
+<h4>Setup Run Tasks</h4>
+
+<INDEXPHP>
+<aidx href="SaveSettings"><b>Save Settings</b></aidx><br/>
+<aidx href="MainProgramSettings">Main-Program Settings</aidx><br/>
+<aidx href="BeamParameters">Beam Parameters</aidx><br/>
+<aidx href="RandomNumberSeed">Random-Number Seed</aidx><br/>
+<aidx href="PDFSelection">PDF Selection</aidx><br/>
+<aidx href="MasterSwitches">Master Switches</aidx><br/>
+<aidx href="ProcessSelection">Process Selection</aidx><br/>
+ --
+<aidx href="QCDProcesses">QCD</aidx><br/>
+ --
+<aidx href="ElectroweakProcesses">Electroweak</aidx><br/>
+ --
+<aidx href="OniaProcesses">Onia</aidx><br/>
+ --
+<aidx href="TopProcesses">Top</aidx><br/>
+ --
+<aidx href="FourthGenerationProcesses">Fourth Generation</aidx><br/>
+ --
+<aidx href="HiggsProcesses">Higgs</aidx><br/>
+ --
+<aidx href="SUSYProcesses">SUSY</aidx><br/>
+ --
+<aidx href="NewGaugeBosonProcesses">New Gauge Bosons</aidx><br/>
+ --
+<aidx href="LeftRightSymmetryProcesses">Left-Right Symmetry</aidx><br/>
+ --
+<aidx href="LeptoquarkProcesses">Leptoquark</aidx><br/>
+ --
+<aidx href="CompositenessProcesses">Compositeness</aidx><br/>
+ --
+<aidx href="ExtraDimensionalProcesses">Extra Dimensions</aidx><br/>
+<aidx href="ASecondHardProcess">A Second Hard Process</aidx><br/>
+<aidx href="PhaseSpaceCuts">Phase Space Cuts</aidx><br/>
+<aidx href="CouplingsAndScales">Couplings and Scales</aidx><br/>
+<aidx href="StandardModelParameters">Standard-Model Parameters</aidx><br/>
+<aidx href="TotalCrossSections">Total Cross Sections</aidx><br/>
+<aidx href="ResonanceDecays">Resonance Decays</aidx><br/>
+<aidx href="TimelikeShowers">Timelike Showers</aidx><br/>
+<aidx href="SpacelikeShowers">Spacelike Showers</aidx><br/>
+<aidx href="MultipleInteractions">Multiple Interactions</aidx><br/>
+<aidx href="BeamRemnants">Beam Remnants</aidx><br/>
+<aidx href="Fragmentation">Fragmentation</aidx><br/>
+<aidx href="FlavourSelection">Flavour Selection</aidx><br/>
+<aidx href="ParticleDecays">Particle Decays</aidx><br/>
+<aidx href="BoseEinsteinEffects">Bose-Einstein Effects</aidx><br/>
+<aidx href="ParticleData">Particle Data</aidx><br/>
+<aidx href="ErrorChecks">Error Checks</aidx><br/>
+<aidx href="Tunes">Tunes</aidx><br/>
+</INDEXPHP>
+
+<h4>Study Output</h4>
+
+<INDEXPHP>
+<aidx href="FourVectors">Four-Vectors</aidx><br/>
+<aidx href="ParticleProperties">Particle Properties</aidx><br/>
+<aidx href="EventRecord">Event Record</aidx><br/>
+<aidx href="EventInformation">Event Information</aidx><br/>
+<aidx href="EventStatistics">Event Statistics</aidx><br/>
+<aidx href="Histograms">Histograms</aidx><br/>
+<aidx href="EventAnalysis">Event Analysis</aidx><br/>
+<aidx href="HepMCInterface">HepMC Interface</aidx><br/>
+</INDEXPHP>
+
+<h4>Link to Other Programs</h4>
+
+<INDEXPHP>
+<aidx href="LesHouchesAccord">Les Houches Accord</aidx><br/>
+<aidx href="AccessPYTHIA6Processes">Access PYTHIA 6 Processes</aidx><br/>
+<aidx href="SemiInternalProcesses">Semi-Internal Processes</aidx><br/>
+<aidx href="SemiInternalResonances">Semi-Internal Resonances</aidx><br/>
+<aidx href="HadronLevelStandalone">Hadron-Level Standalone</aidx><br/>
+<aidx href="SUSYLesHouchesAccord">SUSY Les Houches Accord</aidx><br/>
+<aidx href="BeamShape">Beam Shape</aidx><br/>
+<aidx href="PartonDistributions">Parton Distributions</aidx><br/>
+<aidx href="ExternalDecays">External Decays</aidx><br/>
+<aidx href="UserHooks">User Hooks</aidx><br/>
+<aidx href="RandomNumbers">Random Numbers</aidx><br/>
+<aidx href="ImplementNewShowers">Implement New Showers</aidx><br/>
+</INDEXPHP>
+
+<h4>Reference Materiel</h4>
+
+<aidx href="PYTHIA6TranslationTable">PYTHIA 6 Translation Table</aidx><br/>
+<aidx href="UpdateHistory">Update History</aidx><br/>
+<aidx href="Bibliography">Bibliography</aidx><br/>
+<aidx href="Glossary">Glossary</aidx><br/>
+<aidx href="Version">Version</aidx>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Left-Right-Symmetry Processes">
+
+<h2>Left-Right-Symmetry Processes</h2>
+
+At current energies, the world is left-handed, i.e. the Standard Model
+contains an <ei>SU(2)_L</ei> group. Left-right symmetry at some larger
+scale implies the need for an <ei>SU(2)_R</ei> group. Thus the particle
+content is expanded by right-handed <ei>Z_R^0</ei> and <ei>W_R^+-</ei>
+and right-handed neutrinos. The Higgs fields have to be in a triplet
+representation, leading to doubly-charged Higgs particles, one set for
+each of the two <ei>SU(2)</ei> groups. Also the number of neutral and
+singly-charged Higgs states is increased relative to the Standard Model,
+but a search for the lowest-lying states of this kind is no different
+from e.g. the freedom already accorded by the MSSM Higgs scenarios.
+
+<p/>
+PYTHIA implements the scenario of <ref>Hui97</ref>.
+
+<p/>
+The <ei>W_R^+-</ei> has been implemented as a simple copy of the
+ordinary <ei>W^+-</ei>, with the exception that it couples to
+right-handed neutrinos instead of the ordinary left-handed ones.
+Thus the standard CKM matrix is used in the quark sector, and the
+same vector and axial coupling strengths, leaving only the mass as
+free parameter. The <ei>Z_R^0</ei> implementation (without interference
+with the photon or the ordinary <ei>Z^0</ei>) allows decays both to
+left- and right-handed neutrinos, as well as other fermions, according
+to one specific model ansatz. Obviously both the <ei>W_R^+-</ei>
+and the <ei>Z_R^0</ei> descriptions are likely to be simplifications,
+but provide a starting point.
+
+<p/>
+For the doubly-charged Higgses, the main decay modes implemented are
+<ei>H_L^++ -> W_L^+ W_L^+, l_i^+ l_j^+ </ei> (<ei>i, j</ei> generation
+indices) and <ei>H_R^++ -> W_R^+ W_R^+, l_i^+ l_j^+</ei>.
+
+<p/>
+The right-handed neutrinos can be allowed to decay further. Assuming them
+to have a mass below that of <ei>W_R^+-</ei>, they decay to three-body
+states via a virtual <ei>W_R^+-</ei>, <ei>nu_Rl -> l+- f fbar'</ei>,
+where both lepton charges are allowed owing to the Majorana character
+of the neutrinos. If there is a significant mass splitting, also
+sequential decays <ei>nu_Rl -> l+- l'-+ nu'_Rl</ei> are allowed.
+Currently the decays are isotropic in phase space. If the neutrino
+masses are close to or above the <ei>W_R^</ei> ones, this description
+has to be substituted by a sequential decay via a real <ei>W_R^</ei>
+(not implemented, but actually simpler to do than the one here).
+
+
+<h3>Production processes</h3>
+
+A few different production processes have been implemented, which normally
+would not overlap and therefore could be run together.
+
+<flag name="LeftRightSymmmetry:all" default="off">
+Common switch for the group of implemented processes within a
+left-right-symmetric scenario.
+</flag>
+
+<flag name="LeftRightSymmmetry:ffbar2ZR" default="off">
+Scatterings <ei>f fbar -> Z_R^0</ei>.
+Code 3101.
+</flag>
+
+<flag name="LeftRightSymmmetry:ffbar2WR" default="off">
+Scatterings <ei><f fbar' -> W_R^+</ei>.
+Code 3102.
+</flag>
+
+<flag name="LeftRightSymmmetry:ll2HL" default="off">
+Scatterings <ei>l_i l_j -> H_L^--</ei>.
+Code 3121.
+</flag>
+
+<flag name="LeftRightSymmmetry:lgm2HLe" default="off">
+Scatterings <ei>l_i gamma -> H_L^-- e^+</ei>.
+Code 3122.
+</flag>
+
+<flag name="LeftRightSymmmetry:lgm2HLmu" default="off">
+Scatterings <ei>l_i gamma -> H_L^-- mu^+</ei>.
+Code 3123.
+</flag>
+
+<flag name="LeftRightSymmmetry:lgm2HLtau" default="off">
+Scatterings <ei>l_i gamma -> H_L^-- tau^+</ei>.
+Code 3124.
+</flag>
+
+<flag name="LeftRightSymmmetry:ff2HLff" default="off">
+Scatterings <ei>f_1 f_2 -> H_L^-- f_3 f_4</ei> via <ei>WW</ei> fusion.
+Code 3125.
+</flag>
+
+<flag name="LeftRightSymmmetry:ffbar2HLHL" default="off">
+Scatterings <ei>f fbar -> H_L^++ H_L^--</ei>.
+Code 3126.
+</flag>
+
+<flag name="LeftRightSymmmetry:ll2HR" default="off">
+Scatterings <ei>l_i l_j -> H_R^--</ei>.
+Code 3141.
+</flag>
+
+<flag name="LeftRightSymmmetry:lgm2HRe" default="off">
+Scatterings <ei>l_i gamma -> H_R^-- e^+</ei>.
+Code 3142.
+</flag>
+
+<flag name="LeftRightSymmmetry:lgm2HRmu" default="off">
+Scatterings <ei>l_i gamma -> H_R^-- mu^+</ei>.
+Code 3143.
+</flag>
+
+<flag name="LeftRightSymmmetry:lgm2HRtau" default="off">
+Scatterings <ei>l_i gamma -> H_R^-- tau^+</ei>.
+Code 3144.
+</flag>
+
+<flag name="LeftRightSymmmetry:ff2HRff" default="off">
+Scatterings <ei>f_1 f_2 -> H_R^-- f_3 f_4</ei> via <ei>WW</ei> fusion.
+Code 3145.
+</flag>
+
+<flag name="LeftRightSymmmetry:ffbar2HRHR" default="off">
+Scatterings <ei>f fbar -> H_R^++ H_L^--</ei>.
+Code 3146.
+</flag>
+
+<h3>Parameters</h3>
+
+The basic couplings of the model are
+
+<parm name="LeftRightSymmmetry:gL" default="0.64" min="0.0">
+lefthanded coupling <ei>g_L = e / sin(theta)</ei>.
+</parm>
+
+<parm name="LeftRightSymmmetry:gR" default="0.64" min="0.0">
+righthanded coupling <ei>g_R</ei>, assumed the same as <ei>g_L</ei>.
+</parm>
+
+<parm name="LeftRightSymmmetry:vL" default="5." min="0.0">
+vacuum expectation value <ei>v_L</ei> (in GeV) for the left-triplet.
+</parm>
+
+<p/>
+The corresponding vacuum expectation value <ei>v_R</ei> is assumed
+given by <ei>v_R = sqrt(2) M_WR / g_R</ei> and is not stored explicitly.
+
+<p/>
+The Yukawa couplings of a lepton pair to a <ei>H^--</ei>, assumed the
+same for <ei>H_L^--</ei> and <ei>H_R^--</ei>, is described by a symmetric
+3-by-3 matrix. The default matrix is dominated by the diagonal elements
+and especially by the <ei>tau tau</ei> one.
+
+<parm name="LeftRightSymmmetry:coupHee" default="0.1" min="0.0">
+Yukawa coupling for <ei>H^-- -> e- e-</ei>.
+</parm>
+
+<parm name="LeftRightSymmmetry:coupHmue" default="0.01" min="0.0">
+Yukawa coupling for <ei>H^-- -> mu- e-</ei>.
+</parm>
+
+<parm name="LeftRightSymmmetry:coupHmumu" default="0.1" min="0.0">
+Yukawa coupling for <ei>H^-- -> mu- mu-</ei>.
+</parm>
+
+<parm name="LeftRightSymmmetry:coupHtaue" default="0.01" min="0.0">
+Yukawa coupling for <ei>H^-- -> tau- e-</ei>.
+</parm>
+
+<parm name="LeftRightSymmmetry:coupHtaumu" default="0.01" min="0.0">
+Yukawa coupling for <ei>H^-- -> tau- mu-</ei>.
+</parm>
+
+<parm name="LeftRightSymmmetry:coupHtautau" default="0.3" min="0.0">
+Yukawa coupling for <ei>H^-- -> tau- tau-</ei>.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Leptoquark Processes">
+
+<h2>Leptoquark Processes</h2>
+
+Leptoquarks arise in many scenarios, and can have widely different
+characteristics, with respect to spin, isospin amd flavour.
+The current implentation in no sense attempts to exhaust these
+possibilities, but only to encode one of the simplest possibilities,
+with a single scalar leptoquark, denoted <ei>LQ</ei> and assigned PDG
+code 42. The leptoquark is assumed to carry specific quark
+and lepton quantum numbers, by default <ei>u</ei> quark plus electron.
+These flavour numbers are conserved, i.e. a process such as
+<ei>u e^- -> LQ -> d nu_e</ei> is not allowed.
+
+<p/>
+Although only one leptoquark is implemented, its flavours may be
+changed arbitrarily to study the different possibilities. The
+flavours of the leptoquark are defined by the quark and lepton
+flavours in the decay mode list. Therefore, to change from the
+current <ei>u e^-</ei> to <ei>c mu^+</ei>, say, you only need
+a line
+<br/><code>pythia.readString("42:0:products = 4 -13");</code>
+<br/>in your main program, or the equivalent in a command file.
+The former must always be a quark, while the latter could be a lepton
+or an antilepton; a charge-conjugate partner is automatically defined
+by the program. At initialization, the charge is recalculated as a
+function of the flavours defined; also the leptoquark name is redefined
+to be of the type <code>LQ_q,l</code>, where actual quark and lepton
+flavours are displayed.
+
+<p/>
+The leptoquark is likely to be fairly long-lived, in which case it
+could have time to fragment into a mesonic- or baryonic-type state, which
+would decay later on. Currently this posibility is not handled; therefore
+the leptoquark is always assumed to decay before fragmentation.
+For that reason the leptoquark can also not be put stable.
+
+<h3>Production processes</h3>
+
+Four production processes have been implemented, which normally would
+not overlap and therefore could be run together.
+
+<flag name="LeptoQuark:all" default="off">
+Common switch for the group of lowest-order <ei>LQ</ei> production
+processes, i.e. the four ones below.
+</flag>
+
+<flag name="LeptoQuark:ql2LQ" default="off">
+Scatterings <ei>q l -> LQ</ei>.
+Code 3201.
+</flag>
+
+<flag name="LeptoQuark:qg2LQl" default="off">
+Scatterings <ei>q g -> LQ l</ei>.
+Code 3202.
+</flag>
+
+<flag name="LeptoQuark:gg2LQLQbar" default="off">
+Scatterings <ei>g g -> LQ LQbar</ei>.
+Code 3203.
+</flag>
+
+<flag name="LeptoQuark:qqbar2LQLQbar" default="off">
+Scatterings <ei>q qbar -> LQ LQbar</ei>.
+Code 3204.
+</flag>
+
+<h3>Parameters</h3>
+
+In the above scenario the main free parameters are the leptoquark flavour
+content, set as already described, and the <ei>LQ</ei> mass, set as usual.
+In addition there is one further parameter.
+
+<parm name="LeptoQuark:kCoup" default="1.0" min="0.0">
+multiplicative factor in the <ei>LQ -> q l</ei> squared Yukawa coupling,
+and thereby in the <ei>LQ</ei> width and the <ei>q l -> LQ</ei> and
+other cross sections. Specifically, <ei>lambda^2/(4 pi) = k alpha_em</ei>,
+i.e. it corresponds to the $k$ factor of <ref>Hew88</ref>.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Les Houches Accord">
+
+<h2>Les Houches Accord</h2>
+
+The Les Houches Accord (LHA) for user processes <ref>Boo01</ref> is the
+standard way to input parton-level information from a
+matrix-elements-based generator into PYTHIA. The conventions for
+which information should be stored has been defined in a Fortran context,
+as two commonblocks. Here a C++ equivalent is defined, as a single class.
+
+<p/>
+The <code>LHAup</code> class is a base class, containing reading and
+printout functions, plus two pure virtual functions, one to set
+initialization information and one to set information on each new event.
+Derived classes have to provide these two virtual functions to do
+the actual work. The existing derived classes are for reading information
+from a Les Houches Event File (LHEF), from the respective Fortran
+commonblocks, or from PYTHIA 8 itself.
+
+<p/>
+Normally, pointers to objects of the derived classes should be handed in
+with the <aloc href="ProgramFlow"><code>pythia.init( LHAup*)</code></aloc>
+method. However, with the LHEF format a filename can replace the pointer,
+see below.
+
+<h3>Initialization</h3>
+
+The <code>LHAup</code> class stores information equivalent to the
+<code>/HEPRUP/</code> commonblock, as required to initialize the event
+generation chain. The main difference is that the vector container
+now allows a flexible number of subprocesses to be defined. For the
+rest, names have been modified, since the 6-character-limit does not
+apply, and variables have been regrouped for clarity, but nothing
+fundamental is changed.
+
+<p/>
+The pure virtual function <code>setInit()</code> has to be implemented in
+the derived class, to set relevant information when called. It should
+return <code>false</code> if it fails to set the info.
+
+<p/>
+Inside <code>setInit()</code>, such information can be set by the following
+methods:
+<method name="setBeamA( identity, energy, pdfGroup, pdfSet)">
+sets the properties of the first incoming beam (cf. the Fortran
+<code>IDBMUP(1), EBMUP(1), PDFGUP(1), PDFSUP(1)</code>), and similarly
+a <code>setBeamB</code> method exists. The parton distribution information
+defaults to zero. These numbers can be used to tell which PDF sets were
+used when the hard process was generated, while the normal
+<aloc href="PDFSelection">PDF Selection</aloc> is used for the further
+event generation in PYTHIA.
+</method>
+
+<method name="setStrategy( strategy)">
+sets the event weighting and cross section strategy. The default,
+provided in the class constructor, is 3, which is the natural value
+e.g. for an LHEF.
+<argument name="strategy">
+chosen strategy (cf. <code>IDWTUP</code>; see <ref>Sjo06</ref>
+section 9.9.1 for extensive comments).
+<argoption value="1"> events come with non-negative weight, given in units
+of pb, with an average that converges towards the cross section of the
+process. PYTHIA is in charge of the event mixing, i.e. for each new
+try decides which process should be generated, and then decides whether
+is should be kept, based on a comparison with <code>xMax</code>.
+Accepted events therefore have unit weight.</argoption>
+<argoption value="-1"> as option 1, except that cross sections can now be
+negative and events after unweighting have weight +-1. You can use
+<aloc href="EventInformation"><code>pythia.info.weight()</code></aloc>
+to find the weight of the current event. A correct event mixing requires
+that a process that can take both signs should be split in two, one limited
+to positive or zero and the other to negative or zero values, with
+<code>xMax</code> chosen appropriately for the two.</argoption>
+<argoption value="2"> events come with non-negative weight, in unspecified
+units, but such that <code>xMax</code> can be used to unweight the events
+to unit weight. Again PYTHIA is in charge of the event mixing.
+The total cross section of a process is stored in
+<code>xSec</code>.</argoption>
+<argoption value="-2"> as option 2, except that cross sections can now be
+negative and events after unweighting have weight +-1. As for option -1
+processes with indeterminate sign should be split in two.</argoption>
+<argoption value="3"> events come with unit weight, and are thus accepted
+as is. The total cross section of the process is stored in
+<code>xSec</code>.</argoption>
+<argoption value="-3"> as option 3, except that events now come with weight
++-1. Unlike options -1 and -2 processes with indeterminate sign need not be
+split in two, unless you intend to mix with internal PYTHIA processes
+(see below).</argoption>
+<argoption value="4"> events come with non-negative weight, given in units
+of pb, with an average that converges towards the cross section of the
+process, like for option 1. No attempt is made to unweight the events,
+however, but all are generated in full, and retain their original weight.
+For consistency with normal PYTHIA units, the weight stored in
+<code>pythia.info.weight()</code> has been converted to mb, however.
+</argoption>
+<argoption value="-4"> as option 4, except that events now can come
+either with positive or negative weights.</argoption>
+<note>Note 1</note>: if several processes have already been mixed and
+stored in a common event file, either LHEF or some private format, it
+would be problematical to read back events in a different order. Since it
+is then not feasible to let PYTHIA pick the next process type, strategies
++-1 and +-2 would not work. Instead strategy 3 would be the recommended
+choice, or -3 if negative-weight events are required.
+<note>Note 2</note>: it is possible to switch on internally implemented
+processes and have PYTHIA mix these with LHA ones according to their relative
+cross sections for strategies +-1, +-2 and 3. It does not work for strategy
+-3 unless the positive and negative sectors of the cross sections are in
+separate subprocesses (as must always be the case for -1 and -2), since
+otherwise the overall mixture of PYTHIA and LHA processes will be off.
+Mixing is not possible for strategies +-4, since the weighting procedure
+is not specified by the standard. (For instance, the intention may be to
+have events biased towards larger <ei>pT</ei> values in some particular
+functional form.)
+</argument>
+</method>
+
+<method name="addProcess( idProcess, xSec, xErr, xMax)">
+sets info on an allowed process (cf. <code>LPRUP, XSECUP, XERRUP,
+XMAXUP</code>).
+Each new call will append one more entry to the list of processes.
+The choice of strategy determines which quantities are mandatory:
+<code>xSec</code> for strategies +-2 and +-3,
+<code>xErr</code> never, and
+<code>xMax</code> for strategies +-1 and +-2.
+</method>
+
+<note>Note</note>: PYTHIA does not make active use of the (optional)
+<code>xErr</code> values, but calculates a statistical cross section
+error based on the spread of event-to-event weights. This should work
+fine for strategy options +-1, but not for the others. Specifically,
+for options +-2 and +-3 the weight spread may well vanish, and anyway
+is likely to be an underestimate of the true error. If the author of the
+LHA input information does provide error information you may use that -
+this information is displayed at initialization. If not, then a relative
+error decreasing like <ei>1/sqrt(n_acc)</ei>, where <ei>n_acc</ei>
+is the number of accepted events, should offer a reasonable estimate.
+
+<method name="setXSec( i, xSec)">
+update the <code>xSec</code> value of the <code>i</code>'th process
+added with <code>addProcess</code> method (i.e. <code>i</code> runs
+from 0 through <code>sizeProc() - 1</code>, see below).
+</method>
+
+<method name="setXErr( i, xErr)">
+update the <code>xErr</code> value of the <code>i</code>'th process
+added with <code>addProcess</code> method.
+</method>
+
+<method name="setXMax( i, xMax)">
+update the <code>xMax</code> value of the <code>i</code>'th process
+added with <code>addProcess</code> method.
+</method>
+
+<p/>
+Information is handed back by the following methods:
+<method name="idBeamA(), eBeamA(), pdfGroupBeamA(), pdfSetBeamA()">
+and similarly with <ei>A -> B</ei>, for the two beam particles.
+</method>
+<method name="strategy()">
+for the strategy choice.
+</method>
+<method name="sizeProc()">
+for the number of subprocesses.
+</method>
+<method name="idProcess(i), xSec(i), xErr(i), xMax(i)">
+for process <code>i</code> in the range <code>0 <= i <
+sizeProc()</code>.
+</method>
+
+<p/>
+The information can also be printed using the <code>listInit()</code>
+method, e.g. <code>LHAupObject->listInit()</code>.
+This is automatically done by the <code>pythia.init</code> call.
+
+<h3>Event input</h3>
+
+The <code>LHAup</code> class also stores information equivalent to the
+<code>/HEPEUP/</code> commonblock, as required to hand in the next
+parton-level configuration for complete event generation. The main
+difference is that the vector container now allows a flexible number
+of partons to be defined. For the rest, names have been modified,
+since the 6-character-limit does not apply, and variables have been
+regrouped for clarity, but nothing fundamental is changed.
+
+<p/>
+The LHA standard is based on Fortran arrays beginning with
+index 1, and mother information is defined accordingly. In order to
+be compatible with this convention, the zeroth line of the C++ particle
+array is kept empty, so that index 1 also here corresponds to the first
+particle. One small incompatibility is that the <code>sizePart()</code>
+method returns the full size of the particle array, including the
+empty zeroth line, and thus is one larger than the true number of
+particles (<code>NUP</code>).
+
+<p/>
+The pure virtual function <code>setEvent(idProcess)</code> has to be
+implemented in the derived class, to set relevant information when
+called. For strategy options +-1 and +-2 the input
+<code>idProcess</code> value specifies which process that should be
+generated by <code>setEvent(idProcess)</code>, while
+<code>idProcess</code> is irrelevant for strategies +-3 and +-4.
+The <code>setEvent(idProcess)</code> function should return
+<code>false</code> if it fails to set the info, i.e. normally that the
+supply of events in a file is exhausted. If so, no event is generated,
+and <code>pythia.next()</code> returns <code>false</code>. You can then
+interrogate
+<aloc href="EventInformation"><code>pythia.info.atEndOfFile()</code></aloc>
+to confirm that indeed the failure is caused in the
+<code>setEvent(idProcess)</code> function, and decide to break out of
+the event generation loop.
+
+<p/>
+Inside a normal <code>setEvent(...)</code> call, information can be set
+by the following methods:
+<method name="setProcess( idProcess, weight, scale, alphaQED, alphaQCD)">
+tells which kind of process occured, with what weight, at what scale,
+and which <ei>alpha_EM</ei> and <ei>alpha_strong</ei> were used
+(cf. <code>IDPRUP, XWTGUP, SCALUP, AQEDUP, AQCDUP</code>). This method
+also resets the size of the particle list, and adds the empty zeroth
+line, so it has to be called before the <code>addParticle</code> method below.
+</method>
+<method name="addParticle( id, status, mother1, mother2, colourTag1,
+colourTag2, p_x, p_y, p_z, e, m, tau, spin)">
+gives the properties of the next particle handed in (cf. <code>IDUP, ISTUP,
+MOTHUP(1,..), MOTHUP(2,..), ICOLUP(1,..), ICOLUP(2,..), PUP(J,..),
+VTIMUP, SPINUP</code>) .
+</method>
+
+<p/>
+Information is handed back by the following methods:
+<method name="idProcess(), weight(), scale(), alphaQED(), alphaQCD()">.
+Note that the weight stored in <code>pythia.info.weight()</code> as a rule
+is not the same as the above <code>weight()</code>: the method here gives
+the value before unweighting while the one in <code>info</code> gives
+the one after unweighting and thus normally is 1 or -1. Only with strategy
+options +-3 and +-4 would the value in <code>info</code> be the same as
+here, except for a conversion from pb to mb for +-4.
+</method>
+<method name="sizePart()">
+for the size of the particle array, which is one larger than the number
+of particles in the event, since the zeroth entry is kept empty
+(see above). Thus a typical loop would be
+<br/><code>for (int i = 1; i < sizePart(); ++i) {...}</code>
+</method>
+<method name="id(i), status(i), mother1(i), mother2(i), col1(i), col2(i),
+px(i), py(i), pz(i), e(i), m(i), tau(i), spin(i)">
+for particle <code>i</code> in the range
+<code>0 <= i < size()</code>. (But again note that
+<code>i = 0</code> is an empty line, so the true range begins at 1.)
+</method>
+
+<p/>
+In the LHEF description <ref>Alw06</ref> an extension to
+include information on the parton densities of the colliding partons
+is suggested. This optional further information can be set by
+<method name="setPdf( id1, id2, x1, x2, scalePDF, xpdf1, xpdf2)">
+which gives the flavours , the <ei>x</ei> and the <ie>Q</ei> scale
+(in GeV) at which the parton densities <ei>x*f_i(x, Q)</ei> have been
+evaluated.
+</method>
+
+<p/>
+This information is returned by the methods
+<method name="pdfIsSet(), id1(), id2(), x1(), x2(), scalePDF(), xpdf1(), xpdf2()">
+where the first one tells whether this optional information has been set
+for the current event. (<code>setPdf(...)</code> must be called after the
+<code>setProcess(...)</code> call of the event for this to work.)
+</method>
+
+<p/>
+The information can also be printed using the <code>listEvent()</code>
+method, e.g. <code>LHAupObject->listEvent()</code>.
+In cases where the <code>LHAupObject</code> is not available to the
+user, the <code>pythia.LHAeventList()</code> method can be used, which
+is a wrapper for the above.
+
+<p/>
+The LHA expects the decay of resonances to be included as part of the
+hard process, i.e. if unstable particles are produced in a process then
+their decays are also described. This includes <ei>Z^0, W^+-, H^0</ei>
+and other short-lived particles in models beyond the Standard Model.
+Should this not be the case then PYTHIA will perform the decays of all
+resonances it knows how to do, in the same way as for internal processes.
+Note that you will be on slippery ground if you then restrict the decay of
+these resonances to specific allowed channels since, if this is not what
+was intended, you will obtain the wrong cross section and potentially the
+wrong mix of different event types. (Since the original intention is
+unknown, the cross section will not be corrected for the fraction of
+open channels, i.e. the procedure used for internal processes is not
+applied in this case.)
+
+<h3>An interface to Les Houches Event Files</h3>
+
+The LHEF standard <ref>Alw06</ref> specifies a format where a single file
+packs initialization and event information. This has become the most
+frequently used procedure to process external parton-level events in Pythia.
+Therefore a special
+<aloc href="ProgramFlow"><code>pythia.init(fileName)</code></aloc>
+initialization option exists, where the LHEF name is provided as input.
+Internally this name is then used to create an instance of the derived
+class <code>LHAupLHEF</code>, which can do the job of reading an LHEF.
+
+<p/>
+An example how to generate events from an LHEF is found in
+<code>main12.cc</code>. Note the use of
+<code>pythia.info.atEndOfFile()</code> to find out when the whole
+LHEF has been processed.
+
+<p/>
+To allow the sequential use of several event files the
+<code>init(...)</code> method has an optional second argument:
+<code>pythia.init(fileName, bool skipInit = false)</code>.
+If called with this argument <code>true</code> then there will be no
+initialization, except that the existing <code>LHAupLHEF</code> class
+instance will be deleted and replaced by ones pointing to the new file.
+It is assumed (but never checked) that the initialization information is
+identical, and that the new file simply contains further events of
+exactly the same kind as the previous one. An example of this possibility,
+and the option to mix with internal processes, is found in
+<code>main13.cc</code>.
+
+<h3>A runtime Fortran interface</h3>
+
+The runtime Fortran interface requires linking to an external Fortran
+code. In order to avoid problems with unresolved external references
+when this interface is not used, the code has been put in a separate
+<code>LHAFortran.h</code> file, that is not included in any of the
+other library files. Instead it should be included in the
+user-supplied main program, together with the implementation of two
+methods below that call the Fortran program to do its part of the job.
+
+<p/>
+The <code>LHAupFortran</code> class derives from <code>LHAup</code>.
+It reads initialization and event information from the LHA standard
+Fortran commonblocks, assuming these commonblocks behave like two
+<code>extern "C" struct</code> named <code>heprup_</code> and
+<code>hepeup_</code>. (Note the final underscore, to match how the
+gcc compiler internally names Fortran files.)
+
+<p/>
+The instantiation does not require any arguments.
+
+<p/>
+The user has to supply implementations of the <code>fillHepRup()</code>
+and <code>fillHepEup()</code> methods, that is to do the actual calling
+of the external Fortran routines that fill the <code>HEPRUP</code> and
+<code>HEPEUP</code> commonblocks. The translation of this information to
+the C++ structure is provided by the existing <code>setInit()</code> and
+<code>setEvent()</code> code.
+
+<p/>
+See further
+<aloc href="AccessPYTHIA6Processes">here</aloc> for information how
+PYTHIA 6.4 can be linked to make use of this facility.
+
+<h3>Methods for LHEF output</h3>
+
+The main objective of the <code>LHAup</code> class is to feed information
+from an external program into PYTHIA. It can be used to export information
+as well, however. Specifically, there are four routines in the base class
+that can be called to write a Les Houches Event File. These should be
+called in sequence in order to build up the proper file structure.
+
+<method name="openLHEF(string filename)">
+Opens a file with the filename indicated, and writes a header plus a brief
+comment with date and time information.
+</method>
+
+<method name="initLHEF()">
+Writes initialization information to the file above. Such information should
+already have been set with the methods described in the "Initialization"
+section above.
+</method>
+
+<method name="eventLHEF()">
+Writes event information to the file above. Such information should
+already have been set with the methods described in the "Event input"
+section above. This call should be repeated once for each event to be
+stored.
+</method>
+
+<method name="closeLHEF(bool updateInit = false)">
+Writes the closing tag and closes the file. Optionally, if
+<code>updateInit = true</code>, this routine will reopen the file from
+the beginning, rewrite the same header as <code>openLHEF()</code> did,
+and then call <code>initLHEF()</code> again to overwrite the old
+information. This is especially geared towards programs, such as PYTHIA
+itself, where the cross section information is not available at the
+beginning of the run, but only is obtained by Monte Carlo integration
+in parallel with the event generation itself. Then the
+<code>setXSec( i, xSec)</code>, <code>setXErr( i, xSec)</code> and
+<code>setXMax( i, xSec)</code> can be used to update the relevant
+information before <code>closeLHEF</code> is called.
+<note>Warning:</note> overwriting the beginning of a file without
+upsetting anything is a delicate operation. It only works when the new
+lines require exactly as much space as the old ones did. Thus, if you add
+another process in between, the file will be corrupted.
+</method>
+
+<h3>PYTHIA 8 output to an LHEF</h3>
+
+The above methods could be used by any program to write an LHEF.
+For PYTHIA 8 to do this, a derived class already exists,
+<code>LHAupFromPYTHIA8</code>. In order for it to do its job,
+it must gain access to the information produced by PYTHIA,
+specifically the <code>process</code> event record and the
+generic information stored in <code>info</code>. Therefore, if you
+are working with an instance <code>pythia</code> of the
+<code>Pythia</code> class, you have to instantiate
+<code>LHAupFromPYTHIA8<code> with pointers to the
+<code>process</code> and <code>info</code> objects of
+<code>pythia</code>:
+<br/>LHAupFromPYTHIA8 myLHA(&pythia.process, &pythia.info);
+
+<p/>
+The method <code>setInit()</code> should be called to store the
+<code>pythia</code> initialization information in the LHA object,
+and <code>setEvent()</code> to store event information.
+Furthermore, <code>updateSigma()</code> can be used at the end
+of the run to update cross-section information, cf.
+<code>closeLHEF(true)</code> above. An example how the
+generation, translation and writing methods should be ordered is
+found in <code>main20.cc</code>.
+
+<p/>
+Currently there are some limitations, that could be overcome if
+necessary. Firstly, you may mix many processes in the same run,
+but the cross-section information stored in <code>info</code> only
+refers to the sum of them all, and therefore they are all classified
+as a common process 9999. Secondly, you should generate your events
+in the CM frame of the collision, since this is the assumed frame of
+stored Les Houches events, and no boosts have been implemented
+for the case that <code>pythia.process</code> is not in this frame.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Main-Program Settings">
+
+<h2>Main-Program Settings</h2>
+
+<h3>Introduction</h3>
+
+The main program is up to the user to write. However,
+<aloc href="SampleMainPrograms">sample main programs</aloc>
+are provided. In one such class of programs, key settings of the run
+are read in from a "cards file". These commands may be of two types<br/>
+(a) instructions directly to <code>Pythia</code>, like which
+processes to generate, and<br/>
+(b) instructions to the main program for what it should do,
+like how many events to generate, i.e. how many times
+<code>pythia.next()</code> should be called.<br/>
+In principle these two kinds could be kept completely separate.
+However, to make life simpler, a number of useful main-program
+settings are defined on this page, so that they are recognized by
+the <code>Settings</code> machinery. They can thus be put among
+the other cards without distinction. It is up to you to decide which
+ones, if any, you actually want to use when you write your main program.
+For convenience, some in the second section below can also be interpreted
+directly by <code>Pythia</code>, while the subsequent ones really have
+to be used in your main program.
+
+<p/>
+Once you have used the <code>pythia.readFile(fileName)</code> method to
+read in the cards file, you can interrogate the <code>Settings</code>
+database to make the values available in your main program. A slight
+complication is that you need to use a different <code>Settings</code>
+method for each of the four possible return types that you want to
+extract. To save some typing the same method names are found directly
+in the <code>Pythia</code> class, and just send on to the
+<code>Settings</code> ones to do the job, e.g.
+<pre>
+ bool showCS = pythia.flag("Main:showChangedSettings");
+ int nEvent = pythia.mode("Main:numberOfEvents");
+ double spare1 = pythia.parm("Main:spareParm1");
+ string file = pythia.word("Main:allSettingsFile");
+</pre>
+
+<h3>Run settings</h3>
+
+Here settings related to how many events to generate and whether
+to print some information on data used in run. These variables
+can be set in an input "cards" file, and thereafter read out an used
+in the user-written main program. Usage is purely optional, but may help
+you reduce the need to recompile your main program.
+
+<modeopen name="Main:numberOfEvents" default="1000" min="0">
+The number of events to be generated.
+</modeopen>
+
+<modeopen name="Main:numberToList" default="2" min="0">
+The number of events to list.
+</modeopen>
+
+<modeopen name="Main:timesToShow" default="50" min="0">
+Print the number of events generated so far, this many times,
+i.e. once every <code>numberOfEvents/numberToShow</code> events.
+</modeopen>
+
+<modeopen name="Main:timesAllowErrors" default="10" min = "0">
+Allow this many times that <code>pythia.next()</code> returns false,
+i.e. that an event is flawed, before aborting the run.
+</modeopen>
+
+<flag name="Main:showChangedSettings" default="on">
+Print a list of the changed flag/mode/parameter/word settings.
+</flag>
+
+<flag name="Main:showAllSettings" default="off">
+Print a list of all flag/mode/parameter/word settings.
+Warning: this will be a long list.
+</flag>
+
+<modeopen name="Main:showOneParticleData" default="0" min="0">
+Print particle and decay data for the particle with this particular
+identity code. Default means that no particle is printed.
+</flag>
+
+<flag name="Main:showChangedParticleData" default="off">
+Print a list of particle and decay data for those particles
+that were changed (one way or another).
+</flag>
+
+<flag name="Main:showChangedResonanceData" default="off">
+In the previous listing also include the resonances that are
+initialized at the beginning of a run and thus get new particle
+data, even if these may well agree with the default ones.
+Warning: this will be a rather long list.
+</flag>
+
+<flag name="Main:showAllParticleData" default="off">
+Print a list of all particle and decay data.
+Warning: this will be a long list.
+</flag>
+
+<flag name="Main:writeChangedSettings" default="off">
+Write a file with the changed flag/mode/parameter/word settings, in
+a format appropriate to be read in at the beginning of a new
+run, using the <code>pythia.readFile(fileName)</code> method.
+</flag>
+
+<word name="Main:changedSettingsFile" default="currentSettings.cmnd">
+The name of the file to which the changed flag/mode/parameter/word
+settings are written if <code>Main:writeChangedSettings</code>
+is on.
+</word>
+
+<flag name="Main:writeAllSettings" default="off">
+Write a file with all flag/mode/parameter/word settings, in
+a format appropriate to be read in at the beginning of a new
+run, using the <code>pythia.readFile(fileName)</code> method.
+</flag>
+
+<word name="Main:allSettingsFile" default="allSettings.cmnd">
+The name of the file to which a flag/mode/parameter/word
+settings are written if <code>Main:writeAllSettings</code>
+is on.
+</word>
+
+<flag name="Main:showAllStatistics" default="off">
+Print all available statistics or only the minimal set at the end
+of the run.
+</flag>
+
+<h3>Subruns</h3>
+
+You can use <aloc href="ProgramFlow">subruns</aloc> to carry out
+several tasks in the same run. In that case you will need repeated
+instances of the first setting below in your command file, and could
+additionally use the second and third as well.
+
+<modeopen name="Main:subrun" default="-999", min="0">
+The number of the current subrun, a non-negative integer, put as
+first line in a section of lines to be read for this particular subrun.
+</modeopen>
+
+<flag name="Main:LHEFskipInit" default="off">
+If you read several Les Houches Event Files that you want to see
+considered as one single combined event sample you can set this flag
+<code>on</code> after the first subrun to skip (most of) the
+(re-)initialization step.
+</flag>
+
+<modeopen name="Main:numberOfSubruns" default="0", min = "0">
+The number of subruns you intend to use in your current run.
+Unlike the two settings above, <code>Pythia</code> itself will not
+intepret this number, but you could e.g. have a loop in your main
+program to loop over subruns from 0 through
+<code>numberOfSubruns - 1</code>.
+</flag>
+
+<h3>Spares</h3>
+
+For currently unforeseen purposes, a few dummy settings are made
+available here. The user can set the desired value in a "cards file"
+and then use that value in the main program as desired.
+
+<flag name="Main:spareFlag1" default="off">
+</flag>
+
+<flag name="Main:spareFlag2" default="off">
+</flag>
+
+<flag name="Main:spareFlag3" default="off">
+</flag>
+
+<modeopen name="Main:spareMode1" default="0">
+</modeopen>
+
+<modeopen name="Main:spareMode2" default="0">
+</modeopen>
+
+<modeopen name="Main:spareMode3" default="0">
+</modeopen>
+
+<parm name="Main:spareParm1" default="0.">
+</parm>
+
+<parm name="Main:spareParm2" default="0.">
+</parm>
+
+<parm name="Main:spareParm3" default="0.">
+</parm>
+
+<word name="Main:spareWord1" default="void">
+</word>
+
+<word name="Main:spareWord2" default="void">
+</word>
+
+<word name="Main:spareWord3" default="void">
+</word>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Master Switches">
+
+<h2>Master Switches</h2>
+
+Sometimes it may be convenient to omit certain aspects of the event
+generation chain. This cannot be motivated in a full-blown production
+run, but can often be convenient for own understanding and for
+debug purposes. The flags on this page allow just that.
+
+<p/>
+The event generation is subdivided into three levels: the process
+level, the parton level and the hadron level, and flags are grouped
+accordingly.
+
+<h3>Process Level</h3>
+
+The <code>ProcessLevel</code> class administrates the initial step of
+the event generation, wherein the basic process is selected. Currently
+this is done either using some of the internal processes, or with
+Les Houches Accord input.
+
+<p/>
+There could not be a complete event without an initial process, so
+it would not be a normal action to switch off this step. Furthermore,
+without a process set, it is also not possible to carry out the tasks
+on the parton level. It is still possible, however, to hadronize
+a parton-level configuration provided by some external program.
+
+<flag name="ProcessLevel:all" default="on">
+If off, do not attempt to carry out any generation at all on the
+process or parton level. Do allow parton configurations stored in
+the event record to hadronize and hadrons to decay, however, as set
+by the <code>HadronLevel</code> switches. Further details are found
+<aloc href="HadronLevelStandalone">here</aloc>.
+</flag>
+
+<p/>
+For <code>ProcessLevel:all = on</code> one part of the event generation
+on this level may be switched off individually:
+
+<flag name="ProcessLevel:resonanceDecays" default="on">
+Master switch to allow resonance decays; on/off = true/false.
+Normal hadrons and leptons do not count as resonances, so this is
+aimed specifically towards <ei>Z^0, W^+-, t, h^0</ei> and similar
+objects beyond the Standard Model. Do not use this option if you
+may produce coloured resonances and intend to allow hadronization,
+since currently the program would not know how to handle this.
+</flag>
+
+<p/>
+It is possible to stop the generation immediately after the basic
+process has been selected, see <code>PartonLevel:all</code> below.
+
+<h3>PartonLevel</h3>
+
+The <code>PartonLevel</code> class administrates the middle step of the
+event generation, i.e. the evolution from an input (hard) process from
+<code>ProcessLevel</code>, containing a few partons only, to a complete
+parton-level configuration to be handed on to <code>HadronLevel</code>.
+This step involves the application of initial- and final-state radiation,
+multiple interactions and the structure of beam remnants.
+
+<flag name="PartonLevel:all" default="on">
+If off then stop the generation after the hard process has been
+generated, but before the parton-level and hadron-level steps.
+The <code>process</code> record is filled, but the <code>event</code>
+one is then not.
+</flag>
+
+<p/>
+For <code>PartonLevel:all = on</code> some parts of the event generation
+on this level may be switched off individually:
+
+<flag name="PartonLevel:MI" default="on">
+Master switch for multiple interactions; on/off = true/false.
+Further options are found <aloc href="MultipleInteractions">here</aloc>.
+</flag>
+
+<flag name="PartonLevel:ISR" default="on">
+Master switch for initial-state radiation; on/off = true/false.
+Further options are found <aloc href="SpacelikeShowers">here</aloc>.
+</flag>
+
+<flag name="PartonLevel:FSR" default="on">
+Master switch for initial-state radiation; on/off = true/false.
+Further options are found <aloc href="TimelikeShowers">here</aloc>.
+If you leave this switch on, the following two switches allow
+more detailed control to switch off only parts of the showers.
+</flag>
+
+<flag name="PartonLevel:FSRinProcess" default="on">
+Switch for final-state radiation in association with the hard process
+itself; on/off = true/false. In addition <code>PartonLevel:FSR</code>
+must be on for these emissions to occur.
+</flag>
+
+<flag name="PartonLevel:FSRinResonances" default="on">
+Master switch for final-state radiation in any resonance decays
+subsequent to the hard process itself; on/off = true/false. In addition
+<code>PartonLevel:FSR</code> must be on for these emissions to occur.
+</flag>
+
+<p/>
+Switching off all the above MI/ISR/FSR switches is <b>not</b> equivalent
+to setting <code>PartonLevel:all = off</code>. In the former case a
+minimal skeleton of parton-level operations are carried out, such as
+tying together the scattered partons with the beam remnants into colour
+singlets, and storing this information in the <code>event</code> record.
+It is therefore possible to go on and hadronize the event, if desired.
+In the latter case <b>no</b> operations at all are carried out on the
+parton level, and therefore it is also not possible to go on to the
+hadron level.
+
+<p/>
+It is possible to stop the generation immediately after the parton level
+has been set up, see <code>HadronLevel:all</code> below.
+
+<h3>HadronLevel</h3>
+
+The <code>HadronLevel</code> class administrates the final step of the
+event generation, wherein the partonic configuration from
+<code>PartonLevel</code> is hadronized, including string fragmentation
+and secondary decays.
+
+<p/>
+Most of the code in this class itself deals with subdividing the partonic
+content of the event into separate colour singlets, that can be
+treated individually by the string fragmentation machinery. When a
+junction and an antijunction are directly connected, it also breaks
+the string between the two, so that the topology can be reduced back
+to two separate one-junction systems, while still preserving the
+expected particle flow in the junction-junction string region(s).
+
+<flag name="HadronLevel:all" default="on">
+If off then stop the generation after the hard process and
+parton-level activity has been generated, but before the
+hadron-level steps.
+</flag>
+
+<p/>
+For <code>HadronLevel:all = on</code> some parts of the event generation
+on this level may be switched off individually:
+
+<flag name="HadronLevel:Hadronize" default="on">
+Master switch for hadronization; on/off = true/false.
+Further options are found <aloc href="Fragmentation">here</aloc>.
+</flag>
+
+<flag name="HadronLevel:Decay" default="on">
+Master switch for decays; on/off = true/false.
+Further options are found <aloc href="ParticleDecays">here</aloc>.
+</flag>
+
+<flag name="HadronLevel:BoseEinstein" default="off">
+Master switch for the simulation of Bose-Einstein effects;
+on/off = true/false. Further options are found
+<aloc href="BoseEinsteinEffects">here</aloc>.
+</flag>
+
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Multiple Interactions">
+
+<h2>Multiple Interactions</h2>
+
+The starting point for the multiple interactions physics scenario in
+PYTHIA is provided by <ref>Sjo87</ref>. Recent developments have
+included a more careful study of flavour and colour correlations,
+junction topologies and the relationship to beam remnants
+<ref>Sjo04</ref>, and interleaving with initial-state radiation
+<ref>Sjo05</ref>, making use of transverse-momentum-ordered
+initial- and final-state showers.
+
+<p/>
+A big unsolved issue is how the colour of all these subsystems is
+correlated. For sure there is a correlation coming from the colour
+singlet nature of the incoming beams, but in addition final-state
+colour rearrangements may change the picture. Indeed such extra
+effects appear necessary to describe data, e.g. on
+<ei><pT>(n_ch)</ei>. A simple implementation of colour
+rearrangement is found as part of the
+<aloc href="BeamRemnants">beam remnants</aloc> description.
+
+<h3>Main variables</h3>
+
+The maximum <ei>pT</ei> to be allowed for multiple interactions is
+related to the nature of the hard process itself. It involves a
+delicate balance between not doublecounting and not leaving any
+gaps in the coverage. The best procedure may depend on information
+only the user has: how the events were generated and mixed (e.g. with
+Les Houches Accord external input), and how they are intended to be
+used. Therefore a few options are available, with a sensible default
+behaviour.
+<modepick name="MultipleInteractions:pTmaxMatch" default="0" min="0" max="2">
+Way in which the maximum scale for multiple interactions is set
+to match the scale of the hard process itself.
+<option value="0"><b>(i)</b> if the final state of the hard process
+(not counting subsequent resonance decays) contains only quarks
+(<ei>u, d, s, c ,b</ei>), gluons and photons then <ei>pT_max</ei>
+is chosen to be the factorization scale for internal processes
+and the <code>scale</code> value for Les Houches input;
+<b>(ii)</b> if not, interactions are allowed to go all the way up
+to the kinematical limit.
+The reasoning is that the former kind of processes are generated by
+the multiple-interactions machinery and so would doublecount hard
+processes if allowed to overlap the same <ei>pT</ei> range,
+while no such danger exists in the latter case.
+</option>
+<option value="1">always use the factorization scale for an internal
+process and the <code>scale</code> value for Les Houches input,
+i.e. the lower value. This should avoid doublecounting, but
+may leave out some interactions that ought to have been simulated.
+</option>
+<option value="2">always allow multiple interactions up to the
+kinematical limit. This will simulate all possible event topologies,
+but may lead to doublecounting.
+</option>
+</modepick>
+
+<p/>
+The rate of interactions is determined by
+<parm name="MultipleInteractions:alphaSvalue" default="0.127" min="0.06" max="0.25">
+The value of <ei>alpha_strong</ei> at <ei>m_Z</ei>. Default value is
+picked equal to the one used in CTEQ 5L.
+</parm>
+
+<p/>
+The actual value is then regulated by the running to the scale
+<ei>pT^2</ei>, at which it is evaluated
+<modepick name="MultipleInteractions:alphaSorder" default="1" min="0" max="2">
+The order at which <ei>alpha_strong</ei> runs at scales away from
+<ei>m_Z</ei>.
+<option value="0">zeroth order, i.e. <ei>alpha_strong</ei> is kept
+fixed.</option>
+<option value="1">first order, which is the normal value.</option>
+<option value="2">second order. Since other parts of the code do
+not go to second order there is no strong reason to use this option,
+but there is also nothing wrong with it.</option>
+</modepick>
+
+<p/>
+QED interactions are regulated by the <ei>alpha_electromagnetic</ei>
+value at the <ei>pT^2</ei> scale of an interaction.
+
+<modepick name="MultipleInteractions:alphaEMorder" default="1" min="-1" max="1">
+The running of <ei>alpha_em</ei> used in hard processes.
+<option value="1">first-order running, constrained to agree with
+<code>StandardModel:alphaEMmZ</code> at the <ei>Z^0</ei> mass.
+</option>
+<option value="0">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed at its value at vanishing momentum transfer.</option>
+<option value="-1">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed, but at <code>StandardModel:alphaEMmZ</code>, i.e. its value
+at the <ei>Z^0</ei> mass.
+</option>
+</modepick>
+
+<p/>
+Note that the choices of <ei>alpha_strong</ei> and <ei>alpha_em</ei>
+made here override the ones implemented in the normal process machinery,
+but only for the interactions generated by the
+<code>MultipleInteractions</code> class.
+
+<p/>
+In addition there is the possibility of a global rescaling of
+cross sections (which could not easily be accommodated by a
+changed <ei>alpha_strong</ei>, since <ei>alpha_strong</ei> runs)
+<parm name="MultipleInteractions:Kfactor" default="1.0" min="0.5" max="4.0">
+Multiply all cross sections by this fix factor.
+</parm>
+
+<p/>
+There are two complementary ways of regularizing the small-<ei>pT</ei>
+divergence, a sharp cutoff and a smooth dampening. These can be
+combined as desired, but it makes sense to coordinate with how the
+same issue is handled in <aloc href="SpacelikeShowers">spacelike
+showers</aloc>. Actually, by default, the parameters defined here are
+used also for the spacelike showers, but this can be overridden.
+
+<p/>
+Regularization of the divergence of the QCD cross section for
+<ei>pT -> 0</ei> is obtained by a factor <ei>pT^4 / (pT0^2 + pT^2)^2</ei>,
+and by using an <ei>alpha_s(pT0^2 + pT^2)</ei>. An energy dependence
+of the <ei>pT0</ei> choice is introduced by two further parameters,
+so that <ei>pT0Ref</ei> is the <ei>pT0</ei> value for the reference
+cm energy, <ei>pT0Ref = pT0(ecmRef)</ei>.
+<note>Warning:</note> if a large <ei>pT0</ei> is picked for multiple
+interactions, such that the integrated interaction cross section is
+below the nondiffractive inelastic one, this <ei>pT0</ei> will
+automatically be scaled down to cope.
+
+<p/>
+The actual pT0 parameter used at a given cm energy scale, <ei>ecmNow</ei>,
+is obtained as
+<eq>
+ pT0 = pT0(ecmNow) = pT0Ref * (ecmNow / ecmRef)^ecmPow
+</eq>
+where <ei>pT0Ref</ei>, <ei>ecmRef</ei> and <ei>ecmPow</ei> are the
+three parameters below.
+
+<parm name="MultipleInteractions:pT0Ref" default="2.15" min="0.5" max="10.0">
+The <ei>pT0Ref</ei> scale in the above formula.
+<note>Note:</note> <ei>pT0Ref</ei> is one of the key parameters in a
+complete PYTHIA tune. Its value is intimately tied to a number of other
+choices, such as that of colour flow description, so unfortunately it is
+difficult to give an independent meaning to <ei>pT0Ref</ei>.
+</parm>
+
+<parm name="MultipleInteractions:ecmRef" default="1800.0" min="1.">
+The <ei>ecmRef</ei> reference energy scale introduced above.
+</parm>
+
+<parm name="MultipleInteractions:ecmPow" default="0.16" min="0.0" max="0.5">
+The <ei>ecmPow</ei> energy rescaling pace introduced above.
+</parm>
+
+<p/>
+Alternatively, or in combination, a sharp cut can be used.
+<parm name="MultipleInteractions:pTmin" default="0.2" min="0.1" max="10.0">
+Lower cutoff in <ei>pT</ei>, below which no further interactions
+are allowed. Normally <ei>pT0</ei> above would be used to provide
+the main regularization of the cross section for <ei>pT -> 0</ei>,
+in which case <ei>pTmin</ei> is used mainly for technical reasons.
+It is possible, however, to set <ei>pT0Ref = 0</ei> and use
+<ei>pTmin</ei> to provide a step-function regularization, or to
+combine them in intermediate approaches. Currently <ei>pTmin</ei>
+is taken to be energy-independent.
+</parm>
+
+<p/>
+The choice of impact-parameter dependence is regulated by several
+parameters.
+
+<modepick name="MultipleInteractions:bProfile" default="2"
+min="0" max="3">
+Choice of impact parameter profile for the incoming hadron beams.
+<option value="0">no impact parameter dependence at all.</option>
+<option value="1">a simple Gaussian matter distribution;
+no free parameters.</option>
+<option value="2">a double Gaussian matter distribution,
+with the two free parameters <ei>coreRadius</ei> and
+<ei>coreFraction</ei>.</option>
+<option value="3">an overlap function, i.e. the convolution of
+the matter distributions of the two incoming hadrons, of the form
+<ei>exp(- b^expPow)</ei>, where <ei>expPow</ei> is a free
+parameter.</option>
+</modepick>
+
+<parm name="MultipleInteractions:coreRadius" default="0.4" min="0.1" max="1.">
+When assuming a double Gaussian matter profile, <ei>bProfile = 2</ei>,
+the inner core is assumed to have a radius that is a factor
+<ei>coreRadius</ei> smaller than the rest.
+</parm>
+
+<parm name="MultipleInteractions:coreFraction" default="0.5" min="0." max="1.">
+When assuming a double Gaussian matter profile, <ei>bProfile = 2</ei>,
+the inner core is assumed to have a fraction <ei>coreFraction</ei>
+of the matter content of the hadron.
+</parm>
+
+<parm name="MultipleInteractions:expPow" default="1." min="0.4" max="10.">
+When <ei>bProfile = 3</ei> it gives the power of the assumed overlap
+shape <ei>exp(- b^expPow)</ei>. Default corresponds to a simple
+exponential drop, which is not too dissimilar from the overlap
+obtained with the standard double Gaussian parameters. For
+<ei>expPow = 2</ei> we reduce to the simple Gaussian, <ei>bProfile = 1</ei>,
+and for <ei>expPow -> infinity</ei> to no impact parameter dependence
+at all, <ei>bProfile = 0</ei>. For small <ei>expPow</ei> the program
+becomes slow and unstable, so the min limit must be respected.
+</parm>
+
+<p/>
+It is possible to regulate the set of processes that are included in the
+multiple-interactions framework.
+
+<modepick name="MultipleInteractions:processLevel" default="3"
+min="0" max="3">
+Set of processes included in the machinery.
+<option value="0">only the simplest <ei>2 -> 2</ei> QCD processes
+between quarks and gluons, giving no new flavours, i.e. dominated by
+<ei>t</ei>-channel gluon exchange.</option>
+<option value="1">also <ei>2 -> 2</ei> QCD processes giving new flavours
+(including charm and bottom), i.e. proceeding through <ei>s</ei>-channel
+gluon exchange.</option>
+<option value="2">also <ei>2 -> 2</ei> processes involving one or two
+photons in the final state, <ei>s</ei>-channel <ei>gamma</ei>
+boson exchange and <ei>t</ei>-channel <ei>gamma/Z^0/W^+-</ei>
+boson exchange.</option>
+<option value="3">also charmonium and bottomonium production, via
+colour singlet and colour octet channels.</option>
+</modepick>
+
+<h3>Further variables</h3>
+
+These should normally not be touched. Their only function is for
+cross-checks.
+
+<modeopen name="MultipleInteractions:nQuarkIn" default="5" min="0" max="5">
+Number of allowed incoming quark flavours in the beams; a change
+to 4 would thus exclude <ei>b</ei> and <ei>bbar</ei> as incoming
+partons, etc.
+</modeopen>
+
+<modeopen name="MultipleInteractions:nSample" default="1000" min="100">
+The allowed <ei>pT</ei> range is split (unevenly) into 100 bins,
+and in each of these the interaction cross section is evaluated in
+<ei>nSample</ei> random phase space points. The full integral is used
+at initialization, and the differential one during the run as a
+"Sudakov form factor" for the choice of the hardest interaction.
+A larger number implies increased accuracy of the calculations.
+</modeopen>
+
+<h3>The process library</h3>
+
+The processes used to generate multiple interactions form a subset
+of the standard library of hard processes. The input is slightly
+different from the standard hard-process machinery, however,
+since incoming flavours, the <ei>alpha_strong</ei> value and most
+of the kinematics are aready fixed when the process is called.
+
+<h3>Technical notes</h3>
+
+Relative to the articles mentioned above, not much has happened.
+The main news is a technical one, that the phase space of the
+<ei>2 -> 2</ei> (massless) QCD processes is now sampled in
+<ei>dy_3 dy_4 dpT^2</ei>, where <ei>y_3</ei> and <ei>y_4</ei> are
+the rapidities of the two produced partons. One can show that
+<eq>
+ (dx_1 / x_1) * (dx_2 / x_2) * d(tHat) = dy_3 * dy_4 * dpT^2
+</eq>
+Furthermore, since cross sections are dominated by the "Rutherford"
+one of <ei>t</ei>-channel gluon exchange, which is enhanced by a
+factor of 9/4 for each incoming gluon, effective structure functions
+are defined as
+<eq>
+ F(x, pT2) = (9/4) * xg(x, pT2) + sum_i xq_i(x, pT2)
+</eq>
+With this technical shift of factors 9/4 from cross sections to parton
+densities, a common upper estimate of
+<eq>
+ d(sigmaHat)/d(pT2) < pi * alpha_strong^2 / pT^4
+</eq>
+is obtained.
+
+<p/>
+In fact this estimate can be reduced by a factor of 1/2 for the
+following reason: for any configuration <ei>(y_3, y_4, pT2)</ei> also
+one with <ei>(y_4, y_3, pT2)</ei> lies in the phase space. Not both
+of those can enjoy being enhanced by the <ei>tHat -> 0</ei>
+singularity of
+<eq>
+ d(sigmaHat) propto 1/tHat^2.
+</eq>
+Or if they are, which is possible with identical partons like
+<ei>q q -> q q</ei> and <ei>g g -> g g</ei>, each singularity comes
+with half the strength. So, when integrating/averaging over the two
+configurations, the estimated <ei>d(sigmaHat)/d(pT2)</ei> drops.
+Actually, it drops even further, since the naive estimate above is
+based on
+<eq>
+ (4 /9) * (1 + (uHat/sHat)^2) < 8/9 < 1
+</eq>
+The 8/9 value would be approached for <ei>tHat -> 0</ei>, which
+implies <ei>sHat >> pT2</ei> and thus a heavy parton-distribution
+penalty, while parton distributions are largest for
+<ei>tHat = uHat = -sHat/2</ei>, where the above expression
+evaluates to 5/9. A fudge factor is therefore introduced to go the
+final step, so it can easily be modifed when further non-Rutherford
+processes are added, or should parton distributions change significantly.
+
+<p/>
+At initialization, it is assumed that
+<eq>
+ d(sigma)/d(pT2) < d(sigmaHat)/d(pT2) * F(x_T, pT2) * F(x_T, pT2)
+ * (2 y_max(pT))^2
+</eq>
+where the first factor is the upper estimate as above, the second two
+the parton density sum evaluated at <ei>y_3 = y_ 4 = 0</ei> so that
+<ei>x_1 = x_2 = x_T = 2 pT / E_cm</ei>, where the product is expected
+to be maximal, and the final is the phase space for
+<ei>-y_max < y_{3,4} < y_max</ei>.
+The right-hand side expression is scanned logarithmically in <ei>y</ei>,
+and a <ei>N</ei> is determined such that it always is below
+<ei>N/pT^4</ei>.
+
+<p/>
+To describe the dampening of the cross section at <ei>pT -> 0</ei> by
+colour screening, the actual cross section is multiplied by a
+regularization factor <ei>(pT^2 / (pT^2 + pT0^2))^2</ei>, and the
+<ei>alpha_s</ei> is evaluated at a scale <ei>pT^2 + pT0^2</ei>,
+where <ei>pT0</ei> is a free parameter of the order of 2 - 4 GeV.
+Since <ei>pT0</ei> can be energy-dependent, an ansatz
+<eq>
+ pT0(ecm) = pT0Ref * (ecm/ecmRef)^ecmPow
+</eq>
+is used, where <ei>ecm</ei> is the current cm frame energy,
+<ei>ecmRef</ei> is an arbitrary reference energy where <ei>pT0Ref</ei>
+is defined, and <ei>ecmPow</ei> gives the energy rescaling pace. For
+technical reasons, also an absolute lower <ei>pT</ei> scale <ei>pTmin</ei>,
+by default 0.2 GeV, is introduced. In principle, it is possible to
+recover older scenarios with a sharp <ei>pT</ei> cutoff by setting
+<ei>pT0 = 0</ei> and letting <ei>pTmin</ei> be a larger number.
+
+<p/>
+The above scanning strategy is then slightly modified: instead of
+an upper estimate <ei>N/pT^4</ei> one of the form
+<ei>N/(pT^2 + r * pT0^2)^2</ei> is used. At first glance, <ei>r = 1</ei>
+would seem to be fixed by the form of the regularization procedure,
+but this does not take into account the nontrivial dependence on
+<ei>alpha_s</ei>, parton distributions and phase space. A better
+Monte Carlo efficiency is obtained for <ei>r</ei> somewhat below unity,
+and currently <ei>r = 0.25</ei> is hardcoded.
+
+In the generation a trial <ei>pT2</ei> is then selected according to
+<eq>
+ d(Prob)/d(pT2) = (1/sigma_ND) * N/(pT^2 + r * pT0^2)^2 * ("Sudakov")
+</eq>
+For the trial <ei>pT2</ei>, a <ei>y_3</ei> and a <ei>y_4</ei> are then
+selected, and incoming flavours according to the respective
+<ei>F(x_i, pT2)</ei>, and then the cross section is evaluated for this
+flavour combination. The ratio of trial/upper estimate gives the
+probability of survival.
+
+<p/>
+Actually, to profit from the factor 1/2 mentioned above, the cross
+section for the combination with <ei>y_3</ei> and <ei>y_4</ei>
+interchanged is also tried, which corresponds to exchanging <ei>tHat</ei>
+and <ei>uHat</ei>, and the average formed, while the final kinematics
+is given by the relative importance of the two.
+
+<p/>
+Furthermore, since large <ei>y</ei> values are disfavoured by dropping
+PDF's, a factor
+<eq>
+ WT_y = (1 - (y_3/y_max)^2) * (1 - (y_4/y_max)^2)
+</eq>
+is evaluated, and used as a survival probability before the more
+time-consuming PDF+ME evaluation, with surviving events given a
+compensating weight <ei>1/WT_y</ei>.
+
+<p/>
+An impact-parameter dependencs is also allowed. Based on the hard
+<ei>pT</ei> scale of the first interaction, and enhancement/depletion
+factor is picked, which multiplies the rate of subsequent interactions.
+
+<p/>
+Parton densities are rescaled and modified to take into account the
+energy-momentum and flavours kicked out by already-considered
+interactions.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="New-Gauge-Boson Processes">
+
+<h2>New-Gauge-Boson Processes</h2>
+
+This page contains the production of new <ei>Z'^0</ei> and
+<ei>W'^+-</ei> gauge bosons, e.g. within the context of a new
+<ei>U(1)</ei> or <ei>SU(2)</ei> gauge group, and also a
+(rather speculative) horizontal gauge boson <ei>R^0</ei>.
+Left-right-symmetry scenarios also contain new gauge bosons,
+but are described
+<aloc href"LeftRightSymmetryProcesses">separately</aloc>.
+
+<h3><ei>Z'^0</ei></h3>
+
+This group only contains one subprocess, with the full
+<ei>gamma^*/Z^0/Z'^0</ei> interference structure for couplings
+to fermion pairs. It is possible to pick only a subset, e.g, only
+the pure <ei>Z'^0</ei> piece. No higher-order processes are
+available explicitly, but the ISR showers contain automatic
+matching to the <ei>Z'^0</ei> + 1 jet matrix elements, as for
+the corresponding <ei>gamma^*/Z^0</ei> process.
+
+<flag name="NewGaugeBoson:ffbar2gmZZprime" default="off">
+Scattering <ei>f fbar ->Z'^0</ei>.
+Code 3001.
+</flag>
+
+<modepick name="Zprime:gmZmode" default="0" min="0" max="6">
+Choice of full <ei>gamma^*/Z^0/Z'^0</ei> structure or not in
+the above process. Note that, with the <ei>Z'^0</ei> part switched
+off, this process is reduced to what already exists among
+<aloc href="ElectroweakProcesses">electroweak processes</aloc>,
+so those options are here only for crosschecks.
+<option value="0">full <ei>gamma^*/Z^0/Z'^0</ei> structure,
+with interference included.</option>
+<option value="1">only pure <ei>gamma^*</ei> contribution.</option>
+<option value="2">only pure <ei>Z^0</ei> contribution.</option>
+<option value="3">only pure <ei>Z'^0</ei> contribution.</option>
+<option value="4">only the <ei>gamma^*/Z^0</ei> contribution,
+including interference.</option>
+<option value="5">only the <ei>gamma^*/Z'^0</ei> contribution,
+including interference.</option>
+<option value="6">only the <ei>Z^0/Z'^0</ei> contribution,
+including interference.</option>
+<note>Note</note>: irrespective of the option used, the particle produced
+will always be assigned code 32 for <ei>Z'^0</ei>, and open decay channels
+is purely dictated by what is set for the <ei>Z'^0</ei>.
+</modepick>
+
+<p/>
+The couplings of the <ei>Z'^0</ei> to quarks and leptons can
+either be assumed universal, i.e. generation-independent, or not.
+In the former case eight numbers parametrize the vector and axial
+couplings of down-type quarks, up-type quarks, leptons and neutrinos,
+respectively. Depending on your assumed neutrino nature you may
+want to restrict your freedom in that sector, but no limitations
+are enforced by the program. The default corresponds to the same
+couplings as that of the Standard Model <ei>Z^0</ei>, with axial
+couplings <ei>a_f = +-1</ei> and vector couplings
+<ei>v_f = a_f - 4 e_f sin^2(theta_W)</ei>, with
+<ei>sin^2(theta_W) = 0.23</ei>. Without universality
+the same eight numbers have to be set separately also for the
+second and the third generation. The choice of fixed axial and
+vector couplings implies a resonance width that increases linearly
+with the <ei>Z'^0</ei> mass.
+
+<p/>
+By a suitable choice of the parameters, it is possible to simulate
+just about any imaginable <ei>Z'^0</ei> scenario, with full
+interference effects in cross sections and decay angular
+distributions and generation-dependent couplings; the default values
+should mainly be viewed as placeholders. The conversion
+from the coupling conventions in a set of different <ei>Z'^0</ei>
+models in the literature to those used in PYTHIA is described by
+<a href="http://www.hep.uiuc.edu/home/catutza/nota12.ps">C.
+Ciobanu et al.</a>
+
+<flag name="Zprime:universality" default="on">
+If on then you need only set the first-generation couplings
+below, and these are automatically also used for the second and
+third generation. If off, then couplings can be chosen separately
+for each generation.
+</flag>
+
+<p/>
+Here are the couplings always valid for the first generation,
+and normally also for the second and third by trivial analogy:
+
+<parm name="Zprime:vd" default="-0.693">
+vector coupling of <ei>d</ei> quarks.
+</parm>
+
+<parm name="Zprime:ad" default="-1.">
+axial coupling of <ei>d</ei> quarks.
+</parm>
+
+<parm name="Zprime:vu" default="0.387">
+vector coupling of <ei>u</ei> quarks.
+</parm>
+
+<parm name="Zprime:au" default="1.">
+axial coupling of <ei>u</ei> quarks.
+</parm>
+
+<parm name="Zprime:ve" default="-0.08">
+vector coupling of <ei>e</ei> leptons.
+</parm>
+
+<parm name="Zprime:ae" default="-1.">
+axial coupling of <ei>e</ei> leptons.
+</parm>
+
+<parm name="Zprime:vnue" default="1.">
+vector coupling of <ei>nu_e</ei> neutrinos.
+</parm>
+
+<parm name="Zprime:anue" default="1.">
+axial coupling of <ei>nu_e</ei> neutrinos.
+</parm>
+
+<p/>
+Here are the further couplings that are specific for
+a scenario with <code>Zprime:universality</code> swiched off:
+
+<parm name="Zprime:vs" default="-0.693">
+vector coupling of <ei>s</ei> quarks.
+</parm>
+
+<parm name="Zprime:as" default="-1.">
+axial coupling of <ei>s</ei> quarks.
+</parm>
+
+<parm name="Zprime:vc" default="0.387">
+vector coupling of <ei>c</ei> quarks.
+</parm>
+
+<parm name="Zprime:ac" default="1.">
+axial coupling of <ei>c</ei> quarks.
+</parm>
+
+<parm name="Zprime:vmu" default="-0.08">
+vector coupling of <ei>mu</ei> leptons.
+</parm>
+
+<parm name="Zprime:amu" default="-1.">
+axial coupling of <ei>mu</ei> leptons.
+</parm>
+
+<parm name="Zprime:vnumu" default="1.">
+vector coupling of <ei>nu_mu</ei> neutrinos.
+</parm>
+
+<parm name="Zprime:anumu" default="1.">
+axial coupling of <ei>nu_mu</ei> neutrinos.
+</parm>
+
+<parm name="Zprime:vb" default="-0.693">
+vector coupling of <ei>b</ei> quarks.
+</parm>
+
+<parm name="Zprime:ab" default="-1.">
+axial coupling of <ei>b</ei> quarks.
+</parm>
+
+<parm name="Zprime:vt" default="0.387">
+vector coupling of <ei>t</ei> quarks.
+</parm>
+
+<parm name="Zprime:at" default="1.">
+axial coupling of <ei>t</ei> quarks.
+</parm>
+
+<parm name="Zprime:vtau" default="-0.08">
+vector coupling of <ei>tau</ei> leptons.
+</parm>
+
+<parm name="Zprime:atau" default="-1.">
+axial coupling of <ei>tau</ei> leptons.
+</parm>
+
+<parm name="Zprime:vnutau" default="1.">
+vector coupling of <ei>nu_tau</ei> neutrinos.
+</parm>
+
+<parm name="Zprime:anutau" default="1.">
+axial coupling of <ei>nu_tau</ei> neutrinos.
+</parm>
+
+<p/>
+The coupling to the decay channel <ei>Z'^0 -> W^+ W^-</ei> is
+more model-dependent. By default it is therefore off, but can be
+switched on as follows. Furthermore, we have left some amount of
+freedom in the choice of decay angular correlations in this
+channel, but obviously alternative shapes could be imagined.
+
+<parm name="Zprime:coup2WW" default="0." min="0.">
+the coupling <ei>Z'^0 -> W^+ W^-</ei> is taken to be this number
+times <ei>m_W^2 / m_Z'^2</ei> times the <ei>Z^0 -> W^+ W^-</ei>
+coupling. Thus a unit value corresponds to the
+<ei>Z^0 -> W^+ W^-</ei> coupling, scaled down by a factor
+<ei>m_W^2 / m_Z'^2</ei>, and gives a <ei>Z'^0</ei> partial
+width into this channel that again increases linearly. If you
+cancel this behaviour, by letting <code>Zprime:coup2WW</code> be
+proportional to <ei>m_Z'^2 / m_W^2</ei>, you instead obtain a
+partial width that goes like the fifth power of the <ei>Z'^0</ei>
+mass. These two extremes correspond to the "extended gauge model"
+and the "reference model", respectively, of <ref>Alt89</ref>.
+Note that this channel only includes the pure <ei>Z'</ei> part,
+while <ei>f fbar -> gamma^*/Z^*0 -> W^+ W^-</ei> is available
+as a separate electroweak process.
+</parm>
+
+<parm name="Zprime:anglesWW" default="0." min="0." max="1.">
+in the decay chain <ei>Z'^0 -> W^+ W^- ->f_1 fbar_2 f_3 fbar_4</ei>
+the decay angular distributions is taken to be a mixture of two
+possible shapes. This parameter gives the fraction that is distributed
+as in Higgs <ei>h^0 -> W^+ W^-</ei> (longitudinal bosons),
+with the remainder (by default all) is taken to be the same as for
+<ei>Z^0 -> W^+ W^-</ei> (a mixture of transverse and longitudinal
+bosons).
+</parm>
+
+<p/>
+A massive <ei>Z'^0</ei> is also likely to decay into Higgses
+and potentially into other now unknown particles. Such possibilities
+clearly are quite model-dependent, and have not been included
+for now.
+
+<h3><ei>W'^+-</ei></h3>
+
+The <ei>W'^+-</ei> implementation is less ambitious than the
+<ei>Z'^0</ei>. Specifically, while indirect detection of a
+<ei>Z'^0</ei> through its interference contribution is
+a possible discovery channel in lepton colliders, there is no
+equally compelling case for <ei>W^+-/W'^+-</ei> interference
+effects being of importance for discovery, and such interference
+has therefore not been implemented for now. Related to this, a
+<ei>Z'^0</ei> could appear on its own in a new <ei>U(1)</ei> group,
+while <ei>W'^+-</ei> would have to sit in a <ei>SU(2)</ei> group
+and thus have a <ei>Z'^0</ei> partner that is likely to be found
+first. Only one process is implemented but, like for the
+<ei>W^+-</ei>, the ISR showers contain automatic matching to the
+<ei>W'^+-</ei> + 1 jet matrix elements.
+
+<flag name="NewGaugeBoson:ffbar2Wprime" default="off">
+Scattering <ei>f fbar' -> W'^+-</ei>.
+Code 3021.
+</flag>
+
+<p/>
+The couplings of the <ei>W'^+-</ei> are here assumed universal,
+i.e. the same for all generations. One may set vector and axial
+couplings freely, separately for the <ei>q qbar'</ei> and the
+<ei>l nu_l</ei> decay channels. The defaults correspond to the
+<ei>V - A</ei> structure and normalization of the Standard Model
+<ei>W^+-</ei>, but can be changed to simulate a wide selection
+of models. One limitation is that, for simplicity, the same
+Cabibbo--Kobayashi--Maskawa quark mixing matrix is assumed as for
+the standard <ei>W^+-</ei>. Depending on your assumed neutrino
+nature you may want to restrict your freedom in the lepton sector,
+but no limitations are enforced by the program.
+
+<parm name="Wprime:vq" default="1.">
+vector coupling of quarks.
+</parm>
+
+<parm name="Wprime:aq" default="-1.">
+axial coupling of quarks.
+</parm>
+
+<parm name="Wprime:vl" default="1.">
+vector coupling of leptons.
+</parm>
+
+<parm name="Wprime:al" default="-1.">
+axial coupling of leptons.
+</parm>
+
+<p/>
+The coupling to the decay channel <ei>W'^+- -> W^+- Z^0</ei> is
+more model-dependent, like for <ei>Z'^0 -> W^+ W^-</ei> described
+above. By default it is therefore off, but can be
+switched on as follows. Furthermore, we have left some amount of
+freedom in the choice of decay angular correlations in this
+channel, but obviously alternative shapes could be imagined.
+
+<parm name="Wprime:coup2WZ" default="0." min="0.">
+the coupling <ei>W'^0 -> W^+- Z^0</ei> is taken to be this number
+times <ei>m_W^2 / m_W'^2</ei> times the <ei>W^+- -> W^+- Z^0</ei>
+coupling. Thus a unit value corresponds to the
+<ei>W^+- -> W^+- Z^0</ei> coupling, scaled down by a factor
+<ei>m_W^2 / m_W'^2</ei>, and gives a <ei>W'^+-</ei> partial
+width into this channel that increases linearly with the
+<ei>W'^+-</ei> mass. If you cancel this behaviour, by letting
+<code>Wprime:coup2WZ</code> be proportional to <ei>m_W'^2 / m_W^2</ei>,
+you instead obtain a partial width that goes like the fifth power
+of the <ei>W'^+-</ei> mass. These two extremes correspond to the
+"extended gauge model" and the "reference model", respectively,
+of <ref>Alt89</ref>.
+</parm>
+
+<parm name="Wprime:anglesWZ" default="0." min="0." max="1.">
+in the decay chain <ei>W'^+- -> W^+- Z^0 ->f_1 fbar_2 f_3 fbar_4</ei>
+the decay angular distributions is taken to be a mixture of two
+possible shapes. This parameter gives the fraction that is distributed
+as in Higgs <ei>H^+- -> W^+- Z^0</ei> (longitudinal bosons),
+with the remainder (by default all) is taken to be the same as for
+<ei>W^+- -> W^+- Z^0</ei> (a mixture of transverse and longitudinal
+bosons).
+</parm>
+
+<p/>
+A massive <ei>W'^+-</ei> is also likely to decay into Higgses
+and potentially into other now unknown particles. Such possibilities
+clearly are quite model-dependent, and have not been included
+for now.
+
+<h3><ei>R^0</ei></h3>
+
+The <ei>R^0</ei> boson (particle code 41) represents one possible
+scenario for a horizontal gauge boson, i.e. a gauge boson
+that couples between the generations, inducing processes like
+<ei>s dbar -> R^0 -> mu^- e^+</ei>. Experimental limits on
+flavour-changing neutral currents forces such a boson to be fairly
+heavy. In spite of being neutral the antiparticle is distinct from
+the particle: one carries a net positive generation number and
+the other a negative one. This particular model has no new
+parameters beyond the <ei>R^0</ei> mass. Decays are assumed isotropic.
+For further details see <ref>Ben85</ref>.
+
+<flag name="NewGaugeBoson:ffbar2R0" default="off">
+Scattering <ei>f_1 fbar_2 -> R^0 -> f_3 fbar_4</ei>, where
+<ei>f_1</ei> and <ei>fbar_2</ei> are separated by <ei>+-</ei> one
+generation and similarly for <ei>f_3</ei> and <ei>fbar_4</ei>.
+Thus possible final states are e.g. <ei>d sbar</ei>, <ei>u cbar</ei>
+<ei>s bbar</ei>, <ei>c tbar</ei>, <ei>e- mu+</ei> and
+<ei>mu- tau+</ei>.
+Code 3041.
+</flag>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Onia Processes">
+
+<h2>Onia Processes</h2>
+
+Production of J/psi or Upsilon, directly and via chi states and the
+colour-octet mechanism.
+In each process the square-bracketed expression specifies the state
+in spectroscopic notation, <ei>(2S+1) L J</ei>, followed by
+<ei>(1)</ei> for colour-singlet states and <ei>(8)</ei> for
+colour-octet ditto.
+
+<p/>
+The original Fortran code for these processes has been contributed
+by Stefan Wolf [unpublished]. For the C++ version only the unpolarized
+expressions are retained, since the theoretical predictions of the
+colour-octet model anyway do not agree with the experimental
+observations. Furthermore, the polarization effects are modest,
+so isotropic decay is not a bad starting point. Such an event sample
+can afterwards be reweighted at will by the user, to test various
+assumptions.
+
+<p/>
+The description of
+<aloc href="TimelikeShowers">final-state radiation</aloc>
+is in this case based on some further model assumptions.
+
+<p/>
+Most of the processes below are divergent in the limit
+<ei>pT -> 0</ei>, and therefore a <ei>pTmin</ei> scale should
+be set. Comparisons with data indicate that this divergence
+can be tamed the same way as for the normal QCD <ei>2 -> 2</ei> cross
+sections, which makes sense, since they are all dominated by the
+same kind of <ei>t</ei>-channel gluon exchange. It is therefore
+possible to use the <aloc href="UserHooks">SuppressSmallPT</aloc>
+user hook to impose a reweighting that cancels the low-<ei>pT</ei>
+divergence.
+
+<p/>
+An eikonalized description of these processes is included in the
+multiple-interactions framework. Here the low-<ei>pT</ei> dampening
+is automatic, and additionally the framework is more consistent
+(e.g. with respect to energy-momentum constraints and the
+impact-parameter description) for events where the onium production
+is not the hardest subprocess, as would often be the case in the
+low-<ei>pT</ei> limit.
+
+<h3>Charmonium</h3>
+
+<flag name="Charmonium:all" default="off">
+Common switch for the group of charmonium production.
+</flag>
+
+<flag name="Charmonium:gg2QQbar[3S1(1)]g" default="off">
+<ei>g g -> ccbar[3S1(1)] g</ei>.
+Code 401.
+</flag>
+
+<flag name="Charmonium:gg2QQbar[3P0(1)]g" default="off">
+<ei>g g -> ccbar[3P0(1)] g</ei>.
+Code 402.
+</flag>
+
+<flag name="Charmonium:gg2QQbar[3P1(1)]g" default="off">
+<ei>g g -> ccbar[3P1(1)] g</ei>.
+Code 403.
+</flag>
+
+<flag name="Charmonium:gg2QQbar[3P2(1)]g" default="off">
+<ei>g g -> ccbar[3P2(1)] g</ei>.
+Code 404.
+</flag>
+
+<flag name="Charmonium:qg2QQbar[3P0(1)]q" default="off">
+<ei>q g -> ccbar[3P0(1)] q</ei>.
+Code 405.
+</flag>
+
+<flag name="Charmonium:qg2QQbar[3P1(1)]q" default="off">
+<ei>q g -> ccbar[3P1(1)] q</ei>.
+Code 406.
+</flag>
+
+<flag name="Charmonium:qg2QQbar[3P2(1)]q" default="off">
+<ei>q g -> ccbar[3P2(1)] q</ei>.
+Code 407.
+</flag>
+
+<flag name="Charmonium:qqbar2QQbar[3P0(1)]g" default="off">
+<ei>q qbar -> ccbar[3P0(1)] g</ei>.
+Code 408.
+</flag>
+
+<flag name="Charmonium:qqbar2QQbar[3P1(1)]g" default="off">
+<ei>q qbar -> ccbar[3P1(1)] g</ei>.
+Code 409.
+</flag>
+
+<flag name="Charmonium:qqbar2QQbar[3P2(1)]g" default="off">
+<ei>q qbar -> ccbar[3P2(1)] g</ei>.
+Code 410.
+</flag>
+
+<flag name="Charmonium:gg2QQbar[3S1(8)]g" default="off">
+<ei>g g -> ccbar[3S1(8)] g</ei>.
+Code 411.
+</flag>
+
+<flag name="Charmonium:gg2QQbar[1S0(8)]g" default="off">
+<ei>g g -> ccbar[3S1(8)] g</ei>.
+Code 412.
+</flag>
+
+<flag name="Charmonium:gg2QQbar[3PJ(8)]g" default="off">
+<ei>g g -> ccbar[3S1(8)] g</ei>.
+Code 413.
+</flag>
+
+<flag name="Charmonium:qg2QQbar[3S1(8)]q" default="off">
+<ei>q g -> ccbar[3S1(8)] q</ei>.
+Code 414.
+</flag>
+
+<flag name="Charmonium:qg2QQbar[1S0(8)]q" default="off">
+<ei>q g -> ccbar[3S1(8)] q</ei>.
+Code 415.
+</flag>
+
+<flag name="Charmonium:qg2QQbar[3PJ(8)]q" default="off">
+<ei>q g -> ccbar[3S1(8)] q</ei>.
+Code 416.
+</flag>
+
+<flag name="Charmonium:qqbar2QQbar[3S1(8)]g" default="off">
+<ei>q qbar -> ccbar[3S1(8)] g</ei>.
+Code 417.
+</flag>
+
+<flag name="Charmonium:qqbar2QQbar[1S0(8)]g" default="off">
+<ei>q qbar -> ccbar[3S1(8)] g</ei>.
+Code 418.
+</flag>
+
+<flag name="Charmonium:qqbar2QQbar[3PJ(8)]g" default="off">
+<ei>q qbar -> ccbar[3S1(8)] g</ei>.
+Code 419.
+</flag>
+
+<h3>Bottomonium</h3>
+
+<flag name="Bottomonium:all" default="off">
+Common switch for the group of charmonium production.
+</flag>
+
+<flag name="Bottomonium:gg2QQbar[3S1(1)]g" default="off">
+<ei>g g -> bbbar[3S1(1)] g</ei>.
+Code 501.
+</flag>
+
+<flag name="Bottomonium:gg2QQbar[3P0(1)]g" default="off">
+<ei>g g -> bbbar[3P0(1)] g</ei>.
+Code 502.
+</flag>
+
+<flag name="Bottomonium:gg2QQbar[3P1(1)]g" default="off">
+<ei>g g -> bbbar[3P1(1)] g</ei>.
+Code 503.
+</flag>
+
+<flag name="Bottomonium:gg2QQbar[3P2(1)]g" default="off">
+<ei>g g -> bbbar[3P2(1)] g</ei>.
+Code 504.
+</flag>
+
+<flag name="Bottomonium:qg2QQbar[3P0(1)]q" default="off">
+<ei>q g -> bbbar[3P0(1)] q</ei>.
+Code 505.
+</flag>
+
+<flag name="Bottomonium:qg2QQbar[3P1(1)]q" default="off">
+<ei>q g -> bbbar[3P1(1)] q</ei>.
+Code 506.
+</flag>
+
+<flag name="Bottomonium:qg2QQbar[3P2(1)]q" default="off">
+<ei>q g -> bbbar[3P2(1)] q</ei>.
+Code 507.
+</flag>
+
+<flag name="Bottomonium:qqbar2QQbar[3P0(1)]g" default="off">
+<ei>q qbar -> bbbar[3P0(1)] g</ei>.
+Code 508.
+</flag>
+
+<flag name="Bottomonium:qqbar2QQbar[3P1(1)]g" default="off">
+<ei>q qbar -> bbbar[3P1(1)] g</ei>.
+Code 509.
+</flag>
+
+<flag name="Bottomonium:qqbar2QQbar[3P2(1)]g" default="off">
+<ei>q qbar -> bbbar[3P2(1)] g</ei>.
+Code 510.
+</flag>
+
+<flag name="Bottomonium:gg2QQbar[3S1(8)]g" default="off">
+<ei>g g -> bbbar[3S1(8)] g</ei>.
+Code 511.
+</flag>
+
+<flag name="Bottomonium:gg2QQbar[1S0(8)]g" default="off">
+<ei>g g -> bbbar[3S1(8)] g</ei>.
+Code 512.
+</flag>
+
+<flag name="Bottomonium:gg2QQbar[3PJ(8)]g" default="off">
+<ei>g g -> bbbar[3S1(8)] g</ei>.
+Code 513.
+</flag>
+
+<flag name="Bottomonium:qg2QQbar[3S1(8)]q" default="off">
+<ei>q g -> bbbar[3S1(8)] q</ei>.
+Code 514.
+</flag>
+
+<flag name="Bottomonium:qg2QQbar[1S0(8)]q" default="off">
+<ei>q g -> bbbar[3S1(8)] q</ei>.
+Code 515.
+</flag>
+
+<flag name="Bottomonium:qg2QQbar[3PJ(8)]q" default="off">
+<ei>q g -> bbbar[3S1(8)] q</ei>.
+Code 516.
+</flag>
+
+<flag name="Bottomonium:qqbar2QQbar[3S1(8)]g" default="off">
+<ei>q qbar -> bbbar[3S1(8)] g</ei>.
+Code 517.
+</flag>
+
+<flag name="Bottomonium:qqbar2QQbar[1S0(8)]g" default="off">
+<ei>q qbar -> bbbar[3S1(8)] g</ei>.
+Code 518.
+</flag>
+
+<flag name="Bottomonium:qqbar2QQbar[3PJ(8)]g" default="off">
+<ei>q qbar -> bbbar[3S1(8)] g</ei>.
+Code 519.
+</flag>
+
+<h3>Onium matrix elements</h3>
+
+The implementation of charmonium and bottomonium production, including
+the colour-octet production mechanism, requires information on NRQCD
+matrix elements for the various wavefunctions involved. Default values
+for these are encoded in the following ten variables. They
+are taken from <ref>Nas00</ref>; see also <ref>Bar06</ref>.
+
+<parm name="Charmonium:OJpsi3S11" default="1.16" min="0.0">
+<ei><O(J/psi)[3S1(1)]></ei>.
+</parm>
+
+<parm name="Charmonium:OJpsi3S18" default="0.0119" min="0.0">
+<ei><O(J/psi)[3S1(8)]></ei>.
+</parm>
+
+<parm name="Charmonium:OJpsi1S08" default="0.01" min="0.0">
+<ei><O(J/psi)[1S0(8)]></ei>.
+</parm>
+
+<parm name="Charmonium:OJpsi3P08" default="0.01" min="0.0">
+<ei><O(J/psi)[3P0(8)]>/m_c^2</ei>.
+</parm>
+
+<parm name="Charmonium:Ochic03P01" default="0.05" min="0.0">
+<ei><O(chi_c0)[3P0(8)]>/m_c^2</ei>.
+</parm>
+
+<parm name="Bottomonium:OUpsilon3S11" default="9.28" min="0.0">
+<ei><O(Upsilon)[3S1(1)]></ei>.
+</parm>
+
+<parm name="Bottomonium:OUpsilon3S18" default="0.15" min="0.0">
+<ei><O(Upsilon)[3S1(8)]></ei>.
+</parm>
+
+<parm name="Bottomonium:OUpsilon1S08" default="0.02" min="0.0">
+<ei><O(Upsilon)[1S0(8)]></ei>.
+</parm>
+
+<parm name="Bottomonium:OUpsilon3P08" default="0.48" min="0.0">
+<ei><O(Upsilon)[3P0(8)]>/m_b^2</ei>.
+</parm>
+
+<parm name="Bottomonium:Ochib03P01" default="0.09" min="0.0">
+<ei><O(chi_b0)[3P0(8)]>/m_b^2</ei>.
+</parm>
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="PDF Selection">
+
+<h2>PDF Selection</h2>
+
+This page contains three subsections. The first deals with how to
+pick the parton distribution set for protons, including from LHAPDF,
+to be used for all proton and antiproton beams. The second is a special
+option that allows a separate PDF set to be used for the hard process
+only, while the first choice would still apply to everything else.
+The third gives the possibility to switch off the lepton
+"parton density".
+
+<h3>Parton densities for protons</h3>
+
+The selection of parton densities is made once and then is propagated
+through the program. It is essential to make an informed choice,
+for several reasons:
+<note>Warning 1:</note> the choice of PDF set affects a number of
+properties of events. A change of PDF therefore requires a complete
+retuning e.g. of the multiple-interactions model for minimum-bias and
+underlying events.
+<note>Warning 2:</note> People often underestimate the differences
+between different sets on the market. The sets for the same order are
+constructed to behave more or less similarly at large <ei>x</ei> and
+<ei>Q^2</ei>, while the multiple interactions are dominated by the
+behaviour in the region of small <ei>x</ei> and <ei>Q^2</ei>. A good
+PDF parametrization ought to be sensible down to <ei>x = 10^-6</ei>
+(<ei>x = 10^-7</ei>) and <ei>Q^2 = 1</ei> GeV^2 for Tevatron (LHC)
+applications. Unfortunately there are distributions on the market that
+completely derail in that region. The <code>main41.cc</code> and
+<code>main42.cc</code> programs in the <code>examples</code>
+subdirectory provide some examples of absolutely minimal sanity checks
+before a new PDF set is put in production.
+<note>Warning 3:</note> NLO and LO sets tend to have quite different
+behaviours, e.g. NLO ones have less gluons at small x, which then is
+compensated by positive corrections in the NLO matrix elements.
+Therefore do not blindly assume that an NLO tune has to be better than
+an LO one when combined with the LO matrix elements in PYTHIA. There are
+explicit examples where such thinking can lead you down the wrong alley.
+
+<p/>
+The simplest option is to pick one
+of the few distributions available internally:
+
+<modepick name="PDF:pSet" default="2" min="1" max="2">
+Parton densities to be used for proton beams (and, by implication,
+antiproton ones):
+<option value="1">GRV 94 L;</option>
+<option value="2">CTEQ 5 L.</option>
+</modepick>
+
+<p/>
+Obviously this choice is mainly intended to get going, and if you link to
+the <a href="http://projects.hepforge.org/lhapdf/" target="page">LHAPDF
+library</a> <ref>Wha05</ref> you get access to a much wider selection.
+<note>Warning:</note> owing to previous problems with the behaviour of PDF's
+beyond the <ei>x</ei> and <ei>Q^2</ei> boundaries of a set, you should
+only use LHAPDF <b>version 5.3.0 or later</b>.
+
+<flag name="PDF:useLHAPDF" default="off">
+If off then the choice of proton PDF is based on <code>pPDFset</code>
+above. If on then it is instead based on the choice of
+<code>LHAPDFset</code> and <code>LHAPDFmember</code> below.
+<note>Note:</note> in order for this option to work you must have
+compiled PYTHIA appropriately and have set the <code>LHAPATH</code>
+environment variable to provide the data-files directory of your local
+LHAPDF installation. See the README file in the <code>examples</code>
+directory for further instructions.
+</flag>
+
+<word name="PDF:LHAPDFset" default="MRST2004FF4lo.LHgrid">
+Name of proton PDF set from LHAPDF to be used. You have to choose
+from the
+<a href="http://projects.hepforge.org/lhapdf/pdfsets" target="page">
+list of available sets</a>. Examples of some recent ones would be
+cteq61.LHpdf, cteq61.LHgrid, cteq6l.LHpdf, cteq6ll.LHpdf,
+MRST2004nlo.LHpdf, MRST2004nlo.LHgrid, MRST2004nnlo.LHgrid and
+MRST2004FF3lo.LHgrid. If you pick a LHpdf set it will require some
+calculation the first time it is called.
+<note>Technical note:</note> if you provide a name beginning with a
+slash (/) it is assumed you want to provide the full file path and then
+<code>initPDFsetM(name)</code> is called, else the correct path is assumed
+already set and <code>initPDFsetByNameM(name)</code> is called.
+</word>
+
+<modeopen name="PDF:LHAPDFmember" default="0" min="0">
+Further choice of a specific member from the set picked above. Member 0
+should normally correspond to the central value, with higher values
+corresponding to different error PDF's somewhat off in different
+directions. You have to check from set to set which options are open.
+<note>Note:</note> you can only use one member in a run, so if you
+want to sweep over many members you either have to do many separate
+runs or, as a simplification, save the
+<aloc href="EventInformation">pdf weights</aloc> at the hard scattering
+and do an offline reweighting of events.
+</modeopen>
+
+<flag name="PDF:extrapolateLHAPDF" default="off">
+Parton densities have a guaranteed range of validity in <ei>x</ei>
+and <ei>Q^2</ei>, and what should be done beyond that range usually is
+not explained by the authors of PDF sets. Nevertheless these boundaries
+very often are exceeded, e.g. minimum-bias studies at LHC may sample
+<ei>x</ei> values down to <ei>10^-8</ei>, while many PDF sets stop
+already at <ei>10^-5</ei>. The default behaviour is then that the
+PDF's are frozen at the boundary, i.e. <ei>xf(x,Q^2)</ei> is fixed at
+its value at <ei>x_min</ei> for all values <ei>x < x_min</ei>,
+and so on. This is a conservative approach. Alternatively, if you
+switch on extrapolation, then parametrizations will be extended beyond
+the boundaries, by some prescription. In some cases this will provide a
+more realistic answer, in others complete rubbish. Another problem is
+that some of the PDF-set codes will write a warning message anytime the
+limits are exceeded, thus swamping your output file. Therefore you should
+study a set seriously before you run it with this switch on.
+</flag>
+
+<p/>
+If you want to use PDF's not found in LHAPDF, or you want to interface
+LHAPDF another way, you have full freedom to use the more generic
+<aloc href="PartonDistributions">interface options</aloc>.
+
+<h3>Parton densities for protons in the hard process</h3>
+
+The above options provides a PDF set that will be used everywhere:
+for the hard process, the parton showers and the multiple interactions
+alike. As already mentioned, therefore a change of PDF should be
+accompanied by a <b>complete</b> retuning of the whole MI framework,
+and maybe more. There are cases where one may want to explore
+different PDF options for the hard process, but would not want to touch
+the rest. If several different sets are to be compared, a simple
+reweighting based on the <aloc href="EventInformation">originally
+used</aloc> flavour, <ei>x</ei>, <ei>Q^2</ei> and PDF values may offer the
+best route. The options in this section allow a choice of the PDF set
+for the hard process alone, while the choice made in the previous section
+would still be used for everything else. The hardest interaction
+of the minimum-bias process is part of the multiple-interactions
+framework and so does not count as a hard process here.
+
+<p/>
+Of course it is inconsistent to use different PDF's in different parts
+of an event, but if the <ei>x</ei> and <ei>Q^2</ei> ranges mainly accessed
+by the components are rather different then the contradiction would not be
+too glaring. Furthermore, since standard PDF's are one-particle-inclusive
+we anyway have to 'invent' our own PDF modifications to handle configurations
+where more than one parton is kicked out of the proton <ref>Sjo04</ref>.
+
+<p/>
+The PDF choices that can be made are the same as above, so we do not
+repeat the detailed discussion.
+
+<flag name="PDF:useHard" default="off">
+If on then select a separate PDF set for the hard process, using the
+variables below. If off then use the same PDF set for everything,
+as already chosen above.
+</flag>
+
+<modepick name="PDF:pHardSet" default="2" min="1" max="2">
+Parton densities to be used for proton beams (and, by implication,
+antiproton ones):
+<option value="1">GRV 94 L;</option>
+<option value="2">CTEQ 5 L.</option>
+</modepick>
+
+<flag name="PDF:useHardLHAPDF" default="off">
+If off then the choice of proton PDF is based on <code>hardpPDFset</code>
+above. If on then it is instead based on the choice of
+<code>hardLHAPDFset</code> and <code>hardLHAPDFmember</code> below.
+</flag>
+
+<word name="PDF:hardLHAPDFset" default="MRST2004FF4lo.LHgrid">
+Name of proton PDF set from LHAPDF to be used.
+</word>
+
+<modeopen name="PDF:hardLHAPDFmember" default="0" min="0">
+Further choice of a specific member from the set picked above.
+</modeopen>
+
+<p/>
+Note that there is no separate equivalent of the
+<code>PDF:extrapolateLHAPDF</code> flag specifically for the hard
+PDF. Since LHAPDF only has one global flag for extrapolation or not,
+the choice for the normal PDF's also applies to the hard ones.
+
+<h3>Parton densities for leptons</h3>
+
+For electrons/leptons there is no need to choose between different
+parametrizations, since only one implementation is available, and
+should be rather uncontroversial (apart from some technical details).
+However, insofar as e.g. <ei>e^+ e^-</ei> data often are corrected
+back to a world without any initial-state photon radiation, it is
+useful to have a corresponding option available here.
+
+<flag name="PDF:lepton" default="on">
+Use parton densities for lepton beams or not. If off the colliding
+leptons carry the full beam energy, if on part of the energy is
+radiated away by initial-state photons. In the latter case the
+initial-state showers will generate the angles and energies of the
+set of photons that go with the collision. In addition one collinear
+photon per beam carries any leftover amount of energy not described
+by shower emissions. If the initial-state showers are switched off
+these collinear photons will carry the full radiated energy.
+</flag>
+
+<h3>Incoming parton selection</h3>
+
+There is one useful degree of freedom to restrict the set of incoming
+quark flavours for hard processes. It does not change the PDF's as such,
+only which quarks are allowed to contribute to the hard-process cross
+sections. Note that separate but similarly named modes are available
+for multiple interactions and spacelike showers.
+
+<modeopen name="PDFinProcess:nQuarkIn" default="5" min="0" max="5">
+Number of allowed incoming quark flavours in the beams; a change
+to 4 would thus exclude <ei>b</ei> and <ei>bbar</ei> as incoming
+partons, etc.
+</modeopen>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="PYTHIA 6 Translation Table">
+
+<h2>PYTHIA 6 Translation Table</h2>
+
+For those more familiar with PYTHIA 6 than PYTHIA 8, here comes a table
+that shows the approximate correspondence between some commonly used
+variables in the two programs.The list can be expanded to meet explicit
+needs (channel your suggestions via the Monte Carlo responsible of your
+collaboration), but there is no question of ever providing anywhere near
+a complete coverage.
+
+<h3>Selecting properties of event generation</h3>
+
+For PYTHIA 8 you should use the <code>pythia->readString("command")</code>
+to give in the commands listed below, assuming that you have access to a
+pointer <code>pythia</code> to an instance of the <code>Pythia</code> class.
+
+<table cellspacing="5">
+
+<tr> <th>PYTHIA 6 </th> <th>PYTHIA 8 </th>
+<th> Comment </th> </tr>
+
+<tr> <td>MSEL = 1 </td> <td>SoftQCD:minBias = on</td>
+<td> soft and hard QCD events (for <ei>pp/pbarp</ei>)</td> </tr>
+
+<tr> <td>MSEL = 2 </td> <td>SoftQCD:all = on</td>
+<td> as above, plus elastic and diffractive (for <ei>pp/pbarp</ei>)</td> </tr>
+
+<tr> <td>MSTP(61) = 0 </td> <td>PartonLevel:ISR = off</td>
+<td> no initial-state radiation </td> </tr>
+
+<tr> <td>MSTP(71) = 0 </td> <td>PartonLevel:FSR = off</td>
+<td> no final-state radiation </td> </tr>
+
+<tr> <td>MSTP(81) = 0 </td> <td>PartonLevel:MI = off</td>
+<td> no multiple parton-parton interactions </td> </tr>
+
+<tr> <td>MSTP(111) = 0 </td> <td>HadronLevel:all = off</td>
+<td> no hadronization and no decays </td> </tr>
+
+</table>
+
+<h3>Information about generated event</h3>
+
+Several PYTHIA 6 variables are stored in two places, and then both are
+given below. For PYTHIA 8 it is assumed that you have access to a pointer
+<code>pythia</code> to an instance of the <code>Pythia</code> class.
+
+<table cellspacing="5">
+
+<tr> <th>PYTHIA 6 </th> <th>PYTHIA 8 </th>
+<th> Comment </th> </tr>
+
+<tr> <td>msti(1), mint(1) </td> <td> pythia->info.code() </td>
+<td> process ID (but changed numbering) </td> </tr>
+
+<tr> <td>pari(13), vint(43) </td> <td> pythia->info.mHat() </td>
+<td> invariant mass of the hard subprocess </td> </tr>
+
+<tr> <td>pari(17), vint(47) </td> <td> pythia->info.pTHat() </td>
+<td> transverse momentum of the hard subprocess (2 -> 2)</td> </tr>
+
+<tr> <td>pari(21), vint(51) </td> <td> pythia->info.QRen() </td>
+<td> renormalization scale Q of the hard subprocess (default definition changed)</td> </tr>
+
+<tr> <td>vint(57) </td> <td> pythia->info.alphaEM()</td>
+<td> electromagnetic coupling constant in the hard subprocess </td> </tr>
+
+<tr> <td>vint(58) </td> <td> pythia->info.alphaS()</td>
+<td> strong coupling constant in the hard subprocess </td> </tr>
+
+<tr> <td>msti(15), mint(15) </td> <td> pythia->info.id1() </td>
+<td> ID of the first incoming parton </td> </tr>
+
+<tr> <td>msti(16), mint(16) </td> <td> pythia->info.id2() </td>
+<td> ID of the second incoming parton </td> </tr>
+
+<tr> <td>pari(33), vint(41) </td> <td> pythia->info.x1() </td>
+<td> momentum fraction x of the first incoming parton </td> </tr>
+
+<tr> <td>pari(34), vint(42) </td> <td> pythia->info.x2() </td>
+<td> momentum fraction x of the second incoming parton </td> </tr>
+
+<tr> <td>pari(23), vint(53) </td> <td> pythia->info.QFac() </td>
+<td> factorization scale Q of the hard subprocess (default definition changed) </td> </tr>
+
+<tr> <td>pari(29), vint(39) </td> <td> pythia->info.pdf1() </td>
+<td> x1*f(x1) (PDF density 1) </td> </tr>
+
+<tr> <td>pari(30), vint(40) </td> <td> pythia->info.pdf2() </td>
+<td> x2*f(x2) (PDF density 2) </td> </tr>
+
+<tr> <td>pari(7), vint(97) </td> <td> pythia->info.weight()</td>
+<td> event weight (normally unity) </td> </tr>
+
+</table>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Particle Data">
+
+<h2>Particle Data</h2>
+
+The structure and operation of the particle data table is described
+<aloc href="ParticleDataScheme">here</aloc>. That page
+also describes how default data properties can be changed. The
+current page provides the actual default values.
+
+<h3>Main settings</h3>
+
+Apart from the data itself, the particle data table only contains
+a few aspects that are available to change:
+
+<modepick name="ParticleData:modeBreitWigner" default="4" min="0" max="4">
+Selection of particle masses when the <code>mass(id)</code> is called
+to provide a new mass:
+<option value="0">
+mass is fixed at the nominal <ei>m_0</ei> value.
+</option>
+<option value="1">
+particles registered as having a mass width are given a mass
+in the range <ei>m_min < m < m_max</ei>, according
+to a truncated nonrelativistic Breit-Wigner, i.e. linear in <ei>m</ei>.
+</option>
+<option value="2">
+as above, except that the width is made mass-dependent:
+<ei>Gamma = Gamma_0 * sqrt( (m^2 - m_thr^2) / (m_0^2 - m_thr^2) )</ei>
+where <ei>m</ei> is the current mass, <ei>m_0</ei> the nominal one and
+<ei>m_thr</ei> is the mass threshold, given by the sum of the nominal
+masses of the decay products. In order to decouple production and decay
+the threshold is defined as the branching-ratio-weighted average over
+all allowed decay channels.
+</option>
+<option value="3">
+particles registered as having a mass width are given a mass
+in the range <ei>m_min < m < m_max</ei>, according
+to a truncated nonrelativistic Breit-Wigner, i.e. quadratic in <ei>m</ei>.
+</option>
+<option value="4">
+as 3, but the width is modified as for 2, and the current mass is used
+for its phase-space prefactor, i.e. <ei>m_0 Gamma_0 -> m Gamma(m)</ei>.
+</option>
+<note>Note:</note> this mode only applies to normal hadronic
+resonances like the <ei>rho</ei>. The more massive states of the
+<code>isResonance()</code> type, like <ei>Z^0</ei> or top, are
+considered separately.
+</modepick>
+
+<parm name="ParticleData:maxEnhanceBW" default="2.5" min="1." max="5.">
+The modifications in options 2 and 4 above enhance the large-mass tail
+of the Breit-Wigners (the mass spectrum develops a dm/m divergence).
+However, we expect form factors to dampen this tail at masses some distance
+above the nominal one, so cut off the rise by requiring the actual
+Breit-Wigner weight not to be more than a factor <code> maxEnhanceBW</code>
+above the one obtained with options 1 or 3, respectively. This also
+opens up for a simpler technical handling of mass selection in options
+2 and 4, by using standard hit-and-miss Monte Carlo.
+</parm>
+
+<p/>
+Since running masses are only calculated for the six quark flavours,
+e.g. to obtain couplings to the Higgs boson(s), there is not an entry
+in the normal tables for each particles, but only the six MSbar mass
+values below, used as starting point for the running. In addition you
+can pick an <ei>alpha_s(M_Z)</ei>, which is converted into a first-order
+five-flavour Lambda that is used to determine the rate of the running.
+(Without any match to four flavours below <ei>m_b</ei>; if desired, this
+can be fixed by slightly shifted default mass values, since the routines
+never should be called below the <ei>m_b</ei> scale anyway.)
+
+<parm name="ParticleData:mdRun" default="0.006" min="0.003" max="0.008">
+the d quark MSbar mass at 2 GeV scale.
+
+<parm name="ParticleData:muRun" default="0.003" min="0.001" max="0.006">
+the u quark MSbar mass at 2 GeV scale.
+
+<parm name="ParticleData:msRun" default="0.095" min="0.060" max="0.150">
+the s quark MSbar mass at 2 GeV scale.
+
+<parm name="ParticleData:mcRun" default="1.25" min="1.00" max="1.50">
+the c quark MSbar mass at the mass scale itself.
+
+<parm name="ParticleData:mbRun" default="4.20" min="4.00" max="4.50">
+the b quark MSbar mass at the mass scale itself.
+
+<parm name="ParticleData:mtRun" default="165.0" min="150.0" max="175.0">
+the t quark MSbar mass at the mass scale itself.
+
+<parm name="ParticleData:alphaSvalueMRun" default="0.125" min="0.10" max="0.20">
+the <ei>alpha_s(M_Z)</ei> value used to define tha rate at which MSbar
+masses run.
+
+
+<h3>Comments on the data</h3>
+
+The starting point for the current data is the 2006 Review of Particle
+Physics <ref>Yao06</ref>. All known particle masses, widths and lifetimes
+have been set accordingly, while not-yet-measured particles are kept at
+their values from PYTHIA 6. Decay channels and their branching
+ratios remain a major worry: many particles do not have one single solidly
+measured branching ratio, and many further do not have known branching
+ratios that add up to (the neighbourhood of) unity.
+
+<p/>
+Uncertainties are especially big for the scalar, pseudovector and tensor
+<ei>L = 1</ei> multiplets available in PYTHIA. We note that
+some distributions become better described when these multiplets are
+included in the generation, while others become worse. It is tempting to
+associate this lackluster performance with the primitive knowledge.
+Not even the multiplets themselves are particularly well known.
+It used to be that the <ei>a_0(980)</ei> and <ei>f_0(980)</ei>
+were considered to be members of the scalar multiplet. Nowadays they are
+commonly assumed to be either four-quark states or of some other exotic
+character. This means that the PYTHIA 8 PDG particle codes
+have been changed for these particles, relative to what was used in
+PYTHIA 6 based on previous PDG editions. Specifically their
+numbers are now in the 9000000 series, and they have been replaced in the
+scalar multiplet by <ei>a_0(1450)</ei> and <ei>f_0(1370)</ei>.
+
+<p/>
+For charm and bottom mesons the jungle of partial measurements makes
+it very difficult to construct fully consistent sets of decay channels.
+This part of the program has not yet been brought up to date to the
+2006 RPP. Instead the LHCb decay tables (for EvtGen, but without
+using the EvtGen matrix-element machinery) and the DELPHI tune for
+PYTHIA 6 is being used. (This also includes a few non-c/b
+hadrons that only occur in the c/b decay tables.) This has the
+advantage that many tests have been made for consistency, but the
+disadvantage that it is not always in agreement with the latest
+measurements of some specific decay channels. The decays based
+on the LHCb tables (with some modifications) are 411, 421, 431, 441,
+445, 511, 521, 531, 541, 3124, 4122, 4124, 5122, 10441, 10443, 13122,
+14122, 20443, 23122, 30313, 30323, 30443, 33122, 100113, 100213, 100441,
+100443, 100553, 9000111, 9000211. Correspondingly the decays based on
+the DELPHI tables are 415, 425, 435, 515, 525, 535, 4132, 4232, 4332,
+5132, 5232 and 5332.
+
+<h3>The data itself</h3>
+
+Here comes the default particle data used in the program. Do not touch.
+The meaning of the various properties and the format used are explained
+<aloc href="ParticleDataScheme">here</aloc> and the
+<code>meMode</code> codes <aloc href="ParticleDecays">here</aloc>.
+
+<particle id="0" name="void" spinType="0" chargeType="0" colType="0" m0="0.0">
+</particle>
+
+<particle id="1" name="d" antiName="dbar" spinType="2" chargeType="-1" colType="1"
+ m0="0.33000">
+</particle>
+
+<particle id="2" name="u" antiName="ubar" spinType="2" chargeType="2" colType="1"
+ m0="0.33000">
+</particle>
+
+<particle id="3" name="s" antiName="sbar" spinType="2" chargeType="-1" colType="1"
+ m0="0.50000">
+</particle>
+
+<particle id="4" name="c" antiName="cbar" spinType="2" chargeType="2" colType="1"
+ m0="1.50000">
+</particle>
+
+<particle id="5" name="b" antiName="bbar" spinType="2" chargeType="-1" colType="1"
+ m0="4.80000">
+</particle>
+
+<particle id="6" name="t" antiName="tbar" spinType="2" chargeType="2" colType="1"
+ m0="171.00000" mWidth="1.40000" mMin="86.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000300" products="24 1"/>
+ <channel onMode="1" bRatio="0.0017650" products="24 3"/>
+ <channel onMode="1" bRatio="0.9982050" products="24 5"/>
+</particle>
+
+<particle id="7" name="b'" antiName="b'bar" spinType="2" chargeType="-1" colType="1"
+ m0="400.00000">
+ <channel onMode="1" bRatio="0.0000000" products="-24 2"/>
+ <channel onMode="1" bRatio="0.0000000" products="-24 4"/>
+ <channel onMode="1" bRatio="0.0000000" products="-24 6"/>
+ <channel onMode="1" bRatio="1.0000000" products="-24 8"/>
+</particle>
+
+<particle id="8" name="t'" antiName="t'bar" spinType="2" chargeType="2" colType="1"
+ m0="400.00000">
+ <channel onMode="1" bRatio="0.0000000" products="24 1"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 3"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 5"/>
+ <channel onMode="1" bRatio="1.0000000" products="24 7"/>
+</particle>
+
+<particle id="11" name="e-" antiName="e+" spinType="2" chargeType="-3" colType="0"
+ m0="5.110e-04">
+</particle>
+
+<particle id="12" name="nu_e" antiName="nu_ebar" spinType="2" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="13" name="mu-" antiName="mu+" spinType="2" chargeType="-3" colType="0"
+ m0="0.10566" tau0="6.58654e+05">
+ <channel onMode="1" bRatio="1.0000000" meMode="22" products="-12 11 14"/>
+</particle>
+
+<particle id="14" name="nu_mu" antiName="nu_mubar" spinType="2" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="15" name="tau-" antiName="tau+" spinType="2" chargeType="-3" colType="0"
+ m0="1.77699" tau0="8.71100e-02">
+ <channel onMode="1" bRatio="0.1784000" meMode="22" products="-12 11 16"/>
+ <channel onMode="1" bRatio="0.1736000" meMode="22" products="-14 13 16"/>
+ <channel onMode="1" bRatio="0.1090000" products="16 -211"/>
+ <channel onMode="1" bRatio="0.2520000" products="16 -213"/>
+ <channel onMode="1" bRatio="0.0030000" meMode="21" products="16 -211 111"/>
+ <channel onMode="1" bRatio="0.0900000" meMode="21" products="16 -213 111"/>
+ <channel onMode="1" bRatio="0.0025000" meMode="21" products="16 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0095000" meMode="21" products="16 -213 111 111"/>
+ <channel onMode="1" bRatio="0.0009000" meMode="21" products="16 -211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="21" products="16 -213 111 111 111"/>
+ <channel onMode="1" bRatio="0.0069100" products="16 -321"/>
+ <channel onMode="1" bRatio="0.0120000" products="16 -323"/>
+ <channel onMode="1" bRatio="0.0005200" meMode="21" products="16 -321 111"/>
+ <channel onMode="1" bRatio="0.0005800" meMode="21" products="16 -321 111 111"/>
+ <channel onMode="1" bRatio="0.0004200" meMode="21" products="16 -321 111 111 111"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="21" products="16 -311 -211"/>
+ <channel onMode="1" bRatio="0.0022000" meMode="21" products="16 -311 -213"/>
+ <channel onMode="1" bRatio="0.0016000" meMode="21" products="16 -311 -211 111"/>
+ <channel onMode="1" bRatio="0.0002600" meMode="21" products="16 -311 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0015300" meMode="21" products="16 -321 311"/>
+ <channel onMode="1" bRatio="0.0015400" meMode="21" products="16 -321 311 111"/>
+ <channel onMode="1" bRatio="0.0002400" meMode="21" products="16 310 310 -211"/>
+ <channel onMode="1" bRatio="0.0011200" meMode="21" products="16 310 130 -211"/>
+ <channel onMode="1" bRatio="0.0002400" meMode="21" products="16 130 130 -211"/>
+ <channel onMode="1" bRatio="0.0003100" meMode="21" products="16 130 130 -211 111"/>
+ <channel onMode="1" bRatio="0.0700000" meMode="21" products="16 -211 113"/>
+ <channel onMode="1" bRatio="0.0199000" meMode="21" products="16 -211 211 -211"/>
+ <channel onMode="1" bRatio="0.0269000" meMode="21" products="16 -211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0009000" meMode="21" products="16 -211 211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0002200" meMode="21" products="16 -211 211 -211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0016000" meMode="21" products="16 -321 113"/>
+ <channel onMode="1" bRatio="0.0017300" meMode="21" products="16 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0003100" meMode="21" products="16 -321 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0015300" meMode="21" products="16 -321 321 -211"/>
+ <channel onMode="1" bRatio="0.0000610" meMode="21" products="16 -321 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0008380" meMode="21" products="16 -211 211 -211 211 -211"/>
+ <channel onMode="1" bRatio="0.0001780" meMode="21" products="16 -211 211 -211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0015000" meMode="21" products="16 221 -213"/>
+ <channel onMode="1" bRatio="0.0002700" meMode="21" products="16 221 -211 111"/>
+ <channel onMode="1" bRatio="0.0001500" meMode="21" products="16 221 -213 111"/>
+ <channel onMode="1" bRatio="0.0002300" meMode="21" products="16 221 -211 211 -211"/>
+ <channel onMode="1" bRatio="0.0002700" meMode="21" products="16 221 -321"/>
+ <channel onMode="1" bRatio="0.0002900" meMode="21" products="16 221 -323"/>
+ <channel onMode="1" bRatio="0.0000800" meMode="21" products="16 221 -321 111"/>
+ <channel onMode="1" bRatio="0.0000300" meMode="21" products="16 221 -311 -211"/>
+ <channel onMode="1" bRatio="0.0178730" meMode="21" products="16 223 -211"/>
+ <channel onMode="1" bRatio="0.0004100" meMode="21" products="16 223 -321"/>
+ <channel onMode="1" bRatio="0.0041000" meMode="21" products="16 223 -211 111"/>
+ <channel onMode="1" bRatio="0.0001400" meMode="21" products="16 223 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0001200" meMode="21" products="16 223 -211 211 -211"/>
+</particle>
+
+<particle id="16" name="nu_tau" antiName="nu_taubar" spinType="2" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="17" name="tau'-" antiName="tau'+" spinType="2" chargeType="-3" colType="0"
+ m0="400.00000">
+ <channel onMode="1" bRatio="1.0000000" products="-24 18"/>
+</particle>
+
+<particle id="18" name="nu'_tau" antiName="nu'_taubar" spinType="2" chargeType="0" colType="0"
+ m0="400.00000">
+ <channel onMode="1" bRatio="1.0000000" products="24 17"/>
+</particle>
+
+<particle id="21" name="g" spinType="3" chargeType="0" colType="2"
+ m0="0.00000">
+</particle>
+
+<particle id="22" name="gamma" spinType="3" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="23" name="Z0" spinType="3" chargeType="0" colType="0"
+ m0="91.18760" mWidth="2.49520" mMin="10.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1539950" products="1 -1"/>
+ <channel onMode="1" bRatio="0.1194200" products="2 -2"/>
+ <channel onMode="1" bRatio="0.1539840" products="3 -3"/>
+ <channel onMode="1" bRatio="0.1192590" products="4 -4"/>
+ <channel onMode="1" bRatio="0.1522720" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0335760" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0668060" products="12 -12"/>
+ <channel onMode="1" bRatio="0.0335760" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0668060" products="14 -14"/>
+ <channel onMode="1" bRatio="0.0335000" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0668060" products="16 -16"/>
+</particle>
+
+<particle id="24" name="W+" antiName="W-" spinType="3" chargeType="3" colType="0"
+ m0="80.40300" mWidth="2.14100" mMin="10.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.3213690" products="-1 2"/>
+ <channel onMode="1" bRatio="0.0164940" products="-1 4"/>
+ <channel onMode="1" bRatio="0.0165020" products="-3 2"/>
+ <channel onMode="1" bRatio="0.3206150" products="-3 4"/>
+ <channel onMode="1" bRatio="0.0000100" products="-5 2"/>
+ <channel onMode="1" bRatio="0.0005910" products="-5 4"/>
+ <channel onMode="1" bRatio="0.1081660" products="-11 12"/>
+ <channel onMode="1" bRatio="0.1081660" products="-13 14"/>
+ <channel onMode="1" bRatio="0.1080870" products="-15 16"/>
+</particle>
+
+<particle id="25" name="h0(H_1)" spinType="1" chargeType="0" colType="0"
+ m0="115.00000" mWidth="0.00367" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000010" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0003490" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0487070" products="4 -4"/>
+ <channel onMode="1" bRatio="0.7683080" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0002270" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0640480" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0406210" products="21 21"/>
+ <channel onMode="1" bRatio="0.0020430" products="22 22"/>
+ <channel onMode="1" bRatio="0.0006150" products="22 23"/>
+ <channel onMode="1" bRatio="0.0069810" products="23 23"/>
+ <channel onMode="1" bRatio="0.0680990" products="24 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000025"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000025"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000035"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -1000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 -2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -1000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000002 2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -1000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 -2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -1000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000004 2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -1000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -1000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000006 2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -1000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 -2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -1000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000012 2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -1000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 -2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -1000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000014 2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -1000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 -2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -1000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -2000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -2000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000016 2000016"/>
+</particle>
+
+<particle id="32" name="Z'0" spinType="3" chargeType="0" colType="0"
+ m0="500.00000" mWidth="14.54029" mMin="10.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1458350" products="1 -1"/>
+ <channel onMode="1" bRatio="0.1132760" products="2 -2"/>
+ <channel onMode="1" bRatio="0.1458350" products="3 -3"/>
+ <channel onMode="1" bRatio="0.1132710" products="4 -4"/>
+ <channel onMode="1" bRatio="0.1457810" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0490020" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0320250" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0636420" products="12 -12"/>
+ <channel onMode="1" bRatio="0.0320250" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0636420" products="14 -14"/>
+ <channel onMode="1" bRatio="0.0320220" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0636420" products="16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 -24"/>
+</particle>
+
+<particle id="33" name="Z''0" spinType="3" chargeType="0" colType="0"
+ m0="900.00000">
+</particle>
+
+<particle id="34" name="W'+" antiName="W'-" spinType="3" chargeType="3" colType="0"
+ m0="500.00000" mWidth="16.66099" mMin="10.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.2512250" products="-1 2"/>
+ <channel onMode="1" bRatio="0.0129000" products="-1 4"/>
+ <channel onMode="1" bRatio="0.0000060" products="-1 6"/>
+ <channel onMode="1" bRatio="0.0129000" products="-3 2"/>
+ <channel onMode="1" bRatio="0.2507640" products="-3 4"/>
+ <channel onMode="1" bRatio="0.0003800" products="-3 6"/>
+ <channel onMode="1" bRatio="0.0000080" products="-5 2"/>
+ <channel onMode="1" bRatio="0.0004650" products="-5 4"/>
+ <channel onMode="1" bRatio="0.2154180" products="-5 6"/>
+ <channel onMode="1" bRatio="0.0853120" products="-11 12"/>
+ <channel onMode="1" bRatio="0.0853120" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0853100" products="-15 16"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 23"/>
+</particle>
+
+<particle id="35" name="H0(H_2)" spinType="1" chargeType="0" colType="0"
+ m0="300.00000" mWidth="8.38842" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0000490" products="4 -4"/>
+ <channel onMode="1" bRatio="0.0007740" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0000740" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0004170" products="21 21"/>
+ <channel onMode="1" bRatio="0.0000150" products="22 22"/>
+ <channel onMode="1" bRatio="0.0000610" products="22 23"/>
+ <channel onMode="1" bRatio="0.3067100" products="23 23"/>
+ <channel onMode="1" bRatio="0.6890110" products="24 -24"/>
+ <channel onMode="1" bRatio="0.0000000" products="23 25"/>
+ <channel onMode="1" bRatio="0.0028890" products="25 25"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 -37"/>
+ <channel onMode="1" bRatio="0.0000000" products="37 -24"/>
+ <channel onMode="1" bRatio="0.0000000" products="23 36"/>
+ <channel onMode="1" bRatio="0.0000000" products="25 36"/>
+ <channel onMode="1" bRatio="0.0000000" products="36 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000025"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000025"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000035"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -1000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 -2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -1000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000002 2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -1000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 -2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -1000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000004 2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -1000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -1000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000006 2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -1000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 -2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -1000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000012 2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -1000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 -2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -1000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000014 2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -1000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 -2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -1000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -2000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -2000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000016 2000016"/>
+</particle>
+
+<particle id="36" name="A0(H_3)" spinType="1" chargeType="0" colType="0"
+ m0="300.00000" mWidth="3.37520" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0000010" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0001210" products="4 -4"/>
+ <channel onMode="1" bRatio="0.0019240" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0000010" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0001840" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0031060" products="21 21"/>
+ <channel onMode="1" bRatio="0.0000150" products="22 22"/>
+ <channel onMode="1" bRatio="0.0000030" products="22 23"/>
+ <channel onMode="1" bRatio="0.0000000" products="23 23"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 -24"/>
+ <channel onMode="1" bRatio="0.9946460" products="23 25"/>
+ <channel onMode="1" bRatio="0.0000000" products="25 25"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 -37"/>
+ <channel onMode="1" bRatio="0.0000000" products="37 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000025"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000022"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000023"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000025"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000035"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -1000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 -2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 2000001"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -1000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000002 2000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -1000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 -2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 2000003"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -1000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000004 2000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -1000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -1000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000006 2000006"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -1000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 -2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 2000011"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -1000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000012 2000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -1000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 -2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 2000013"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -1000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000014 2000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -1000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 -2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 2000015"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -1000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -2000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -2000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000016 2000016"/>
+</particle>
+
+<particle id="37" name="H+" antiName="H-" spinType="1" chargeType="3" colType="0"
+ m0="300.00000" mWidth="4.17669" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" products="-1 2"/>
+ <channel onMode="1" bRatio="0.0000210" products="-3 4"/>
+ <channel onMode="1" bRatio="0.0901350" products="-5 6"/>
+ <channel onMode="1" bRatio="0.0000000" products="-11 12"/>
+ <channel onMode="1" bRatio="0.0000130" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0037140" products="-15 16"/>
+ <channel onMode="1" bRatio="0.9061170" products="24 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000024"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1000037"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -1000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -1000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -2000005"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 1000002"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 1000004"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 1000012"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 1000014"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 1000016"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000015 1000016"/>
+</particle>
+
+<particle id="39" name="Graviton" spinType="5" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="40" name="BlackHole" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="41" name="R0" antiName="Rbar0" spinType="3" chargeType="0" colType="0"
+ m0="5.000e+03" mWidth="4.173e+02" mMin="1.000e+02" mMax="0.000e+00">
+ <channel onMode="1" bRatio="0.2151190" products="1 -3"/>
+ <channel onMode="1" bRatio="0.2151190" products="2 -4"/>
+ <channel onMode="1" bRatio="0.2151190" products="3 -5"/>
+ <channel onMode="1" bRatio="0.2147240" products="4 -6"/>
+ <channel onMode="1" bRatio="0.0699600" products="11 -13"/>
+ <channel onMode="1" bRatio="0.0699590" products="13 -15"/>
+</particle>
+
+<particle id="42" name="LQ_ue" antiName="LQ_uebar" spinType="1" chargeType="-1" colType="1"
+ m0="200.00000" mWidth="0.39162" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="1.0000000" products="2 11"/>
+</particle>
+
+<particle id="81" name="specflav" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="82" name="rndmflavq" antiName="rndmflavqbar" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+
+<particle id="83" name="rndmflavg" antiName="rndmflavgbar" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+</particle>
+
+<particle id="90" name="system" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="110" name="reggeon" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="111" name="pi0" spinType="1" chargeType="0" colType="0"
+ m0="0.13498" tau0="2.51000e-05">
+ <channel onMode="1" bRatio="0.9879900" products="22 22"/>
+ <channel onMode="1" bRatio="0.0119800" meMode="11" products="22 11 -11"/>
+ <channel onMode="1" bRatio="0.0000300" meMode="13" products="11 -11 11 -11"/>
+</particle>
+
+<particle id="113" name="rho0" spinType="3" chargeType="0" colType="0"
+ m0="0.77550" mWidth="0.14700" mMin="0.30000" mMax="1.50000">
+ <channel onMode="1" bRatio="0.9988485" meMode="2" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0006000" products="111 22"/>
+ <channel onMode="1" bRatio="0.0002950" products="221 22"/>
+ <channel onMode="1" bRatio="0.0001010" meMode="1" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000470" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0000455" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0000450" products="111 111 22"/>
+ <channel onMode="1" bRatio="0.0000180" products="211 -211 211 -211"/>
+</particle>
+
+<particle id="115" name="a_20" spinType="5" chargeType="0" colType="0"
+ m0="1.31830" mWidth="0.10700" mMin="1.00000" mMax="1.70000">
+ <channel onMode="1" bRatio="0.3483455" products="213 -211"/>
+ <channel onMode="1" bRatio="0.3483455" products="-213 211"/>
+ <channel onMode="1" bRatio="0.1440000" products="221 111"/>
+ <channel onMode="1" bRatio="0.1050000" products="223 211 -211"/>
+ <channel onMode="1" bRatio="0.0245000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0122500" products="130 130"/>
+ <channel onMode="1" bRatio="0.0122500" products="310 310"/>
+ <channel onMode="1" bRatio="0.0053000" products="331 111"/>
+ <channel onMode="1" bRatio="0.0000090" products="22 22"/>
+</particle>
+
+<particle id="130" name="K_L0" spinType="1" chargeType="0" colType="0"
+ m0="0.49765" tau0="1.53300e+04">
+ <channel onMode="1" bRatio="0.1955770" products="111 111 111"/>
+ <channel onMode="1" bRatio="0.1255900" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.2026300" meMode="22" products="-12 11 211"/>
+ <channel onMode="1" bRatio="0.2026300" meMode="22" products="12 -11 -211"/>
+ <channel onMode="1" bRatio="0.1350900" meMode="22" products="-14 13 211"/>
+ <channel onMode="1" bRatio="0.1350900" meMode="22" products="14 -13 -211"/>
+ <channel onMode="1" bRatio="0.0019760" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0008690" products="111 111"/>
+ <channel onMode="1" bRatio="0.0005480" products="22 22"/>
+</particle>
+
+<particle id="211" name="pi+" antiName="pi-" spinType="1" chargeType="3" colType="0"
+ m0="0.13957" tau0="7.80450e+03">
+ <channel onMode="1" bRatio="0.9998770" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0001230" products="-11 12"/>
+</particle>
+
+<particle id="213" name="rho+" antiName="rho-" spinType="3" chargeType="3" colType="0"
+ m0="0.77540" mWidth="0.14940" mMin="0.30000" mMax="1.50000">
+ <channel onMode="1" bRatio="0.9995500" meMode="2" products="211 111"/>
+ <channel onMode="1" bRatio="0.0004500" products="211 22"/>
+</particle>
+
+<particle id="215" name="a_2+" antiName="a_2-" spinType="5" chargeType="3" colType="0"
+ m0="1.31830" mWidth="0.10700" mMin="1.00000" mMax="1.70000">
+ <channel onMode="1" bRatio="0.3480100" products="213 111"/>
+ <channel onMode="1" bRatio="0.3480100" products="113 211"/>
+ <channel onMode="1" bRatio="0.1440000" products="221 211"/>
+ <channel onMode="1" bRatio="0.1040000" products="223 211 111"/>
+ <channel onMode="1" bRatio="0.0480000" products="321 -311"/>
+ <channel onMode="1" bRatio="0.0053000" products="331 211"/>
+ <channel onMode="1" bRatio="0.0026800" products="211 22"/>
+</particle>
+
+<particle id="221" name="eta" spinType="1" chargeType="0" colType="0"
+ m0="0.54751">
+ <channel onMode="1" bRatio="0.3938240" products="22 22"/>
+ <channel onMode="1" bRatio="0.3251200" products="111 111 111"/>
+ <channel onMode="1" bRatio="0.0004400" products="111 22 22"/>
+ <channel onMode="1" bRatio="0.2270000" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.0469000" products="211 -211 22"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="11" products="22 11 -11"/>
+ <channel onMode="1" bRatio="0.0003100" meMode="11" products="22 13 -13"/>
+ <channel onMode="1" bRatio="0.0000060" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0004000" meMode="12" products="211 -211 11 -11"/>
+</particle>
+
+<particle id="223" name="omega" spinType="3" chargeType="0" colType="0"
+ m0="0.78265" mWidth="0.00849" mMin="0.50000" mMax="1.10000">
+ <channel onMode="1" bRatio="0.8924150" meMode="1" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.0890000" products="111 22"/>
+ <channel onMode="1" bRatio="0.0170000" meMode="2" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0004900" products="221 22"/>
+ <channel onMode="1" bRatio="0.0007700" meMode="11" products="111 11 -11"/>
+ <channel onMode="1" bRatio="0.0000960" meMode="11" products="111 13 -13"/>
+ <channel onMode="1" bRatio="0.0000720" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0000900" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0000670" products="111 111 22"/>
+</particle>
+
+<particle id="225" name="f_2" spinType="5" chargeType="0" colType="0"
+ m0="1.27540" mWidth="0.18500" mMin="0.60000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.5653260" products="211 -211"/>
+ <channel onMode="1" bRatio="0.2826600" products="111 111"/>
+ <channel onMode="1" bRatio="0.0710000" products="211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0280000" products="211 -211 211 -211"/>
+ <channel onMode="1" bRatio="0.0230000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0115000" products="130 130"/>
+ <channel onMode="1" bRatio="0.0115000" products="310 310"/>
+ <channel onMode="1" bRatio="0.0040000" products="221 221"/>
+ <channel onMode="1" bRatio="0.0030000" products="111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000140" products="22 22"/>
+</particle>
+
+<particle id="310" name="K_S0" spinType="1" chargeType="0" colType="0"
+ m0="0.49765" tau0="2.68420e+01">
+ <channel onMode="1" bRatio="0.6923500" products="211 -211"/>
+ <channel onMode="1" bRatio="0.3069000" products="111 111"/>
+ <channel onMode="1" bRatio="0.0000470" meMode="12" products="211 -211 11 -11"/>
+ <channel onMode="1" bRatio="0.0003500" meMode="22" products="-12 11 211"/>
+ <channel onMode="1" bRatio="0.0003500" meMode="22" products="12 -11 -211"/>
+ <channel onMode="1" bRatio="0.0000030" products="22 22"/>
+</particle>
+
+<particle id="311" name="K0" antiName="Kbar0" spinType="1" chargeType="0" colType="0"
+ m0="0.49765">
+ <channel onMode="1" bRatio="0.5000000" products="130"/>
+ <channel onMode="1" bRatio="0.5000000" products="310"/>
+</particle>
+
+<particle id="313" name="K*0" antiName="K*bar0" spinType="3" chargeType="0" colType="0"
+ m0="0.89600" mWidth="0.05030" mMin="0.65000" mMax="1.20000">
+ <channel onMode="1" bRatio="0.6650000" meMode="2" products="321 -211"/>
+ <channel onMode="1" bRatio="0.3326900" meMode="2" products="311 111"/>
+ <channel onMode="1" bRatio="0.0023100" products="311 22"/>
+</particle>
+
+<particle id="315" name="K*_2(1430)0" antiName="K*_2(1430)bar0" spinType="5" chargeType="0" colType="0"
+ m0="1.43240" mWidth="0.10900" mMin="1.10000" mMax="1.80000">
+ <channel onMode="1" bRatio="0.3340000" products="321 -211"/>
+ <channel onMode="1" bRatio="0.1670000" products="311 111"/>
+ <channel onMode="1" bRatio="0.1650000" products="323 -211"/>
+ <channel onMode="1" bRatio="0.0825000" products="313 111"/>
+ <channel onMode="1" bRatio="0.0890000" products="323 -211 111"/>
+ <channel onMode="1" bRatio="0.0450000" products="313 211 -211"/>
+ <channel onMode="1" bRatio="0.0580000" products="321 -213"/>
+ <channel onMode="1" bRatio="0.0290000" products="311 113"/>
+ <channel onMode="1" bRatio="0.0290000" products="311 223"/>
+ <channel onMode="1" bRatio="0.0015000" products="311 221"/>
+</particle>
+
+<particle id="321" name="K+" antiName="K-" spinType="1" chargeType="3" colType="0"
+ m0="0.49368" tau0="3.71300e+03">
+ <channel onMode="1" bRatio="0.6343000" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0000150" products="-11 12"/>
+ <channel onMode="1" bRatio="0.2091100" products="211 111"/>
+ <channel onMode="1" bRatio="0.0559000" products="211 211 -211"/>
+ <channel onMode="1" bRatio="0.0175700" products="211 111 111"/>
+ <channel onMode="1" bRatio="0.0498000" meMode="22" products="12 -11 111"/>
+ <channel onMode="1" bRatio="0.0332000" meMode="22" products="14 -13 111"/>
+ <channel onMode="1" bRatio="0.0000220" products="-11 12 111 111"/>
+ <channel onMode="1" bRatio="0.0000410" products="-11 12 211 -211"/>
+ <channel onMode="1" bRatio="0.0000140" products="-13 14 111 111"/>
+ <channel onMode="1" bRatio="0.0000280" products="-13 14 211 -211"/>
+</particle>
+
+<particle id="323" name="K*+" antiName="K*-" spinType="3" chargeType="3" colType="0"
+ m0="0.89166" mWidth="0.05080" mMin="0.65000" mMax="1.20000">
+ <channel onMode="1" bRatio="0.6660000" meMode="2" products="311 211"/>
+ <channel onMode="1" bRatio="0.3330000" meMode="2" products="321 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="321 22"/>
+</particle>
+
+<particle id="325" name="K*_2(1430)+" antiName="K*_2(1430)-" spinType="5" chargeType="3" colType="0"
+ m0="1.42560" mWidth="0.09850" mMin="1.10000" mMax="1.80000">
+ <channel onMode="1" bRatio="0.3330000" products="311 211"/>
+ <channel onMode="1" bRatio="0.1660000" products="321 111"/>
+ <channel onMode="1" bRatio="0.1647000" products="313 211"/>
+ <channel onMode="1" bRatio="0.0824000" products="323 111"/>
+ <channel onMode="1" bRatio="0.0890000" products="313 211 111"/>
+ <channel onMode="1" bRatio="0.0450000" products="323 211 -211"/>
+ <channel onMode="1" bRatio="0.0580000" products="311 213"/>
+ <channel onMode="1" bRatio="0.0290000" products="321 113"/>
+ <channel onMode="1" bRatio="0.0290000" products="321 223"/>
+ <channel onMode="1" bRatio="0.0015000" products="321 221"/>
+ <channel onMode="1" bRatio="0.0024000" products="321 22"/>
+</particle>
+
+<particle id="331" name="eta'" spinType="1" chargeType="0" colType="0"
+ m0="0.95778" mWidth="0.00020" mMin="0.95578" mMax="0.95978">
+ <channel onMode="1" bRatio="0.4449000" products="211 -211 221"/>
+ <channel onMode="1" bRatio="0.2939500" products="113 22"/>
+ <channel onMode="1" bRatio="0.2080000" products="111 111 221"/>
+ <channel onMode="1" bRatio="0.0303000" products="223 22"/>
+ <channel onMode="1" bRatio="0.0212000" products="22 22"/>
+ <channel onMode="1" bRatio="0.0015500" products="111 111 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="13 -13 22"/>
+</particle>
+
+<particle id="333" name="phi" spinType="3" chargeType="0" colType="0"
+ m0="1.01946" mWidth="0.00426" mMin="1.00000" mMax="1.04000">
+ <channel onMode="1" bRatio="0.4919270" meMode="2" products="321 -321"/>
+ <channel onMode="1" bRatio="0.3400000" meMode="2" products="130 310"/>
+ <channel onMode="1" bRatio="0.0420000" products="-213 211"/>
+ <channel onMode="1" bRatio="0.0420000" products="113 111"/>
+ <channel onMode="1" bRatio="0.0420000" products="213 -211"/>
+ <channel onMode="1" bRatio="0.0270000" meMode="1" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.0130000" products="221 22"/>
+ <channel onMode="1" bRatio="0.0012500" products="111 22"/>
+ <channel onMode="1" bRatio="0.0002970" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0002860" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0001150" meMode="11" products="221 11 -11"/>
+ <channel onMode="1" bRatio="0.0000730" meMode="2" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0000520" products="223 111"/>
+</particle>
+
+<particle id="335" name="f'_2(1525)" spinType="5" chargeType="0" colType="0"
+ m0="1.52500" mWidth="0.07300" mMin="1.10000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.4444000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.2222000" products="130 130"/>
+ <channel onMode="1" bRatio="0.2222000" products="310 310"/>
+ <channel onMode="1" bRatio="0.1030000" products="221 221"/>
+ <channel onMode="1" bRatio="0.0041000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0041000" products="111 111"/>
+</particle>
+
+<particle id="411" name="D+" antiName="D-" spinType="1" chargeType="3" colType="0"
+ m0="1.86930" tau0="3.11800e-01">
+ <channel onMode="1" bRatio="0.0004000" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0010000" products="-15 16"/>
+ <channel onMode="1" bRatio="0.0043000" meMode="22" products="-11 12 111"/>
+ <channel onMode="1" bRatio="0.0028000" meMode="22" products="-11 12 113"/>
+ <channel onMode="1" bRatio="0.0026000" meMode="22" products="-11 12 221"/>
+ <channel onMode="1" bRatio="0.0028000" meMode="22" products="-11 12 223"/>
+ <channel onMode="1" bRatio="0.0900000" meMode="22" products="-11 12 311"/>
+ <channel onMode="1" bRatio="0.0554000" meMode="22" products="-11 12 -313"/>
+ <channel onMode="1" bRatio="0.0038000" meMode="22" products="-11 12 -315"/>
+ <channel onMode="1" bRatio="0.0005000" meMode="22" products="-11 12 331"/>
+ <channel onMode="1" bRatio="0.0036000" meMode="22" products="-11 12 -10313"/>
+ <channel onMode="1" bRatio="0.0043000" meMode="22" products="-13 14 111"/>
+ <channel onMode="1" bRatio="0.0028000" meMode="22" products="-13 14 113"/>
+ <channel onMode="1" bRatio="0.0026000" meMode="22" products="-13 14 221"/>
+ <channel onMode="1" bRatio="0.0028000" meMode="22" products="-13 14 223"/>
+ <channel onMode="1" bRatio="0.0874000" meMode="22" products="-13 14 311"/>
+ <channel onMode="1" bRatio="0.0533000" meMode="22" products="-13 14 -313"/>
+ <channel onMode="1" bRatio="0.0038000" meMode="22" products="-13 14 -315"/>
+ <channel onMode="1" bRatio="0.0005000" meMode="22" products="-13 14 331"/>
+ <channel onMode="1" bRatio="0.0036000" meMode="22" products="-13 14 -10313"/>
+ <channel onMode="1" bRatio="0.0014000" meMode="22" products="-11 12 311 111"/>
+ <channel onMode="1" bRatio="0.0027000" meMode="22" products="-11 12 -321 211"/>
+ <channel onMode="1" bRatio="0.0014000" meMode="22" products="-13 14 311 111"/>
+ <channel onMode="1" bRatio="0.0027000" meMode="22" products="-13 14 -321 211"/>
+ <channel onMode="1" bRatio="0.0026000" products="211 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="211 113"/>
+ <channel onMode="1" bRatio="0.0076000" products="221 211"/>
+ <channel onMode="1" bRatio="0.0282000" products="311 211"/>
+ <channel onMode="1" bRatio="0.0210000" products="-313 213"/>
+ <channel onMode="1" bRatio="0.0074000" products="321 311"/>
+ <channel onMode="1" bRatio="0.0042000" products="321 -313"/>
+ <channel onMode="1" bRatio="0.0310000" products="323 311"/>
+ <channel onMode="1" bRatio="0.0180000" products="323 -313"/>
+ <channel onMode="1" bRatio="0.0070000" products="333 211"/>
+ <channel onMode="1" bRatio="0.0115000" products="-10311 211"/>
+ <channel onMode="1" bRatio="0.0800000" products="20213 311"/>
+ <channel onMode="1" bRatio="0.0508000" products="-20313 211"/>
+ <channel onMode="1" bRatio="0.0015000" products="211 111 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="211 211 -211"/>
+ <channel onMode="1" bRatio="0.0030000" products="221 211 111"/>
+ <channel onMode="1" bRatio="0.0970000" products="311 211 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="311 211 113"/>
+ <channel onMode="1" bRatio="0.0100000" products="311 221 211"/>
+ <channel onMode="1" bRatio="0.0050000" products="311 223 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="311 311 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="313 311 211"/>
+ <channel onMode="1" bRatio="0.0100000" products="-313 211 111"/>
+ <channel onMode="1" bRatio="0.0078000" products="-313 211 113"/>
+ <channel onMode="1" bRatio="0.0100000" products="-313 221 211"/>
+ <channel onMode="1" bRatio="0.0050000" products="-313 223 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="-313 311 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="321 311 111"/>
+ <channel onMode="1" bRatio="0.0100000" products="321 311 311"/>
+ <channel onMode="1" bRatio="0.0010000" products="321 -313 111"/>
+ <channel onMode="1" bRatio="0.0046000" products="321 -321 211"/>
+ <channel onMode="1" bRatio="0.0920000" products="-321 211 211"/>
+ <channel onMode="1" bRatio="0.0110000" products="-321 213 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="323 311 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="323 -321 211"/>
+ <channel onMode="1" bRatio="0.0070000" products="-323 211 211"/>
+ <channel onMode="1" bRatio="0.0100000" products="-323 213 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="-323 321 211"/>
+ <channel onMode="1" bRatio="0.0230000" products="333 211 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0090000" products="211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="221 211 111 111"/>
+ <channel onMode="1" bRatio="0.0030000" products="221 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0188000" products="311 211 111 111"/>
+ <channel onMode="1" bRatio="0.0120000" products="-321 211 211 111"/>
+ <channel onMode="1" bRatio="0.0021000" products="211 211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0035000" products="311 211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0087000" products="311 211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="-321 211 211 111 111"/>
+ <channel onMode="1" bRatio="0.0022000" products="-321 211 211 211 -211"/>
+</particle>
+
+<particle id="413" name="D*+" antiName="D*-" spinType="3" chargeType="3" colType="0"
+ m0="2.01000">
+ <channel onMode="1" bRatio="0.6770000" meMode="2" products="421 211"/>
+ <channel onMode="1" bRatio="0.3070000" meMode="2" products="411 111"/>
+ <channel onMode="1" bRatio="0.0160000" products="411 22"/>
+</particle>
+
+<particle id="415" name="D*_2(2460)+" antiName="D*_2(2460)-" spinType="5" chargeType="3" colType="0"
+ m0="2.45900" mWidth="0.02900" mMin="2.30000" mMax="2.65000">
+ <channel onMode="1" bRatio="0.2200000" products="423 211"/>
+ <channel onMode="1" bRatio="0.1100000" products="413 111"/>
+ <channel onMode="1" bRatio="0.3800000" products="421 211"/>
+ <channel onMode="1" bRatio="0.1900000" products="411 111"/>
+ <channel onMode="1" bRatio="0.0670000" products="423 211 111"/>
+ <channel onMode="1" bRatio="0.0330000" products="413 211 -211"/>
+</particle>
+
+<particle id="421" name="D0" antiName="Dbar0" spinType="1" chargeType="0" colType="0"
+ m0="1.86450" tau0="1.22900e-01">
+ <channel onMode="1" bRatio="0.0034000" meMode="22" products="-11 12 -211"/>
+ <channel onMode="1" bRatio="0.0022000" meMode="22" products="-11 12 -213"/>
+ <channel onMode="1" bRatio="0.0350000" meMode="22" products="-11 12 -321"/>
+ <channel onMode="1" bRatio="0.0225000" meMode="22" products="-11 12 -323"/>
+ <channel onMode="1" bRatio="0.0015000" meMode="22" products="-11 12 -325"/>
+ <channel onMode="1" bRatio="0.0014000" meMode="22" products="-11 12 -10323"/>
+ <channel onMode="1" bRatio="0.0034000" meMode="22" products="-13 14 -211"/>
+ <channel onMode="1" bRatio="0.0022000" meMode="22" products="-13 14 -213"/>
+ <channel onMode="1" bRatio="0.0340000" meMode="22" products="-13 14 -321"/>
+ <channel onMode="1" bRatio="0.0214000" meMode="22" products="-13 14 -323"/>
+ <channel onMode="1" bRatio="0.0015000" meMode="22" products="-13 14 -325"/>
+ <channel onMode="1" bRatio="0.0014000" meMode="22" products="-13 14 -10323"/>
+ <channel onMode="1" bRatio="0.0011000" meMode="22" products="-11 12 311 -211"/>
+ <channel onMode="1" bRatio="0.0006000" meMode="22" products="-11 12 -321 111"/>
+ <channel onMode="1" bRatio="0.0011000" meMode="22" products="-13 14 311 -211"/>
+ <channel onMode="1" bRatio="0.0006000" meMode="22" products="-13 14 -321 111"/>
+ <channel onMode="1" bRatio="0.0008000" products="111 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="113 111"/>
+ <channel onMode="1" bRatio="0.0006000" products="130 130"/>
+ <channel onMode="1" bRatio="0.0015000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0040000" products="213 -211"/>
+ <channel onMode="1" bRatio="0.0040000" products="-213 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="221 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="221 221"/>
+ <channel onMode="1" bRatio="0.0006000" products="310 310"/>
+ <channel onMode="1" bRatio="0.0212000" products="311 111"/>
+ <channel onMode="1" bRatio="0.0071000" products="311 221"/>
+ <channel onMode="1" bRatio="0.0210000" products="311 223"/>
+ <channel onMode="1" bRatio="0.0004000" products="313 311"/>
+ <channel onMode="1" bRatio="0.0014000" products="313 -313"/>
+ <channel onMode="1" bRatio="0.0085000" products="-313 111"/>
+ <channel onMode="1" bRatio="0.0146000" products="-313 113"/>
+ <channel onMode="1" bRatio="0.0190000" products="-313 221"/>
+ <channel onMode="1" bRatio="0.0110000" products="-313 223"/>
+ <channel onMode="1" bRatio="0.0008000" products="-313 311"/>
+ <channel onMode="1" bRatio="0.0001500" products="321 -211"/>
+ <channel onMode="1" bRatio="0.0043000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0383000" products="-321 211"/>
+ <channel onMode="1" bRatio="0.0035000" products="323 -321"/>
+ <channel onMode="1" bRatio="0.0610000" products="-323 213"/>
+ <channel onMode="1" bRatio="0.0018000" products="-323 321"/>
+ <channel onMode="1" bRatio="0.0010000" products="331 111"/>
+ <channel onMode="1" bRatio="0.0172000" products="331 311"/>
+ <channel onMode="1" bRatio="0.0020000" products="331 -313"/>
+ <channel onMode="1" bRatio="0.0007000" products="333 111"/>
+ <channel onMode="1" bRatio="0.0086000" products="333 311"/>
+ <channel onMode="1" bRatio="0.0071000" products="-10313 111"/>
+ <channel onMode="1" bRatio="0.0107000" products="-10323 211"/>
+ <channel onMode="1" bRatio="0.0730000" products="20213 -321"/>
+ <channel onMode="1" bRatio="0.0010000" products="111 111 111"/>
+ <channel onMode="1" bRatio="0.0060000" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.0270000" products="211 -211 130"/>
+ <channel onMode="1" bRatio="0.0270000" products="310 211 -211"/>
+ <channel onMode="1" bRatio="0.0008000" products="310 310 310"/>
+ <channel onMode="1" bRatio="0.0078000" products="311 111 111"/>
+ <channel onMode="1" bRatio="0.0116000" products="-313 111 111"/>
+ <channel onMode="1" bRatio="0.0225000" products="-313 211 -211"/>
+ <channel onMode="1" bRatio="0.0005000" products="321 -211 111"/>
+ <channel onMode="1" bRatio="0.0051000" products="321 -321 311"/>
+ <channel onMode="1" bRatio="0.1390000" products="-321 211 111"/>
+ <channel onMode="1" bRatio="0.0060000" products="-321 211 113"/>
+ <channel onMode="1" bRatio="0.0068000" products="-321 213 111"/>
+ <channel onMode="1" bRatio="0.0100000" products="-321 221 211"/>
+ <channel onMode="1" bRatio="0.0303000" products="-321 223 211"/>
+ <channel onMode="1" bRatio="0.0100000" products="-323 211 111"/>
+ <channel onMode="1" bRatio="0.0075000" products="331 -321 211"/>
+ <channel onMode="1" bRatio="0.0011000" products="333 211 -211"/>
+ <channel onMode="1" bRatio="0.0073000" products="211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0050000" products="211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0143000" products="311 111 111 111"/>
+ <channel onMode="1" bRatio="0.0085000" products="311 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0015000" products="311 311 111 111"/>
+ <channel onMode="1" bRatio="0.0015000" products="311 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0030000" products="321 -321 111 111"/>
+ <channel onMode="1" bRatio="0.0025000" products="321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0257500" products="-321 211 111 111"/>
+ <channel onMode="1" bRatio="0.0074000" products="-321 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0177000" products="211 211 -211 -211 111"/>
+ <channel onMode="1" bRatio="0.0060000" products="211 -211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0058000" products="311 211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0638000" products="311 211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0038000" products="-321 211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0038000" products="-321 211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0192000" products="311 211 -211 111 111 111"/>
+</particle>
+
+<particle id="423" name="D*0" antiName="D*bar0" spinType="3" chargeType="0" colType="0"
+ m0="2.00670">
+ <channel onMode="1" bRatio="0.6190000" meMode="2" products="421 111"/>
+ <channel onMode="1" bRatio="0.3810000" products="421 22"/>
+</particle>
+
+<particle id="425" name="D*_2(2460)0" antiName="D*_2(2460)bar0" spinType="5" chargeType="0" colType="0"
+ m0="2.46110" mWidth="0.04300" mMin="2.30000" mMax="2.65000">
+ <channel onMode="1" bRatio="0.2200000" products="413 -211"/>
+ <channel onMode="1" bRatio="0.1100000" products="423 111"/>
+ <channel onMode="1" bRatio="0.3800000" products="411 -211"/>
+ <channel onMode="1" bRatio="0.1900000" products="421 111"/>
+ <channel onMode="1" bRatio="0.0670000" products="413 -211 111"/>
+ <channel onMode="1" bRatio="0.0330000" products="423 211 -211"/>
+</particle>
+
+<particle id="431" name="D_s+" antiName="D_s-" spinType="1" chargeType="3" colType="0"
+ m0="1.96820" tau0="1.49900e-01">
+ <channel onMode="1" bRatio="0.0061600" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0640000" products="-15 16"/>
+ <channel onMode="1" bRatio="0.0307000" meMode="22" products="-11 12 221"/>
+ <channel onMode="1" bRatio="0.0027000" meMode="22" products="-11 12 311"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="-11 12 -313"/>
+ <channel onMode="1" bRatio="0.0106000" meMode="22" products="-11 12 331"/>
+ <channel onMode="1" bRatio="0.0242000" meMode="22" products="-11 12 333"/>
+ <channel onMode="1" bRatio="0.0307000" meMode="22" products="-13 14 221"/>
+ <channel onMode="1" bRatio="0.0027000" meMode="22" products="-13 14 311"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="-13 14 -313"/>
+ <channel onMode="1" bRatio="0.0106000" meMode="22" products="-13 14 331"/>
+ <channel onMode="1" bRatio="0.0242000" meMode="22" products="-13 14 333"/>
+ <channel onMode="1" bRatio="0.0010000" products="211 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="211 113"/>
+ <channel onMode="1" bRatio="0.0004000" products="213 111"/>
+ <channel onMode="1" bRatio="0.0210000" products="221 211"/>
+ <channel onMode="1" bRatio="0.1310400" products="221 213"/>
+ <channel onMode="1" bRatio="0.0034000" products="223 211"/>
+ <channel onMode="1" bRatio="0.0023000" products="225 211"/>
+ <channel onMode="1" bRatio="0.0040000" products="311 211"/>
+ <channel onMode="1" bRatio="0.0015000" products="311 213"/>
+ <channel onMode="1" bRatio="0.0079000" products="313 211"/>
+ <channel onMode="1" bRatio="0.0050000" products="313 213"/>
+ <channel onMode="1" bRatio="0.0015000" products="321 113"/>
+ <channel onMode="1" bRatio="0.0002000" products="321 221"/>
+ <channel onMode="1" bRatio="0.0440000" products="321 311"/>
+ <channel onMode="1" bRatio="0.0400000" products="321 -313"/>
+ <channel onMode="1" bRatio="0.0530000" products="323 311"/>
+ <channel onMode="1" bRatio="0.0700000" products="323 -313"/>
+ <channel onMode="1" bRatio="0.0470000" products="331 211"/>
+ <channel onMode="1" bRatio="0.1220000" products="331 213"/>
+ <channel onMode="1" bRatio="0.0002000" products="331 321"/>
+ <channel onMode="1" bRatio="0.0440000" products="333 211"/>
+ <channel onMode="1" bRatio="0.0820000" products="333 213"/>
+ <channel onMode="1" bRatio="0.0003000" products="333 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="20213 311"/>
+ <channel onMode="1" bRatio="0.0100000" products="9010221 211"/>
+ <channel onMode="1" bRatio="0.0000500" products="211 111 111"/>
+ <channel onMode="1" bRatio="0.0000500" products="211 211 -211"/>
+ <channel onMode="1" bRatio="0.0150000" products="221 211 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="311 211 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="313 211 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="321 221 111"/>
+ <channel onMode="1" bRatio="0.0030000" products="321 311 111"/>
+ <channel onMode="1" bRatio="0.0012000" products="321 -313 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="321 321 -321"/>
+ <channel onMode="1" bRatio="0.0110000" products="321 -321 211"/>
+ <channel onMode="1" bRatio="0.0012000" products="323 311 111"/>
+ <channel onMode="1" bRatio="0.0040000" products="323 -313 111"/>
+ <channel onMode="1" bRatio="0.0150000" products="331 211 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="331 321 111"/>
+ <channel onMode="1" bRatio="0.0100000" products="333 211 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="221 211 111 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="221 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="321 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0010000" products="321 311 111 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="321 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="331 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0050000" products="333 211 111 111"/>
+ <channel onMode="1" bRatio="0.0080000" products="333 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0043000" products="321 -321 211 211 -211"/>
+</particle>
+
+<particle id="433" name="D*_s+" antiName="D*_s-" spinType="3" chargeType="3" colType="0"
+ m0="2.11200">
+ <channel onMode="1" bRatio="0.9420000" products="431 22"/>
+ <channel onMode="1" bRatio="0.0580000" meMode="2" products="431 111"/>
+</particle>
+
+<particle id="435" name="D*_2s(2573)+" antiName="D*_2s(2573)-" spinType="5" chargeType="3" colType="0"
+ m0="2.57350" mWidth="0.01500" mMin="2.51000" mMax="2.70000">
+ <channel onMode="1" bRatio="0.0500000" products="413 311"/>
+ <channel onMode="1" bRatio="0.0500000" products="423 321"/>
+ <channel onMode="1" bRatio="0.4500000" products="411 311"/>
+ <channel onMode="1" bRatio="0.4500000" products="421 321"/>
+</particle>
+
+<particle id="441" name="eta_c" spinType="1" chargeType="0" colType="0"
+ m0="2.98040" mWidth="0.02550" mMin="2.78040" mMax="3.18040">
+ <channel onMode="1" bRatio="0.0002800" products="22 22"/>
+ <channel onMode="1" bRatio="0.0087000" products="113 113"/>
+ <channel onMode="1" bRatio="0.0173000" products="213 -213"/>
+ <channel onMode="1" bRatio="0.0042000" products="313 -313"/>
+ <channel onMode="1" bRatio="0.0043000" products="323 -323"/>
+ <channel onMode="1" bRatio="0.0026000" products="333 333"/>
+ <channel onMode="1" bRatio="0.0013000" products="2212 -2212"/>
+ <channel onMode="1" bRatio="0.0163000" products="221 111 111"/>
+ <channel onMode="1" bRatio="0.0327000" products="221 211 -211"/>
+ <channel onMode="1" bRatio="0.0095000" products="311 311 111"/>
+ <channel onMode="1" bRatio="0.0191000" products="321 311 -211"/>
+ <channel onMode="1" bRatio="0.0072000" products="321 -313 -211"/>
+ <channel onMode="1" bRatio="0.0095000" products="321 -321 111"/>
+ <channel onMode="1" bRatio="0.0191000" products="-321 311 211"/>
+ <channel onMode="1" bRatio="0.0072000" products="-321 313 211"/>
+ <channel onMode="1" bRatio="0.0137000" products="331 111 111"/>
+ <channel onMode="1" bRatio="0.0273000" products="331 211 -211"/>
+ <channel onMode="1" bRatio="0.0018000" products="333 321 -321"/>
+ <channel onMode="1" bRatio="0.0033000" products="211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0006000" products="321 321 -321 -321"/>
+ <channel onMode="1" bRatio="0.0054000" products="321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.7886200" meMode="52" products="83 -83"/>
+</particle>
+
+<particle id="443" name="J/psi" spinType="3" chargeType="0" colType="0"
+ m0="3.09692" mWidth="0.00009" mMin="3.09602" mMax="3.09782">
+ <channel onMode="1" bRatio="0.8023950" meMode="43" products="83 -83"/>
+ <channel onMode="1" bRatio="0.0594000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0593000" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0130000" products="441 22"/>
+ <channel onMode="1" bRatio="0.0056000" products="113 111"/>
+ <channel onMode="1" bRatio="0.0056500" products="213 -211"/>
+ <channel onMode="1" bRatio="0.0056500" products="-213 211"/>
+ <channel onMode="1" bRatio="0.0036000" products="115 113"/>
+ <channel onMode="1" bRatio="0.0036000" products="-215 213"/>
+ <channel onMode="1" bRatio="0.0036000" products="215 -213"/>
+ <channel onMode="1" bRatio="0.0043000" products="225 223"/>
+ <channel onMode="1" bRatio="0.0022000" products="313 -315"/>
+ <channel onMode="1" bRatio="0.0022000" products="323 -325"/>
+ <channel onMode="1" bRatio="0.0022000" products="-323 325"/>
+ <channel onMode="1" bRatio="0.0025000" products="321 -323"/>
+ <channel onMode="1" bRatio="0.0025000" products="-321 323"/>
+ <channel onMode="1" bRatio="0.0021000" products="311 -313"/>
+ <channel onMode="1" bRatio="0.0021000" products="-311 313"/>
+ <channel onMode="1" bRatio="0.0019000" products="20323 -321"/>
+ <channel onMode="1" bRatio="0.0019000" products="-20323 321"/>
+ <channel onMode="1" bRatio="0.0015000" products="10213 -211"/>
+ <channel onMode="1" bRatio="0.0015000" products="-10213 211"/>
+ <channel onMode="1" bRatio="0.0023000" products="10113 111"/>
+ <channel onMode="1" bRatio="0.0004800" products="10331 223"/>
+ <channel onMode="1" bRatio="0.0007400" products="223 221"/>
+ <channel onMode="1" bRatio="0.0003600" products="10331 333"/>
+ <channel onMode="1" bRatio="0.0008000" products="333 335"/>
+ <channel onMode="1" bRatio="0.0006800" products="20333 223"/>
+ <channel onMode="1" bRatio="0.0007400" products="333 221"/>
+ <channel onMode="1" bRatio="0.0004500" products="223 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="333 331"/>
+ <channel onMode="1" bRatio="0.0003200" products="333 9010221"/>
+ <channel onMode="1" bRatio="0.0002600" products="333 20223"/>
+ <channel onMode="1" bRatio="0.0001930" products="113 221"/>
+ <channel onMode="1" bRatio="0.0001820" products="223 331"/>
+ <channel onMode="1" bRatio="0.0001400" products="223 9010221"/>
+ <channel onMode="1" bRatio="0.0001050" products="113 331"/>
+ <channel onMode="1" bRatio="0.0011000" products="2224 -2224"/>
+ <channel onMode="1" bRatio="0.0005150" products="3112 -3112"/>
+ <channel onMode="1" bRatio="0.0005900" products="3314 -3314"/>
+ <channel onMode="1" bRatio="0.0003200" products="3324 -3324"/>
+ <channel onMode="1" bRatio="0.0003200" products="3324 -3324"/>
+ <channel onMode="1" bRatio="0.0001550" products="3114 -3114"/>
+ <channel onMode="1" bRatio="0.0001550" products="3224 -3224"/>
+</particle>
+
+<particle id="445" name="chi_2c" spinType="5" chargeType="0" colType="0"
+ m0="3.55620" mWidth="0.00206" mMin="3.53620" mMax="3.57620">
+ <channel onMode="1" bRatio="0.0002590" products="22 22"/>
+ <channel onMode="1" bRatio="0.2020000" products="443 22"/>
+ <channel onMode="1" bRatio="0.0008900" products="130 130"/>
+ <channel onMode="1" bRatio="0.0018000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0008900" products="310 310"/>
+ <channel onMode="1" bRatio="0.0047000" products="313 -313"/>
+ <channel onMode="1" bRatio="0.0009000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0024000" products="333 333"/>
+ <channel onMode="1" bRatio="0.0000680" products="2212 -2212"/>
+ <channel onMode="1" bRatio="0.0003000" products="3122 -3122"/>
+ <channel onMode="1" bRatio="0.0046000" products="211 -211 113"/>
+ <channel onMode="1" bRatio="0.0046000" products="213 -211 111"/>
+ <channel onMode="1" bRatio="0.0046000" products="-213 211 111"/>
+ <channel onMode="1" bRatio="0.0015000" products="321 -313 -211"/>
+ <channel onMode="1" bRatio="0.0015000" products="-321 313 211"/>
+ <channel onMode="1" bRatio="0.0016000" products="323 311 -211"/>
+ <channel onMode="1" bRatio="0.0016000" products="-323 311 211"/>
+ <channel onMode="1" bRatio="0.0102000" products="211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0003000" products="310 310 211 -211"/>
+ <channel onMode="1" bRatio="0.0012000" products="321 321 -321 -321"/>
+ <channel onMode="1" bRatio="0.0103000" products="321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0003000" products="321 -321 310 310"/>
+ <channel onMode="1" bRatio="0.0017000" products="2212 -2212 211 -211"/>
+ <channel onMode="1" bRatio="0.0107000" products="211 211 211 -211 -211 -211"/>
+ <channel onMode="1" bRatio="0.7310930" meMode="52" products="83 -83"/>
+</particle>
+
+<particle id="511" name="B0" antiName="Bbar0" spinType="1" chargeType="0" colType="0"
+ m0="5.27940" tau0="4.58700e-01">
+ <channel onMode="1" bRatio="0.0001330" meMode="22" products="12 -11 -211"/>
+ <channel onMode="1" bRatio="0.0002690" meMode="22" products="12 -11 -213"/>
+ <channel onMode="1" bRatio="0.0207000" meMode="22" products="12 -11 -411"/>
+ <channel onMode="1" bRatio="0.0570000" meMode="22" products="12 -11 -413"/>
+ <channel onMode="1" bRatio="0.0023000" meMode="22" products="12 -11 -415"/>
+ <channel onMode="1" bRatio="0.0045000" meMode="22" products="12 -11 -10411"/>
+ <channel onMode="1" bRatio="0.0052000" meMode="22" products="12 -11 -10413"/>
+ <channel onMode="1" bRatio="0.0083000" meMode="22" products="12 -11 -20413"/>
+ <channel onMode="1" bRatio="0.0001330" meMode="22" products="14 -13 -211"/>
+ <channel onMode="1" bRatio="0.0002690" meMode="22" products="14 -13 -213"/>
+ <channel onMode="1" bRatio="0.0207000" meMode="22" products="14 -13 -411"/>
+ <channel onMode="1" bRatio="0.0570000" meMode="22" products="14 -13 -413"/>
+ <channel onMode="1" bRatio="0.0023000" meMode="22" products="14 -13 -415"/>
+ <channel onMode="1" bRatio="0.0045000" meMode="22" products="14 -13 -10411"/>
+ <channel onMode="1" bRatio="0.0052000" meMode="22" products="14 -13 -10413"/>
+ <channel onMode="1" bRatio="0.0083000" meMode="22" products="14 -13 -20413"/>
+ <channel onMode="1" bRatio="0.0000600" meMode="22" products="16 -15 -211"/>
+ <channel onMode="1" bRatio="0.0000830" meMode="22" products="16 -15 -213"/>
+ <channel onMode="1" bRatio="0.0000080" meMode="22" products="16 -15 -215"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="16 -15 -411"/>
+ <channel onMode="1" bRatio="0.0160000" meMode="22" products="16 -15 -413"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="16 -15 -415"/>
+ <channel onMode="1" bRatio="0.0000080" meMode="22" products="16 -15 -10213"/>
+ <channel onMode="1" bRatio="0.0013000" meMode="22" products="16 -15 -10411"/>
+ <channel onMode="1" bRatio="0.0013000" meMode="22" products="16 -15 -10413"/>
+ <channel onMode="1" bRatio="0.0000900" meMode="22" products="16 -15 -20213"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="16 -15 -20413"/>
+ <channel onMode="1" bRatio="0.0000080" meMode="22" products="16 -15 -9000211"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="12 -11 -411 111"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="12 -11 -413 111"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="12 -11 -421 -211"/>
+ <channel onMode="1" bRatio="0.0007000" meMode="22" products="12 -11 -423 -211"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="14 -13 -411 111"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="14 -13 -413 111"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="14 -13 -421 -211"/>
+ <channel onMode="1" bRatio="0.0007000" meMode="22" products="14 -13 -423 -211"/>
+ <channel onMode="1" bRatio="0.0000015" products="111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="113 113"/>
+ <channel onMode="1" bRatio="0.0000060" products="130 111"/>
+ <channel onMode="1" bRatio="0.0000026" products="130 113"/>
+ <channel onMode="1" bRatio="0.0000006" products="130 130"/>
+ <channel onMode="1" bRatio="0.0000046" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0000300" products="213 -213"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 130"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 221"/>
+ <channel onMode="1" bRatio="0.0000005" products="223 22"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 113"/>
+ <channel onMode="1" bRatio="0.0000023" products="223 130"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 223"/>
+ <channel onMode="1" bRatio="0.0000060" products="310 111"/>
+ <channel onMode="1" bRatio="0.0000026" products="310 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="310 221"/>
+ <channel onMode="1" bRatio="0.0000023" products="310 223"/>
+ <channel onMode="1" bRatio="0.0000006" products="310 310"/>
+ <channel onMode="1" bRatio="0.0000401" products="313 22"/>
+ <channel onMode="1" bRatio="0.0000017" products="313 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 113"/>
+ <channel onMode="1" bRatio="0.0000190" products="313 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 223"/>
+ <channel onMode="1" bRatio="0.0000030" products="313 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 -313"/>
+ <channel onMode="1" bRatio="0.0000180" products="321 -211"/>
+ <channel onMode="1" bRatio="0.0000099" products="321 -213"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0000130" products="323 -211"/>
+ <channel onMode="1" bRatio="0.0000200" products="323 -213"/>
+ <channel onMode="1" bRatio="0.0000020" products="323 -321"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -323"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 113"/>
+ <channel onMode="1" bRatio="0.0000320" products="331 130"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 223"/>
+ <channel onMode="1" bRatio="0.0000320" products="331 310"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 331"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 113"/>
+ <channel onMode="1" bRatio="0.0000042" products="333 130"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 223"/>
+ <channel onMode="1" bRatio="0.0000042" products="333 310"/>
+ <channel onMode="1" bRatio="0.0000110" products="333 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 331"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 333"/>
+ <channel onMode="1" bRatio="0.0002700" products="411 -411"/>
+ <channel onMode="1" bRatio="0.0028000" products="-411 211"/>
+ <channel onMode="1" bRatio="0.0077000" products="-411 213"/>
+ <channel onMode="1" bRatio="0.0002000" products="-411 321"/>
+ <channel onMode="1" bRatio="0.0003700" products="-411 323"/>
+ <channel onMode="1" bRatio="0.0003350" products="413 -411"/>
+ <channel onMode="1" bRatio="0.0008300" products="413 -413"/>
+ <channel onMode="1" bRatio="0.0028000" products="-413 211"/>
+ <channel onMode="1" bRatio="0.0068000" products="-413 213"/>
+ <channel onMode="1" bRatio="0.0001700" products="-413 321"/>
+ <channel onMode="1" bRatio="0.0003800" products="-413 323"/>
+ <channel onMode="1" bRatio="0.0003350" products="-413 411"/>
+ <channel onMode="1" bRatio="0.0009000" products="-415 211"/>
+ <channel onMode="1" bRatio="0.0022000" products="-415 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="421 313"/>
+ <channel onMode="1" bRatio="0.0002900" products="-421 111"/>
+ <channel onMode="1" bRatio="0.0002900" products="-421 113"/>
+ <channel onMode="1" bRatio="0.0002200" products="-421 221"/>
+ <channel onMode="1" bRatio="0.0002500" products="-421 223"/>
+ <channel onMode="1" bRatio="0.0000400" products="-421 311"/>
+ <channel onMode="1" bRatio="0.0000400" products="-421 313"/>
+ <channel onMode="1" bRatio="0.0001700" products="-421 331"/>
+ <channel onMode="1" bRatio="0.0000100" products="423 313"/>
+ <channel onMode="1" bRatio="0.0002700" products="-423 111"/>
+ <channel onMode="1" bRatio="0.0002900" products="-423 113"/>
+ <channel onMode="1" bRatio="0.0002600" products="-423 221"/>
+ <channel onMode="1" bRatio="0.0004200" products="-423 223"/>
+ <channel onMode="1" bRatio="0.0000400" products="-423 311"/>
+ <channel onMode="1" bRatio="0.0000400" products="-423 313"/>
+ <channel onMode="1" bRatio="0.0001700" products="-423 331"/>
+ <channel onMode="1" bRatio="0.0000390" products="431 -211"/>
+ <channel onMode="1" bRatio="0.0000160" products="431 -213"/>
+ <channel onMode="1" bRatio="0.0090000" products="431 -411"/>
+ <channel onMode="1" bRatio="0.0126000" products="431 -413"/>
+ <channel onMode="1" bRatio="0.0042000" products="431 -415"/>
+ <channel onMode="1" bRatio="0.0000460" products="-431 321"/>
+ <channel onMode="1" bRatio="0.0000160" products="-431 323"/>
+ <channel onMode="1" bRatio="0.0000260" products="433 -211"/>
+ <channel onMode="1" bRatio="0.0000160" products="433 -213"/>
+ <channel onMode="1" bRatio="0.0090000" products="433 -411"/>
+ <channel onMode="1" bRatio="0.0240000" products="433 -413"/>
+ <channel onMode="1" bRatio="0.0040000" products="433 -415"/>
+ <channel onMode="1" bRatio="0.0000160" products="-433 321"/>
+ <channel onMode="1" bRatio="0.0000160" products="-433 323"/>
+ <channel onMode="1" bRatio="0.0006000" products="441 130"/>
+ <channel onMode="1" bRatio="0.0006000" products="441 310"/>
+ <channel onMode="1" bRatio="0.0016200" products="441 313"/>
+ <channel onMode="1" bRatio="0.0000220" products="443 111"/>
+ <channel onMode="1" bRatio="0.0000160" products="443 113"/>
+ <channel onMode="1" bRatio="0.0004400" products="443 130"/>
+ <channel onMode="1" bRatio="0.0000300" products="443 223"/>
+ <channel onMode="1" bRatio="0.0004400" products="443 310"/>
+ <channel onMode="1" bRatio="0.0005000" products="443 315"/>
+ <channel onMode="1" bRatio="0.0000300" products="445 313"/>
+ <channel onMode="1" bRatio="0.0000001" products="2212 -2212"/>
+ <channel onMode="1" bRatio="0.0000010" products="10113 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="10113 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="10113 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="10113 331"/>
+ <channel onMode="1" bRatio="0.0000100" products="10213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10213 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10213 321"/>
+ <channel onMode="1" bRatio="0.0000010" products="10311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 113"/>
+ <channel onMode="1" bRatio="0.0000030" products="10311 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 333"/>
+ <channel onMode="1" bRatio="0.0015000" products="10313 443"/>
+ <channel onMode="1" bRatio="0.0000010" products="10321 -211"/>
+ <channel onMode="1" bRatio="0.0000200" products="10321 -213"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 -321"/>
+ <channel onMode="1" bRatio="0.0002000" products="-10411 211"/>
+ <channel onMode="1" bRatio="0.0006000" products="-10413 211"/>
+ <channel onMode="1" bRatio="0.0004000" products="-10413 213"/>
+ <channel onMode="1" bRatio="0.0012000" products="-10413 431"/>
+ <channel onMode="1" bRatio="0.0024000" products="-10413 433"/>
+ <channel onMode="1" bRatio="0.0016000" products="10431 -411"/>
+ <channel onMode="1" bRatio="0.0016000" products="10431 -413"/>
+ <channel onMode="1" bRatio="0.0001500" products="10441 130"/>
+ <channel onMode="1" bRatio="0.0001500" products="10441 310"/>
+ <channel onMode="1" bRatio="0.0003000" products="10441 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="20113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="20113 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 223"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 311"/>
+ <channel onMode="1" bRatio="0.0000200" products="20113 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="20113 331"/>
+ <channel onMode="1" bRatio="0.0000500" products="20113 20113"/>
+ <channel onMode="1" bRatio="0.0000400" products="20213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 -213"/>
+ <channel onMode="1" bRatio="0.0083400" products="20213 -411"/>
+ <channel onMode="1" bRatio="0.0120000" products="20213 -413"/>
+ <channel onMode="1" bRatio="0.0000500" products="20213 -20213"/>
+ <channel onMode="1" bRatio="0.0000400" products="-20213 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-20213 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="-20213 321"/>
+ <channel onMode="1" bRatio="0.0000200" products="-20213 323"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 333"/>
+ <channel onMode="1" bRatio="0.0001000" products="20313 443"/>
+ <channel onMode="1" bRatio="0.0001000" products="-20413 211"/>
+ <channel onMode="1" bRatio="0.0013000" products="-20413 213"/>
+ <channel onMode="1" bRatio="0.0006000" products="-20413 431"/>
+ <channel onMode="1" bRatio="0.0012000" products="-20413 433"/>
+ <channel onMode="1" bRatio="0.0041000" products="20433 -411"/>
+ <channel onMode="1" bRatio="0.0098000" products="20433 -413"/>
+ <channel onMode="1" bRatio="0.0002300" products="20443 130"/>
+ <channel onMode="1" bRatio="0.0002300" products="20443 310"/>
+ <channel onMode="1" bRatio="0.0003000" products="20443 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="30313 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="30313 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="30323 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="30323 -321"/>
+ <channel onMode="1" bRatio="0.0002400" products="30443 130"/>
+ <channel onMode="1" bRatio="0.0002400" products="30443 310"/>
+ <channel onMode="1" bRatio="0.0004800" products="30443 313"/>
+ <channel onMode="1" bRatio="0.0002900" products="30443 10313"/>
+ <channel onMode="1" bRatio="0.0000005" products="100113 130"/>
+ <channel onMode="1" bRatio="0.0000005" products="100113 310"/>
+ <channel onMode="1" bRatio="0.0002400" products="100441 130"/>
+ <channel onMode="1" bRatio="0.0002400" products="100441 310"/>
+ <channel onMode="1" bRatio="0.0006600" products="100441 313"/>
+ <channel onMode="1" bRatio="0.0003300" products="100443 130"/>
+ <channel onMode="1" bRatio="0.0003300" products="100443 310"/>
+ <channel onMode="1" bRatio="0.0006600" products="100443 313"/>
+ <channel onMode="1" bRatio="0.0004000" products="100443 10313"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 223"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 311"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000111 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 331"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 10113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 20113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 9000111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="9000211 -213"/>
+ <channel onMode="1" bRatio="0.0000030" products="-9000211 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-9000211 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="-9000211 321"/>
+ <channel onMode="1" bRatio="0.0000050" products="-9000211 323"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 223"/>
+ <channel onMode="1" bRatio="0.0000060" products="9010221 311"/>
+ <channel onMode="1" bRatio="0.0000050" products="9010221 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 331"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 10113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 20113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 9000111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 9010221"/>
+ <channel onMode="1" bRatio="0.0000010" products="111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="113 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="113 113 111"/>
+ <channel onMode="1" bRatio="0.0000240" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000030" products="211 -211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="213 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="213 -213 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="-213 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 111 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="221 113 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 113 113"/>
+ <channel onMode="1" bRatio="0.0000170" products="221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 213 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 213 -213"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 -213 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 221 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="221 221 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="223 113 111"/>
+ <channel onMode="1" bRatio="0.0000030" products="223 211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="223 221 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="223 221 113"/>
+ <channel onMode="1" bRatio="0.0000002" products="223 221 221"/>
+ <channel onMode="1" bRatio="0.0000006" meMode="11" products="311 11 -11"/>
+ <channel onMode="1" bRatio="0.0000006" meMode="11" products="311 13 -13"/>
+ <channel onMode="1" bRatio="0.0000001" meMode="11" products="311 15 -15"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 113 111"/>
+ <channel onMode="1" bRatio="0.0000260" products="311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 -213 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 221 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 221"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 223 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 223 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 223"/>
+ <channel onMode="1" bRatio="0.0000480" products="311 311 311"/>
+ <channel onMode="1" bRatio="0.0000018" meMode="11" products="313 11 -11"/>
+ <channel onMode="1" bRatio="0.0000014" meMode="11" products="313 13 -13"/>
+ <channel onMode="1" bRatio="0.0000002" meMode="11" products="313 15 -15"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 -213 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="313 221 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 223 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="313 223 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 -313 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="313 -313 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="-313 311 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -213 111"/>
+ <channel onMode="1" bRatio="0.0000200" products="321 221 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 221 -213"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 223 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 311 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 -213"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -313 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 223"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 313"/>
+ <channel onMode="1" bRatio="0.0000005" products="-321 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 311 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 313 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 -211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 -213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 221 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 221 -213"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 223 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 311 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -313 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 -321 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -323 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="323 -323 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 313 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="-323 321 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 113 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 113 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 213 -213"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 221 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 221 113"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 223 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 223 113"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 223 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 223"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 311"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 313 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 313 223"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 313 -313"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 -213"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 -321"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 -213"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 323 -323"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 331 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 113 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 213 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 -213 211"/>
+ <channel onMode="1" bRatio="0.0000005" products="333 221 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 223 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 223"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 311 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 313 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="333 313 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 -213"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 321 -321"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 323 -211"/>
+ <channel onMode="1" bRatio="0.0000002" products="333 331 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="333 331 313"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 333 111"/>
+ <channel onMode="1" bRatio="0.0000030" products="333 333 311"/>
+ <channel onMode="1" bRatio="0.0000030" products="333 333 313"/>
+ <channel onMode="1" bRatio="0.0015000" products="411 -411 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="411 -411 313"/>
+ <channel onMode="1" bRatio="0.0005000" products="-411 211 111"/>
+ <channel onMode="1" bRatio="0.0011000" products="-411 211 113"/>
+ <channel onMode="1" bRatio="0.0011000" products="-411 213 111"/>
+ <channel onMode="1" bRatio="0.0047000" products="413 -411 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="413 -411 313"/>
+ <channel onMode="1" bRatio="0.0070000" products="413 -413 311"/>
+ <channel onMode="1" bRatio="0.0050000" products="413 -413 313"/>
+ <channel onMode="1" bRatio="0.0008000" products="-413 211 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="-413 211 113"/>
+ <channel onMode="1" bRatio="0.0010000" products="-413 213 111"/>
+ <channel onMode="1" bRatio="0.0018000" products="-413 411 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="-413 411 313"/>
+ <channel onMode="1" bRatio="0.0017000" products="421 -411 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="421 -411 323"/>
+ <channel onMode="1" bRatio="0.0031000" products="421 -413 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="421 -413 323"/>
+ <channel onMode="1" bRatio="0.0005000" products="421 -421 311"/>
+ <channel onMode="1" bRatio="0.0005000" products="421 -421 313"/>
+ <channel onMode="1" bRatio="0.0005000" products="-421 211 -211"/>
+ <channel onMode="1" bRatio="0.0049000" products="423 -411 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="423 -411 323"/>
+ <channel onMode="1" bRatio="0.0100000" products="423 -413 321"/>
+ <channel onMode="1" bRatio="0.0050000" products="423 -413 323"/>
+ <channel onMode="1" bRatio="0.0005000" products="423 -421 313"/>
+ <channel onMode="1" bRatio="0.0015000" products="423 -423 311"/>
+ <channel onMode="1" bRatio="0.0010000" products="423 -423 313"/>
+ <channel onMode="1" bRatio="0.0005000" products="-423 111 111"/>
+ <channel onMode="1" bRatio="0.0003000" products="-423 211 -211"/>
+ <channel onMode="1" bRatio="0.0005000" products="-423 421 313"/>
+ <channel onMode="1" bRatio="0.0018000" products="431 -411 111"/>
+ <channel onMode="1" bRatio="0.0037000" products="431 -421 -211"/>
+ <channel onMode="1" bRatio="0.0018000" products="433 -411 111"/>
+ <channel onMode="1" bRatio="0.0037000" products="433 -421 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 311 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="441 321 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="443 311 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="443 321 -211"/>
+ <channel onMode="1" bRatio="0.0000900" products="443 333 311"/>
+ <channel onMode="1" bRatio="0.0001000" products="445 311 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="445 321 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 -213 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 221 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 321 -321"/>
+ <channel onMode="1" bRatio="0.0000020" products="10311 331 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 333 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 -211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 -213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10321 221 -213"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 -321 311"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 331 -213"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 333 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10321 321 311"/>
+ <channel onMode="1" bRatio="0.0001000" products="10441 311 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="10441 321 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="20113 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 321 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20113 331 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="20213 221 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 311 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20213 331 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-20213 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="-20213 221 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-20213 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-20213 321 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="-20213 331 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 321 -321"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 333 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="20313 333 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="20313 333 331"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 333 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 311 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="20443 321 -211"/>
+ <channel onMode="1" bRatio="0.0001400" products="30443 311 111"/>
+ <channel onMode="1" bRatio="0.0001400" products="30443 321 -211"/>
+ <channel onMode="1" bRatio="0.0000500" products="100441 311 111"/>
+ <channel onMode="1" bRatio="0.0000800" products="100441 321 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 311 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="100443 321 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000111 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000111 213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000111 -213 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000111 221 113"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000111 313 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="9000111 313 221"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000111 323 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="9000111 331 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 331 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000211 -211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000211 -213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000211 221 -213"/>
+ <channel onMode="1" bRatio="0.0000020" products="9000211 331 -213"/>
+ <channel onMode="1" bRatio="0.0000010" products="-9000211 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="-9000211 211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="-9000211 213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="-9000211 221 213"/>
+ <channel onMode="1" bRatio="0.0000050" products="-9000211 323 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="-9000211 323 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="-9000211 331 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="-9000211 331 323"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 113 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 -213 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="9010221 221 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 223 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 313 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="9010221 313 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 323 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 331 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 331 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 333 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 333 311"/>
+ <channel onMode="1" bRatio="0.0000020" products="113 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="211 -211 113 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="213 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="213 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="-213 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="-213 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 113 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 211 -211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 213 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 -213 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="221 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="223 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="223 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 113 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 211 -211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 213 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 -213 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 113 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 213 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 -213 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 221 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 223 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 223 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 223 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 113 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 213 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 -213 211"/>
+ <channel onMode="1" bRatio="0.0000005" products="311 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="311 311 221 113"/>
+ <channel onMode="1" bRatio="0.0000002" products="311 311 221 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 223 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000001" products="311 311 311 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="313 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="313 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="313 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-313 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-313 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="-313 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -211 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 213 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -213 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -213 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 221 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 221 -211 113"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 221 -213 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 221 221 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 223 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 223 221 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 -211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 -213 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 311 221 -213"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 223 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 313 311 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -313 -211 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -313 221 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -313 311 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 321 -321 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 321 -321 -213"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 321 -321 -321"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 113 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 213 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 -213 211"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -321 221 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -321 221 113"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 -321 221 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 223 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -321 223 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 113"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 -321 311 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 223"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 -321 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 311 211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 311 213 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="-321 311 221 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 311 223 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 313 211 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="-321 313 221 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 221 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 311 -211 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="323 311 221 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 311 311 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 321 -321 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -321 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="323 -321 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="-323 311 221 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 321 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="-323 321 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="-323 321 321 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 113 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 211 -211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 213 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 -213 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 223 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 223 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 113 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 213 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 -213 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 223 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 311 311 113"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 313 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 313 211 -211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 313 311 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 -313 311 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 -211 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 -213 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 221 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 223 -211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 311 -213"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -313 -211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -321 113"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 -321 221"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -321 223"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 -321 311 213"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 -321 313 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 -211 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 323 311 -211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 323 -321 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 -323 311 211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 -323 321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="333 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="333 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="333 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 311 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 313 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 -313 311 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="333 321 221 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 321 311 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 -321 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 -321 313"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 -323 321 311"/>
+ <channel onMode="1" bRatio="0.0000002" products="333 331 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="333 331 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="333 331 311 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="333 331 321 -211"/>
+ <channel onMode="1" bRatio="0.0010000" products="-411 211 111 111"/>
+ <channel onMode="1" bRatio="0.0022000" products="-411 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0010000" products="-413 211 111 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="-421 111 111 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="-421 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="-423 111 111 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="-423 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0022000" products="431 -411 111 111"/>
+ <channel onMode="1" bRatio="0.0030000" products="431 -411 211 -211"/>
+ <channel onMode="1" bRatio="0.0022000" products="431 -421 -211 111"/>
+ <channel onMode="1" bRatio="0.0022000" products="433 -411 111 111"/>
+ <channel onMode="1" bRatio="0.0030000" products="433 -411 211 -211"/>
+ <channel onMode="1" bRatio="0.0022000" products="433 -421 -211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 311 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="441 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="445 311 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="445 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="445 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 321 311 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 321 -321 221"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 331 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="10311 331 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="10311 331 311 311"/>
+ <channel onMode="1" bRatio="0.0000020" products="10311 331 321 -321"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10311 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="-10311 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10311 321 311 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="-10311 331 311 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10321 221 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 311 311 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 321 -321 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 331 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10321 321 321 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="10441 311 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="10441 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="10441 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="20313 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="20313 321 -321 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="20313 331 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="20313 331 321 -321"/>
+ <channel onMode="1" bRatio="0.0000020" products="-20313 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-20313 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="-20313 331 311 311"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 321 -321 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="-20323 321 321 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 311 111 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="20443 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000700" products="30443 311 111 111"/>
+ <channel onMode="1" bRatio="0.0001400" products="30443 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000700" products="30443 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000500" products="100441 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000800" products="100441 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000500" products="100441 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="100443 311 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="100443 321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-9000211 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-9000211 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 321 311 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 321 -321 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 331 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 331 211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="111 111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="211 211 -211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="211 -211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="221 111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="221 211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="221 211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="311 311 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="311 311 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="311 311 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="311 311 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 311 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 311 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 311 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="311 311 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 211 -211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 -211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 221 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 221 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 311 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 311 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 311 221 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 311 311 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 311 311 221 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 311 311 311 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 321 -321 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 321 -321 221 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 321 -321 311 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 321 -321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 321 -321 -321 311"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 -321 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 -321 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 -321 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 -321 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 -321 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 -321 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 -321 311 311 311"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 -321 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0000002" products="-321 311 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="-321 311 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="-321 311 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="-321 311 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 311 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 311 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 311 -211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 311 311 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 321 -321 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 -321 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="331 321 -321 311 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 -321 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 311 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 321 311 311 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 321 321 -321 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="333 321 -321 311 111"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="55" products="-3 1"/>
+ <channel onMode="1" bRatio="0.0110000" meMode="63" products="-4101 2101"/>
+ <channel onMode="1" bRatio="0.0220000" meMode="63" products="-4103 2103"/>
+ <channel onMode="1" bRatio="0.0030000" meMode="63" products="-4301 2101"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="63" products="-4303 2103"/>
+ <channel onMode="1" bRatio="0.0000700" meMode="23" products="1 -1 -1 1"/>
+ <channel onMode="1" bRatio="0.0018000" meMode="23" products="1 -1 -3 1"/>
+ <channel onMode="1" bRatio="0.0030000" meMode="23" products="2 -1 -2 1"/>
+ <channel onMode="1" bRatio="0.0020500" meMode="23" products="2 -2 -1 1"/>
+ <channel onMode="1" bRatio="0.0022000" meMode="23" products="2 -2 -3 1"/>
+ <channel onMode="1" bRatio="0.0210000" meMode="63" products="2 -3 -4 1"/>
+ <channel onMode="1" bRatio="0.0180000" meMode="23" products="2 -4 -1 1"/>
+ <channel onMode="1" bRatio="0.0009000" meMode="23" products="2 -4 -3 1"/>
+ <channel onMode="1" bRatio="0.0000900" meMode="23" products="3 -3 -1 1"/>
+ <channel onMode="1" bRatio="0.0015000" meMode="23" products="3 -3 -3 1"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="43" products="4 -1 -4 1"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="23" products="4 -3 -2 1"/>
+ <channel onMode="1" bRatio="0.0740000" meMode="43" products="4 -3 -4 1"/>
+ <channel onMode="2" bRatio="0.0018920" meMode="22" products="12 -11 1 -2"/>
+ <channel onMode="2" bRatio="0.0018920" meMode="22" products="14 -13 1 -2"/>
+ <channel onMode="2" bRatio="0.0012910" products="443 313"/>
+ <channel onMode="2" bRatio="0.0000500" products="445 130"/>
+ <channel onMode="2" bRatio="0.0000500" products="445 310"/>
+ <channel onMode="2" bRatio="0.0000100" products="213 -211 113"/>
+ <channel onMode="2" bRatio="0.0000100" products="223 213 -211"/>
+ <channel onMode="2" bRatio="0.0000067" products="313 111 111"/>
+ <channel onMode="2" bRatio="0.0000100" products="321 -211 113"/>
+ <channel onMode="2" bRatio="0.0000010" products="321 -321 130"/>
+ <channel onMode="2" bRatio="0.0000010" products="321 -321 310"/>
+ <channel onMode="2" bRatio="0.0000070" products="333 311 221"/>
+ <channel onMode="2" bRatio="0.0005000" products="423 -421 311"/>
+ <channel onMode="2" bRatio="0.0015000" products="-423 421 311"/>
+ <channel onMode="2" bRatio="0.0000050" products="9000211 313 -211"/>
+ <channel onMode="2" bRatio="0.0003118" meMode="31" products="1 -3 22"/>
+ <channel onMode="2" bRatio="0.0000050" meMode="12" products="1 -3 11 -11"/>
+ <channel onMode="2" bRatio="0.0000025" meMode="12" products="1 -3 13 -13"/>
+ <channel onMode="2" bRatio="0.0000002" meMode="12" products="1 -3 15 -15"/>
+ <channel onMode="2" bRatio="0.3158500" meMode="23" products="2 -1 -4 1"/>
+ <channel onMode="3" bRatio="0.0018920" meMode="22" products="12 -11 -2 1"/>
+ <channel onMode="3" bRatio="0.0018920" meMode="22" products="14 -13 -2 1"/>
+ <channel onMode="3" bRatio="0.0012310" products="443 313"/>
+ <channel onMode="3" bRatio="0.0000100" products="445 130"/>
+ <channel onMode="3" bRatio="0.0000100" products="445 310"/>
+ <channel onMode="3" bRatio="0.0000100" products="-213 211 113"/>
+ <channel onMode="3" bRatio="0.0000100" products="223 -213 211"/>
+ <channel onMode="3" bRatio="0.0000067" products="-313 111 111"/>
+ <channel onMode="3" bRatio="0.0000050" products="321 -211 113"/>
+ <channel onMode="3" bRatio="0.0000105" products="321 -321 130"/>
+ <channel onMode="3" bRatio="0.0000105" products="321 -321 310"/>
+ <channel onMode="3" bRatio="0.0000050" products="333 311 221"/>
+ <channel onMode="3" bRatio="0.0015000" products="423 -421 311"/>
+ <channel onMode="3" bRatio="0.0005000" products="-423 421 311"/>
+ <channel onMode="3" bRatio="0.0000050" products="-9000211 313 211"/>
+ <channel onMode="3" bRatio="0.0003118" meMode="31" products="-3 1 22"/>
+ <channel onMode="3" bRatio="0.3160000" meMode="23" products="2 -1 -4 1"/>
+ <channel onMode="3" bRatio="0.0000050" meMode="12" products="-3 1 11 -11"/>
+ <channel onMode="3" bRatio="0.0000025" meMode="12" products="-3 1 13 -13"/>
+ <channel onMode="3" bRatio="0.0000002" meMode="12" products="-3 1 15 -15"/>
+</particle>
+
+<particle id="513" name="B*0" antiName="B*bar0" spinType="3" chargeType="0" colType="0"
+ m0="5.32500">
+ <channel onMode="1" bRatio="1.0000000" products="511 22"/>
+</particle>
+
+<particle id="515" name="B*_20" antiName="B*_2bar0" spinType="5" chargeType="0" colType="0"
+ m0="5.83000" mWidth="0.02000" mMin="5.63000" mMax="6.03000">
+ <channel onMode="1" bRatio="0.3100000" products="523 -211"/>
+ <channel onMode="1" bRatio="0.1500000" products="513 111"/>
+ <channel onMode="1" bRatio="0.3100000" products="521 -211"/>
+ <channel onMode="1" bRatio="0.1500000" products="511 111"/>
+ <channel onMode="1" bRatio="0.0500000" products="523 -211 111"/>
+ <channel onMode="1" bRatio="0.0300000" products="513 211 -211"/>
+</particle>
+
+<particle id="521" name="B+" antiName="B-" spinType="1" chargeType="3" colType="0"
+ m0="5.27900" tau0="4.91100e-01">
+ <channel onMode="1" bRatio="0.0000930" products="16 -15"/>
+ <channel onMode="1" bRatio="0.0000720" meMode="22" products="12 -11 111"/>
+ <channel onMode="1" bRatio="0.0001450" meMode="22" products="12 -11 113"/>
+ <channel onMode="1" bRatio="0.0000840" meMode="22" products="12 -11 221"/>
+ <channel onMode="1" bRatio="0.0001450" meMode="22" products="12 -11 223"/>
+ <channel onMode="1" bRatio="0.0000840" meMode="22" products="12 -11 331"/>
+ <channel onMode="1" bRatio="0.0224000" meMode="22" products="12 -11 -421"/>
+ <channel onMode="1" bRatio="0.0617000" meMode="22" products="12 -11 -423"/>
+ <channel onMode="1" bRatio="0.0030000" meMode="22" products="12 -11 -425"/>
+ <channel onMode="1" bRatio="0.0049000" meMode="22" products="12 -11 -10421"/>
+ <channel onMode="1" bRatio="0.0056000" meMode="22" products="12 -11 -10423"/>
+ <channel onMode="1" bRatio="0.0090000" meMode="22" products="12 -11 -20423"/>
+ <channel onMode="1" bRatio="0.0000720" meMode="22" products="14 -13 111"/>
+ <channel onMode="1" bRatio="0.0001450" meMode="22" products="14 -13 113"/>
+ <channel onMode="1" bRatio="0.0000840" meMode="22" products="14 -13 221"/>
+ <channel onMode="1" bRatio="0.0001450" meMode="22" products="14 -13 223"/>
+ <channel onMode="1" bRatio="0.0000840" meMode="22" products="14 -13 331"/>
+ <channel onMode="1" bRatio="0.0224000" meMode="22" products="14 -13 -421"/>
+ <channel onMode="1" bRatio="0.0617000" meMode="22" products="14 -13 -423"/>
+ <channel onMode="1" bRatio="0.0030000" meMode="22" products="14 -13 -425"/>
+ <channel onMode="1" bRatio="0.0049000" meMode="22" products="14 -13 -10421"/>
+ <channel onMode="1" bRatio="0.0056000" meMode="22" products="14 -13 -10423"/>
+ <channel onMode="1" bRatio="0.0090000" meMode="22" products="14 -13 -20423"/>
+ <channel onMode="1" bRatio="0.0000300" meMode="22" products="16 -15 111"/>
+ <channel onMode="1" bRatio="0.0000420" meMode="22" products="16 -15 113"/>
+ <channel onMode="1" bRatio="0.0000120" meMode="22" products="16 -15 221"/>
+ <channel onMode="1" bRatio="0.0000420" meMode="22" products="16 -15 223"/>
+ <channel onMode="1" bRatio="0.0000200" meMode="22" products="16 -15 225"/>
+ <channel onMode="1" bRatio="0.0000180" meMode="22" products="16 -15 331"/>
+ <channel onMode="1" bRatio="0.0000200" meMode="22" products="16 -15 335"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="16 -15 -421"/>
+ <channel onMode="1" bRatio="0.0160000" meMode="22" products="16 -15 -423"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="16 -15 -425"/>
+ <channel onMode="1" bRatio="0.0000270" meMode="22" products="16 -15 10113"/>
+ <channel onMode="1" bRatio="0.0000020" meMode="22" products="16 -15 10221"/>
+ <channel onMode="1" bRatio="0.0000130" meMode="22" products="16 -15 10223"/>
+ <channel onMode="1" bRatio="0.0000130" meMode="22" products="16 -15 10333"/>
+ <channel onMode="1" bRatio="0.0013000" meMode="22" products="16 -15 -10421"/>
+ <channel onMode="1" bRatio="0.0013000" meMode="22" products="16 -15 -10423"/>
+ <channel onMode="1" bRatio="0.0000460" meMode="22" products="16 -15 20113"/>
+ <channel onMode="1" bRatio="0.0000230" meMode="22" products="16 -15 20223"/>
+ <channel onMode="1" bRatio="0.0000230" meMode="22" products="16 -15 20333"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="16 -15 -20423"/>
+ <channel onMode="1" bRatio="0.0000040" meMode="22" products="16 -15 9000111"/>
+ <channel onMode="1" bRatio="0.0000020" meMode="22" products="16 -15 9010221"/>
+ <channel onMode="1" bRatio="0.0019000" meMode="22" products="12 -11 -411 211"/>
+ <channel onMode="1" bRatio="0.0006000" meMode="22" products="12 -11 -413 211"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="12 -11 -421 111"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="12 -11 -423 111"/>
+ <channel onMode="1" bRatio="0.0019000" meMode="22" products="14 -13 -411 211"/>
+ <channel onMode="1" bRatio="0.0006000" meMode="22" products="14 -13 -413 211"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="14 -13 -421 111"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="14 -13 -423 111"/>
+ <channel onMode="1" bRatio="0.0000055" products="211 111"/>
+ <channel onMode="1" bRatio="0.0000091" products="211 113"/>
+ <channel onMode="1" bRatio="0.0000120" products="211 130"/>
+ <channel onMode="1" bRatio="0.0000120" products="213 111"/>
+ <channel onMode="1" bRatio="0.0000150" products="213 113"/>
+ <channel onMode="1" bRatio="0.0000048" products="221 211"/>
+ <channel onMode="1" bRatio="0.0000086" products="221 213"/>
+ <channel onMode="1" bRatio="0.0000059" products="223 211"/>
+ <channel onMode="1" bRatio="0.0000130" products="223 213"/>
+ <channel onMode="1" bRatio="0.0000023" products="225 211"/>
+ <channel onMode="1" bRatio="0.0000120" products="310 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 213"/>
+ <channel onMode="1" bRatio="0.0000120" products="321 111"/>
+ <channel onMode="1" bRatio="0.0000052" products="321 113"/>
+ <channel onMode="1" bRatio="0.0000026" products="321 221"/>
+ <channel onMode="1" bRatio="0.0000051" products="321 223"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311"/>
+ <channel onMode="1" bRatio="0.0000403" products="323 22"/>
+ <channel onMode="1" bRatio="0.0000020" products="323 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 113"/>
+ <channel onMode="1" bRatio="0.0000240" products="323 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 223"/>
+ <channel onMode="1" bRatio="0.0000030" products="323 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -313"/>
+ <channel onMode="1" bRatio="0.0000042" products="331 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 213"/>
+ <channel onMode="1" bRatio="0.0000780" products="331 321"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 323"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 213"/>
+ <channel onMode="1" bRatio="0.0000090" products="333 321"/>
+ <channel onMode="1" bRatio="0.0000110" products="333 323"/>
+ <channel onMode="1" bRatio="0.0000005" products="411 111"/>
+ <channel onMode="1" bRatio="0.0000110" products="411 311"/>
+ <channel onMode="1" bRatio="0.0000005" products="413 111"/>
+ <channel onMode="1" bRatio="0.0000060" products="413 311"/>
+ <channel onMode="1" bRatio="0.0050000" products="-421 211"/>
+ <channel onMode="1" bRatio="0.0134000" products="-421 213"/>
+ <channel onMode="1" bRatio="0.0004100" products="-421 321"/>
+ <channel onMode="1" bRatio="0.0006100" products="-421 323"/>
+ <channel onMode="1" bRatio="0.0002700" products="-421 411"/>
+ <channel onMode="1" bRatio="0.0003350" products="-421 413"/>
+ <channel onMode="1" bRatio="0.0046000" products="-423 211"/>
+ <channel onMode="1" bRatio="0.0098000" products="-423 213"/>
+ <channel onMode="1" bRatio="0.0003600" products="-423 321"/>
+ <channel onMode="1" bRatio="0.0007700" products="-423 323"/>
+ <channel onMode="1" bRatio="0.0003350" products="-423 411"/>
+ <channel onMode="1" bRatio="0.0010400" products="-423 413"/>
+ <channel onMode="1" bRatio="0.0008000" products="-425 211"/>
+ <channel onMode="1" bRatio="0.0038000" products="-425 213"/>
+ <channel onMode="1" bRatio="0.0000200" products="431 111"/>
+ <channel onMode="1" bRatio="0.0000280" products="431 113"/>
+ <channel onMode="1" bRatio="0.0129000" products="431 -421"/>
+ <channel onMode="1" bRatio="0.0124000" products="431 -423"/>
+ <channel onMode="1" bRatio="0.0042000" products="431 -425"/>
+ <channel onMode="1" bRatio="0.0000200" products="433 111"/>
+ <channel onMode="1" bRatio="0.0000280" products="433 113"/>
+ <channel onMode="1" bRatio="0.0111000" products="433 -421"/>
+ <channel onMode="1" bRatio="0.0278000" products="433 -423"/>
+ <channel onMode="1" bRatio="0.0040000" products="433 -425"/>
+ <channel onMode="1" bRatio="0.0009000" products="441 321"/>
+ <channel onMode="1" bRatio="0.0012000" products="441 323"/>
+ <channel onMode="1" bRatio="0.0000400" products="443 211"/>
+ <channel onMode="1" bRatio="0.0000600" products="443 213"/>
+ <channel onMode="1" bRatio="0.0010600" products="443 321"/>
+ <channel onMode="1" bRatio="0.0014300" products="443 323"/>
+ <channel onMode="1" bRatio="0.0005000" products="443 325"/>
+ <channel onMode="1" bRatio="0.0000200" products="445 321"/>
+ <channel onMode="1" bRatio="0.0000100" products="10113 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10113 321"/>
+ <channel onMode="1" bRatio="0.0000100" products="10213 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10213 311"/>
+ <channel onMode="1" bRatio="0.0000700" products="10311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 213"/>
+ <channel onMode="1" bRatio="0.0000020" products="-10311 321"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 333"/>
+ <channel onMode="1" bRatio="0.0018000" products="10323 443"/>
+ <channel onMode="1" bRatio="0.0009100" products="-10421 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="-10423 211"/>
+ <channel onMode="1" bRatio="0.0007000" products="-10423 213"/>
+ <channel onMode="1" bRatio="0.0012000" products="-10423 431"/>
+ <channel onMode="1" bRatio="0.0024000" products="-10423 433"/>
+ <channel onMode="1" bRatio="0.0016000" products="10431 -421"/>
+ <channel onMode="1" bRatio="0.0016000" products="10431 -423"/>
+ <channel onMode="1" bRatio="0.0003000" products="10441 321"/>
+ <channel onMode="1" bRatio="0.0004000" products="10441 323"/>
+ <channel onMode="1" bRatio="0.0000400" products="20113 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 321"/>
+ <channel onMode="1" bRatio="0.0000200" products="20113 323"/>
+ <channel onMode="1" bRatio="0.0000400" products="20213 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 223"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 311"/>
+ <channel onMode="1" bRatio="0.0000200" products="20213 313"/>
+ <channel onMode="1" bRatio="0.0088700" products="20213 -421"/>
+ <channel onMode="1" bRatio="0.0159700" products="20213 -423"/>
+ <channel onMode="1" bRatio="0.0000500" products="20213 20113"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 333"/>
+ <channel onMode="1" bRatio="0.0001000" products="20323 443"/>
+ <channel onMode="1" bRatio="0.0007500" products="-20423 211"/>
+ <channel onMode="1" bRatio="0.0022000" products="-20423 213"/>
+ <channel onMode="1" bRatio="0.0006000" products="-20423 431"/>
+ <channel onMode="1" bRatio="0.0012000" products="-20423 433"/>
+ <channel onMode="1" bRatio="0.0041000" products="20433 -421"/>
+ <channel onMode="1" bRatio="0.0098000" products="20433 -423"/>
+ <channel onMode="1" bRatio="0.0005700" products="20443 321"/>
+ <channel onMode="1" bRatio="0.0002900" products="20443 323"/>
+ <channel onMode="1" bRatio="0.0004800" products="30443 321"/>
+ <channel onMode="1" bRatio="0.0005000" products="30443 323"/>
+ <channel onMode="1" bRatio="0.0003000" products="30443 10323"/>
+ <channel onMode="1" bRatio="0.0000022" products="100113 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="100113 321"/>
+ <channel onMode="1" bRatio="0.0003600" products="100441 321"/>
+ <channel onMode="1" bRatio="0.0004800" products="100441 323"/>
+ <channel onMode="1" bRatio="0.0006300" products="100443 321"/>
+ <channel onMode="1" bRatio="0.0006000" products="100443 323"/>
+ <channel onMode="1" bRatio="0.0004000" products="100443 10323"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000111 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 321"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000111 323"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="9000211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 311"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000211 313"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 213"/>
+ <channel onMode="1" bRatio="0.0000085" products="9010221 321"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 323"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 20213"/>
+ <channel onMode="1" bRatio="0.0000260" products="211 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="211 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="211 113 113"/>
+ <channel onMode="1" bRatio="0.0000160" products="211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="213 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="213 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="213 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="213 -213 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-213 211 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 211 113"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 213 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 221 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="221 221 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="223 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="223 211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="223 213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="223 221 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="223 221 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 213 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 213"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 223 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="313 221 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="313 221 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 223 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 -313 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-313 311 211"/>
+ <channel onMode="1" bRatio="0.0000006" meMode="11" products="321 11 -11"/>
+ <channel onMode="1" bRatio="0.0000006" meMode="11" products="321 13 -13"/>
+ <channel onMode="1" bRatio="0.0000001" meMode="11" products="321 15 -15"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 113 111"/>
+ <channel onMode="1" bRatio="0.0000049" products="321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -213 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 221 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 221 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 221 221"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 223 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 223 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 223"/>
+ <channel onMode="1" bRatio="0.0000480" products="321 311 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 313 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -313 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -313 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -313 311"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 321 -211"/>
+ <channel onMode="1" bRatio="0.0000260" products="321 321 -321"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 213"/>
+ <channel onMode="1" bRatio="0.0000001" products="-321 211 211"/>
+ <channel onMode="1" bRatio="0.0000018" meMode="11" products="323 11 -11"/>
+ <channel onMode="1" bRatio="0.0000014" meMode="11" products="323 13 -13"/>
+ <channel onMode="1" bRatio="0.0000002" meMode="11" products="323 15 -15"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 213 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 -213 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 221 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 221 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="323 221 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 223 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 223 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 311 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="323 311 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -313 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="323 -313 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 321 -321"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -321 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 321 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-323 321 321"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 211 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 213 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 213 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 221 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 223 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 223 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 213"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 313 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 223"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 311"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -313"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 323 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 223"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 323 311"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 323 -313"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 331 321"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 213 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="333 221 211"/>
+ <channel onMode="1" bRatio="0.0000005" products="333 221 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 223 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 113"/>
+ <channel onMode="1" bRatio="0.0000050" products="333 321 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 223"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 323 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="333 331 211"/>
+ <channel onMode="1" bRatio="0.0000002" products="333 331 213"/>
+ <channel onMode="1" bRatio="0.0000020" products="333 331 321"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 333 211"/>
+ <channel onMode="1" bRatio="0.0000030" products="333 333 321"/>
+ <channel onMode="1" bRatio="0.0000030" products="333 333 323"/>
+ <channel onMode="1" bRatio="0.0005000" products="411 -411 321"/>
+ <channel onMode="1" bRatio="0.0005000" products="411 -411 323"/>
+ <channel onMode="1" bRatio="0.0010200" products="-411 211 211"/>
+ <channel onMode="1" bRatio="0.0020000" products="-411 213 211"/>
+ <channel onMode="1" bRatio="0.0005000" products="413 -411 321"/>
+ <channel onMode="1" bRatio="0.0005000" products="413 -411 323"/>
+ <channel onMode="1" bRatio="0.0015000" products="413 -413 321"/>
+ <channel onMode="1" bRatio="0.0010000" products="413 -413 323"/>
+ <channel onMode="1" bRatio="0.0012500" products="-413 211 211"/>
+ <channel onMode="1" bRatio="0.0020000" products="-413 213 211"/>
+ <channel onMode="1" bRatio="0.0015000" products="-413 411 321"/>
+ <channel onMode="1" bRatio="0.0005000" products="-413 411 323"/>
+ <channel onMode="1" bRatio="0.0015000" products="421 -421 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="421 -421 323"/>
+ <channel onMode="1" bRatio="0.0005000" products="-421 211 111"/>
+ <channel onMode="1" bRatio="0.0021000" products="-421 211 113"/>
+ <channel onMode="1" bRatio="0.0017000" products="-421 411 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="-421 411 313"/>
+ <channel onMode="1" bRatio="0.0049000" products="-421 413 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="-421 413 313"/>
+ <channel onMode="1" bRatio="0.0047000" products="423 -421 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="423 -421 323"/>
+ <channel onMode="1" bRatio="0.0070000" products="423 -423 321"/>
+ <channel onMode="1" bRatio="0.0050000" products="423 -423 323"/>
+ <channel onMode="1" bRatio="0.0005000" products="-423 211 111"/>
+ <channel onMode="1" bRatio="0.0005000" products="-423 211 113"/>
+ <channel onMode="1" bRatio="0.0005000" products="-423 213 111"/>
+ <channel onMode="1" bRatio="0.0031000" products="-423 411 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="-423 411 313"/>
+ <channel onMode="1" bRatio="0.0100000" products="-423 413 311"/>
+ <channel onMode="1" bRatio="0.0050000" products="-423 413 313"/>
+ <channel onMode="1" bRatio="0.0018000" products="-423 421 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="-423 421 323"/>
+ <channel onMode="1" bRatio="0.0036000" products="431 -411 211"/>
+ <channel onMode="1" bRatio="0.0018000" products="431 -421 111"/>
+ <channel onMode="1" bRatio="0.0037000" products="433 -411 211"/>
+ <channel onMode="1" bRatio="0.0018000" products="433 -421 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="441 311 211"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 321 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="443 311 211"/>
+ <channel onMode="1" bRatio="0.0001000" products="443 321 111"/>
+ <channel onMode="1" bRatio="0.0000900" products="443 333 321"/>
+ <channel onMode="1" bRatio="0.0002000" products="445 311 211"/>
+ <channel onMode="1" bRatio="0.0001000" products="445 321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 221 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 321 311"/>
+ <channel onMode="1" bRatio="0.0000020" products="10311 331 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 333 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10311 321 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 213 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="10321 221 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 321 -321"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 331 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 333 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10321 333 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 333 331"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10321 321 321"/>
+ <channel onMode="1" bRatio="0.0002000" products="10441 311 211"/>
+ <channel onMode="1" bRatio="0.0001000" products="10441 321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="20113 221 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20113 321 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="20113 331 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="20213 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="20213 321 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20213 331 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="-20213 211 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 333 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 321 -321"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 333 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="20323 333 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="20323 333 331"/>
+ <channel onMode="1" bRatio="0.0004000" products="20443 311 211"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 321 111"/>
+ <channel onMode="1" bRatio="0.0003000" products="30443 311 211"/>
+ <channel onMode="1" bRatio="0.0002000" products="30443 321 111"/>
+ <channel onMode="1" bRatio="0.0000800" products="100441 311 211"/>
+ <channel onMode="1" bRatio="0.0000500" products="100441 321 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="100443 311 211"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000111 213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000111 221 213"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000111 323 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="9000111 331 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000211 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9000211 -213 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000211 221 113"/>
+ <channel onMode="1" bRatio="0.0000050" products="9000211 313 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="9000211 331 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="-9000211 211 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 211 113"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 213 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="9010221 221 213"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 223 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 313 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 323 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="9010221 323 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 331 213"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 331 323"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 333 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 333 321"/>
+ <channel onMode="1" bRatio="0.0000100" products="211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="211 113 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="211 211 -211 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="213 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="213 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="-213 211 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 211 113 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="221 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 213 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 213 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 -213 211 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="221 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 221 213 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="223 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 211 113 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 213 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 213 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 -213 211 211"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="311 221 213 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 221 221 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 223 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 213 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="311 311 221 211"/>
+ <channel onMode="1" bRatio="0.0000005" products="311 311 221 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 311 223 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="313 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="313 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="313 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-313 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 113 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 213 -211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -213 211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 221 113 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 221 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 223 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 223 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 113 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 213 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 -213 211"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 311 221 113"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 311 221 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 223 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 311 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 313 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -313 111 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -313 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -313 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 321 -321 113"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 321 -321 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 321 -321 223"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 321 -321 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 211 113"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 213 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -321 221 211"/>
+ <channel onMode="1" bRatio="0.0000005" products="321 -321 221 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 223 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 213"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 311 213 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-321 313 211 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="323 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="323 221 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000005" products="323 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="323 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="323 -321 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 311 211 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="-323 321 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="-323 321 321 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 211 113 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 213 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 213 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 -213 211 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 223 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 311 213 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 311 311 213"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 313 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 113 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 221 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 223 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 311 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 311 113"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 311 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 311 311"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -313 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 321 -321"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -321 211"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 321 -321 213"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 323 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 323 221 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="331 323 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000005" products="333 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="333 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="333 321 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 321 -321"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 323 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 323 321 -321"/>
+ <channel onMode="1" bRatio="0.0000002" products="333 331 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="333 331 321 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="-411 211 211 111"/>
+ <channel onMode="1" bRatio="0.0150000" products="-413 211 211 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="-421 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0005000" products="-423 211 111 111"/>
+ <channel onMode="1" bRatio="0.0005000" products="-423 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0033000" products="431 -411 211 111"/>
+ <channel onMode="1" bRatio="0.0008000" products="431 -421 111 111"/>
+ <channel onMode="1" bRatio="0.0033000" products="431 -421 211 -211"/>
+ <channel onMode="1" bRatio="0.0033000" products="433 -411 211 111"/>
+ <channel onMode="1" bRatio="0.0008000" products="433 -421 111 111"/>
+ <channel onMode="1" bRatio="0.0033000" products="433 -421 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 311 211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 321 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="441 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="445 311 211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="445 321 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="445 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 321 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10311 321 311 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="10311 321 -321 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="10311 331 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="10311 331 321 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10311 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10311 321 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="-10311 321 311 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10311 321 321 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="-10311 331 321 311"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10321 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="10321 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="10321 321 -321 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 331 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="10321 331 321 -321"/>
+ <channel onMode="1" bRatio="0.0000100" products="-10321 321 321 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="-10321 321 321 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="-10321 331 321 321"/>
+ <channel onMode="1" bRatio="0.0001000" products="10441 311 211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="10441 321 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="10441 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="20313 321 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="20313 321 311 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 321 -321 211"/>
+ <channel onMode="1" bRatio="0.0000020" products="20313 331 321 311"/>
+ <channel onMode="1" bRatio="0.0000020" products="-20313 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000100" products="-20313 321 311 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="-20313 321 311 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="-20313 331 321 311"/>
+ <channel onMode="1" bRatio="0.0000040" products="20323 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 311 311 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="20323 321 -321 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="20323 331 311 311"/>
+ <channel onMode="1" bRatio="0.0000010" products="20323 331 321 -321"/>
+ <channel onMode="1" bRatio="0.0000020" products="-20323 321 321 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 311 211 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 321 111 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="20443 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="30443 311 211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="30443 321 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="30443 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000500" products="100441 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000500" products="100441 321 111 111"/>
+ <channel onMode="1" bRatio="0.0000800" products="100441 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="100443 311 211 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="100443 321 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 321 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000111 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9000211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="-9000211 211 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="9010221 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 321 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="9010221 321 321 -321"/>
+ <channel onMode="1" bRatio="0.0000010" products="9010221 331 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="211 111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="211 211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="221 211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="311 211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="311 221 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="311 311 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="311 311 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="311 311 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="311 311 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 111 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="321 211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 221 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 221 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 221 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 311 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 311 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 311 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 311 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 311 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 311 311 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 311 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 321 -321 111 111"/>
+ <channel onMode="1" bRatio="0.0000050" products="321 321 -321 221 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 321 -321 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 321 -321 -321 211"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 -321 211 111 111"/>
+ <channel onMode="1" bRatio="0.0000002" products="321 -321 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="321 -321 221 211 111"/>
+ <channel onMode="1" bRatio="0.0000100" products="321 -321 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="321 -321 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000002" products="-321 311 211 211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="-321 311 221 211 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 211 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 311 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 311 311 211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 111 111 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 211 -211 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="331 321 221 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 311 111 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 311 211 -211"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000020" products="331 321 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 321 -321 211 111"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 -321 311 211 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 311 311 311 211"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 321 311 -211"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 321 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="55" products="-3 2"/>
+ <channel onMode="1" bRatio="0.0330000" meMode="63" products="-4103 2203"/>
+ <channel onMode="1" bRatio="0.0090000" meMode="63" products="-4303 2203"/>
+ <channel onMode="1" bRatio="0.0000700" meMode="23" products="1 -1 -1 2"/>
+ <channel onMode="1" bRatio="0.0018000" meMode="23" products="1 -1 -3 2"/>
+ <channel onMode="1" bRatio="0.0030000" meMode="23" products="2 -1 -2 2"/>
+ <channel onMode="1" bRatio="0.0020500" meMode="23" products="2 -2 -1 2"/>
+ <channel onMode="1" bRatio="0.0022000" meMode="23" products="2 -2 -3 2"/>
+ <channel onMode="1" bRatio="0.0225000" meMode="43" products="2 -3 -4 2"/>
+ <channel onMode="1" bRatio="0.0000900" meMode="23" products="3 -3 -1 2"/>
+ <channel onMode="1" bRatio="0.0015000" meMode="23" products="3 -3 -3 2"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="43" products="4 -1 -4 2"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="23" products="4 -3 -2 2"/>
+ <channel onMode="1" bRatio="0.0740000" meMode="43" products="4 -3 -4 2"/>
+ <channel onMode="2" bRatio="0.0019480" meMode="22" products="12 -11 2 -2"/>
+ <channel onMode="2" bRatio="0.0019480" meMode="22" products="14 -13 2 -2"/>
+ <channel onMode="2" bRatio="0.0000200" products="445 323"/>
+ <channel onMode="2" bRatio="0.0000010" products="333 321 313 311"/>
+ <channel onMode="2" bRatio="0.0000020" products="-20313 321 321 -211"/>
+ <channel onMode="2" bRatio="0.0003118" meMode="31" products="2 -3 22"/>
+ <channel onMode="2" bRatio="0.2682660" meMode="23" products="2 -1 -4 2"/>
+ <channel onMode="2" bRatio="0.0000050" meMode="12" products="2 -3 11 -11"/>
+ <channel onMode="2" bRatio="0.0000025" meMode="12" products="2 -3 13 -13"/>
+ <channel onMode="2" bRatio="0.0000002" meMode="12" products="2 -3 15 -15"/>
+ <channel onMode="3" bRatio="0.0019480" meMode="22" products="12 -11 -2 2"/>
+ <channel onMode="3" bRatio="0.0019480" meMode="22" products="14 -13 -2 2"/>
+ <channel onMode="3" bRatio="0.0000400" products="445 323"/>
+ <channel onMode="3" bRatio="0.0000010" products="333 321 -313 311"/>
+ <channel onMode="3" bRatio="0.0000020" products="20313 321 321 -211"/>
+ <channel onMode="3" bRatio="0.0003118" meMode="31" products="-3 2 22"/>
+ <channel onMode="3" bRatio="0.2683360" meMode="23" products="2 -1 -4 2"/>
+ <channel onMode="3" bRatio="0.0000050" meMode="12" products="-3 2 11 -11"/>
+ <channel onMode="3" bRatio="0.0000025" meMode="12" products="-3 2 13 -13"/>
+ <channel onMode="3" bRatio="0.0000002" meMode="12" products="-3 2 15 -15"/>
+</particle>
+
+<particle id="523" name="B*+" antiName="B*-" spinType="3" chargeType="3" colType="0"
+ m0="5.32500">
+ <channel onMode="1" bRatio="1.0000000" products="521 22"/>
+</particle>
+
+<particle id="525" name="B*_2+" antiName="B*_2-" spinType="5" chargeType="3" colType="0"
+ m0="5.83000" mWidth="0.02000" mMin="5.63000" mMax="6.03000">
+ <channel onMode="1" bRatio="0.3100000" products="513 211"/>
+ <channel onMode="1" bRatio="0.1500000" products="523 111"/>
+ <channel onMode="1" bRatio="0.3100000" products="511 211"/>
+ <channel onMode="1" bRatio="0.1500000" products="521 111"/>
+ <channel onMode="1" bRatio="0.0500000" products="513 211 111"/>
+ <channel onMode="1" bRatio="0.0300000" products="523 211 -211"/>
+</particle>
+
+<particle id="531" name="B_s0" antiName="B_sbar0" spinType="1" chargeType="0" colType="0"
+ m0="5.36750" tau0="4.39000e-01">
+ <channel onMode="1" bRatio="0.0002000" meMode="22" products="12 -11 -321"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="12 -11 -323"/>
+ <channel onMode="1" bRatio="0.0210000" meMode="22" products="12 -11 -431"/>
+ <channel onMode="1" bRatio="0.0490000" meMode="22" products="12 -11 -433"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="12 -11 -435"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="12 -11 -10323"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="22" products="12 -11 -10431"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="12 -11 -10433"/>
+ <channel onMode="1" bRatio="0.0002000" meMode="22" products="12 -11 -20323"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="22" products="12 -11 -20433"/>
+ <channel onMode="1" bRatio="0.0002000" meMode="22" products="14 -13 -321"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="14 -13 -323"/>
+ <channel onMode="1" bRatio="0.0210000" meMode="22" products="14 -13 -431"/>
+ <channel onMode="1" bRatio="0.0490000" meMode="22" products="14 -13 -433"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="14 -13 -435"/>
+ <channel onMode="1" bRatio="0.0003000" meMode="22" products="14 -13 -10323"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="22" products="14 -13 -10431"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="14 -13 -10433"/>
+ <channel onMode="1" bRatio="0.0002000" meMode="22" products="14 -13 -20323"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="22" products="14 -13 -20433"/>
+ <channel onMode="1" bRatio="0.0080000" meMode="22" products="16 -15 -431"/>
+ <channel onMode="1" bRatio="0.0160000" meMode="22" products="16 -15 -433"/>
+ <channel onMode="1" bRatio="0.0028000" meMode="22" products="16 -15 -435"/>
+ <channel onMode="1" bRatio="0.0018000" meMode="22" products="16 -15 -10431"/>
+ <channel onMode="1" bRatio="0.0028000" meMode="22" products="16 -15 -10433"/>
+ <channel onMode="1" bRatio="0.0018000" meMode="22" products="16 -15 -20433"/>
+ <channel onMode="1" bRatio="0.0000005" products="22 22"/>
+ <channel onMode="1" bRatio="0.0000100" products="130 130"/>
+ <channel onMode="1" bRatio="0.0000000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0000040" products="221 221"/>
+ <channel onMode="1" bRatio="0.0000012" products="223 221"/>
+ <channel onMode="1" bRatio="0.0000100" products="310 310"/>
+ <channel onMode="1" bRatio="0.0000002" products="311 111"/>
+ <channel onMode="1" bRatio="0.0000000" products="311 113"/>
+ <channel onMode="1" bRatio="0.0000002" products="311 221"/>
+ <channel onMode="1" bRatio="0.0000001" products="311 223"/>
+ <channel onMode="1" bRatio="0.0000020" products="313 130"/>
+ <channel onMode="1" bRatio="0.0000020" products="313 310"/>
+ <channel onMode="1" bRatio="0.0000040" products="313 -313"/>
+ <channel onMode="1" bRatio="0.0000000" products="-313 111"/>
+ <channel onMode="1" bRatio="0.0000008" products="-313 113"/>
+ <channel onMode="1" bRatio="0.0000020" products="-313 130"/>
+ <channel onMode="1" bRatio="0.0000001" products="-313 221"/>
+ <channel onMode="1" bRatio="0.0000020" products="-313 310"/>
+ <channel onMode="1" bRatio="0.0000185" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0000048" products="-321 211"/>
+ <channel onMode="1" bRatio="0.0000120" products="-321 213"/>
+ <channel onMode="1" bRatio="0.0000046" products="323 -321"/>
+ <channel onMode="1" bRatio="0.0000060" products="323 -323"/>
+ <channel onMode="1" bRatio="0.0000250" products="-323 211"/>
+ <channel onMode="1" bRatio="0.0000200" products="-323 213"/>
+ <channel onMode="1" bRatio="0.0000082" products="-323 321"/>
+ <channel onMode="1" bRatio="0.0000250" products="331 221"/>
+ <channel onMode="1" bRatio="0.0000025" products="331 223"/>
+ <channel onMode="1" bRatio="0.0000001" products="331 311"/>
+ <channel onMode="1" bRatio="0.0000000" products="331 -313"/>
+ <channel onMode="1" bRatio="0.0000580" products="331 331"/>
+ <channel onMode="1" bRatio="0.0000450" products="333 22"/>
+ <channel onMode="1" bRatio="0.0000213" products="333 221"/>
+ <channel onMode="1" bRatio="0.0000004" products="333 -313"/>
+ <channel onMode="1" bRatio="0.0000125" products="333 331"/>
+ <channel onMode="1" bRatio="0.0000080" products="333 333"/>
+ <channel onMode="1" bRatio="0.0002000" products="-421 311"/>
+ <channel onMode="1" bRatio="0.0002000" products="-421 -313"/>
+ <channel onMode="1" bRatio="0.0002000" products="-423 311"/>
+ <channel onMode="1" bRatio="0.0002000" products="-423 -313"/>
+ <channel onMode="1" bRatio="0.0017000" products="431 -411"/>
+ <channel onMode="1" bRatio="0.0017000" products="431 -413"/>
+ <channel onMode="1" bRatio="0.0086000" products="431 -431"/>
+ <channel onMode="1" bRatio="0.0026000" products="-431 211"/>
+ <channel onMode="1" bRatio="0.0073000" products="-431 213"/>
+ <channel onMode="1" bRatio="0.0001500" products="-431 321"/>
+ <channel onMode="1" bRatio="0.0003000" products="-431 323"/>
+ <channel onMode="1" bRatio="0.0017000" products="433 -411"/>
+ <channel onMode="1" bRatio="0.0017000" products="433 -413"/>
+ <channel onMode="1" bRatio="0.0197000" products="433 -433"/>
+ <channel onMode="1" bRatio="0.0027000" products="-433 211"/>
+ <channel onMode="1" bRatio="0.0070000" products="-433 213"/>
+ <channel onMode="1" bRatio="0.0001500" products="-433 321"/>
+ <channel onMode="1" bRatio="0.0003000" products="-433 323"/>
+ <channel onMode="1" bRatio="0.0013000" products="-435 211"/>
+ <channel onMode="1" bRatio="0.0004000" products="441 221"/>
+ <channel onMode="1" bRatio="0.0008000" products="441 331"/>
+ <channel onMode="1" bRatio="0.0015000" products="441 333"/>
+ <channel onMode="1" bRatio="0.0003200" products="443 221"/>
+ <channel onMode="1" bRatio="0.0000800" products="443 311"/>
+ <channel onMode="1" bRatio="0.0006400" products="443 331"/>
+ <channel onMode="1" bRatio="0.0013500" products="443 333"/>
+ <channel onMode="1" bRatio="0.0002350" products="445 221"/>
+ <channel onMode="1" bRatio="0.0004650" products="445 331"/>
+ <channel onMode="1" bRatio="0.0000500" products="10441 221"/>
+ <channel onMode="1" bRatio="0.0001000" products="10441 331"/>
+ <channel onMode="1" bRatio="0.0002000" products="10441 333"/>
+ <channel onMode="1" bRatio="0.0002350" products="10443 221"/>
+ <channel onMode="1" bRatio="0.0004650" products="10443 331"/>
+ <channel onMode="1" bRatio="0.0010000" products="10443 333"/>
+ <channel onMode="1" bRatio="0.0085000" products="20213 -431"/>
+ <channel onMode="1" bRatio="0.0122000" products="20213 -433"/>
+ <channel onMode="1" bRatio="0.0008000" products="-20433 211"/>
+ <channel onMode="1" bRatio="0.0021000" products="-20433 213"/>
+ <channel onMode="1" bRatio="0.0003000" products="20443 221"/>
+ <channel onMode="1" bRatio="0.0007000" products="20443 331"/>
+ <channel onMode="1" bRatio="0.0014000" products="20443 333"/>
+ <channel onMode="1" bRatio="0.0002000" products="100441 221"/>
+ <channel onMode="1" bRatio="0.0004000" products="100441 331"/>
+ <channel onMode="1" bRatio="0.0006000" products="100441 333"/>
+ <channel onMode="1" bRatio="0.0002350" products="100443 221"/>
+ <channel onMode="1" bRatio="0.0004650" products="100443 331"/>
+ <channel onMode="1" bRatio="0.0012000" products="100443 333"/>
+ <channel onMode="1" bRatio="0.0000023" meMode="11" products="333 11 -11"/>
+ <channel onMode="1" bRatio="0.0000023" meMode="11" products="333 13 -13"/>
+ <channel onMode="1" bRatio="0.0007000" products="411 -411 311"/>
+ <channel onMode="1" bRatio="0.0007000" products="413 -411 311"/>
+ <channel onMode="1" bRatio="0.0007000" products="421 411 -321"/>
+ <channel onMode="1" bRatio="0.0007000" products="-421 413 -321"/>
+ <channel onMode="1" bRatio="0.0096000" products="431 -411 311"/>
+ <channel onMode="1" bRatio="0.0096000" products="431 421 -321"/>
+ <channel onMode="1" bRatio="0.0009000" products="-431 211 113"/>
+ <channel onMode="1" bRatio="0.0009000" products="-431 213 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="-431 411 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="-431 411 313"/>
+ <channel onMode="1" bRatio="0.0050000" products="-431 413 311"/>
+ <channel onMode="1" bRatio="0.0025000" products="-431 413 313"/>
+ <channel onMode="1" bRatio="0.0020000" products="-431 421 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="-431 421 323"/>
+ <channel onMode="1" bRatio="0.0050000" products="-431 423 321"/>
+ <channel onMode="1" bRatio="0.0025000" products="-431 423 323"/>
+ <channel onMode="1" bRatio="0.0096000" products="433 -411 311"/>
+ <channel onMode="1" bRatio="0.0096000" products="433 -421 -321"/>
+ <channel onMode="1" bRatio="0.0010000" products="-433 211 113"/>
+ <channel onMode="1" bRatio="0.0010000" products="-433 213 111"/>
+ <channel onMode="1" bRatio="0.0050000" products="-433 411 311"/>
+ <channel onMode="1" bRatio="0.0050000" products="-433 411 313"/>
+ <channel onMode="1" bRatio="0.0150000" products="-433 413 311"/>
+ <channel onMode="1" bRatio="0.0030000" products="-433 413 313"/>
+ <channel onMode="1" bRatio="0.0050000" products="-433 421 321"/>
+ <channel onMode="1" bRatio="0.0050000" products="-433 421 323"/>
+ <channel onMode="1" bRatio="0.0150000" products="-433 423 321"/>
+ <channel onMode="1" bRatio="0.0030000" products="-433 423 323"/>
+ <channel onMode="1" bRatio="0.0002800" products="441 311 311"/>
+ <channel onMode="1" bRatio="0.0002800" products="441 321 -321"/>
+ <channel onMode="1" bRatio="0.0002000" products="443 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="443 211 -211"/>
+ <channel onMode="1" bRatio="0.0007000" products="443 311 311"/>
+ <channel onMode="1" bRatio="0.0007000" products="443 321 -321"/>
+ <channel onMode="1" bRatio="0.0001600" products="445 311 311"/>
+ <channel onMode="1" bRatio="0.0001600" products="445 321 -321"/>
+ <channel onMode="1" bRatio="0.0000300" products="10441 311 311"/>
+ <channel onMode="1" bRatio="0.0000300" products="10441 321 -321"/>
+ <channel onMode="1" bRatio="0.0001600" products="10443 311 311"/>
+ <channel onMode="1" bRatio="0.0001600" products="10443 321 -321"/>
+ <channel onMode="1" bRatio="0.0002600" products="20443 311 311"/>
+ <channel onMode="1" bRatio="0.0002600" products="20443 321 -321"/>
+ <channel onMode="1" bRatio="0.0001200" products="100441 311 311"/>
+ <channel onMode="1" bRatio="0.0001200" products="100441 321 -321"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 211 -211"/>
+ <channel onMode="1" bRatio="0.0003000" products="100443 311 311"/>
+ <channel onMode="1" bRatio="0.0003000" products="100443 321 -321"/>
+ <channel onMode="1" bRatio="0.0003000" products="411 -411 311 111"/>
+ <channel onMode="1" bRatio="0.0003000" products="411 -411 -321 211"/>
+ <channel onMode="1" bRatio="0.0003000" products="413 -411 311 111"/>
+ <channel onMode="1" bRatio="0.0003000" products="413 -411 -321 211"/>
+ <channel onMode="1" bRatio="0.0007000" products="-421 411 311 -211"/>
+ <channel onMode="1" bRatio="0.0007000" products="-421 411 -321 111"/>
+ <channel onMode="1" bRatio="0.0007000" products="-421 413 311 -211"/>
+ <channel onMode="1" bRatio="0.0007000" products="-421 413 -321 111"/>
+ <channel onMode="1" bRatio="0.0024000" products="431 -411 311 111"/>
+ <channel onMode="1" bRatio="0.0048000" products="431 -411 -321 211"/>
+ <channel onMode="1" bRatio="0.0048000" products="431 -421 311 -211"/>
+ <channel onMode="1" bRatio="0.0024000" products="431 -421 -321 111"/>
+ <channel onMode="1" bRatio="0.0009000" products="-431 211 111 111"/>
+ <channel onMode="1" bRatio="0.0009000" products="-431 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0024000" products="433 -411 311 111"/>
+ <channel onMode="1" bRatio="0.0048000" products="433 -411 -321 211"/>
+ <channel onMode="1" bRatio="0.0048000" products="433 -421 311 -211"/>
+ <channel onMode="1" bRatio="0.0024000" products="433 -421 -321 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="-433 211 111 111"/>
+ <channel onMode="1" bRatio="0.0077000" products="-433 211 211 -211"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 221 111 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0002800" products="441 311 311 111"/>
+ <channel onMode="1" bRatio="0.0002800" products="441 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0002800" products="441 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0002000" products="441 331 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="441 331 211 -211"/>
+ <channel onMode="1" bRatio="0.0004000" products="441 333 111 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="441 333 211 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="443 221 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="443 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0007000" products="443 311 311 111"/>
+ <channel onMode="1" bRatio="0.0007000" products="443 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0007000" products="443 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0004000" products="443 331 111 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="443 331 211 -211"/>
+ <channel onMode="1" bRatio="0.0003900" products="443 333 111 111"/>
+ <channel onMode="1" bRatio="0.0003900" products="443 333 211 -211"/>
+ <channel onMode="1" bRatio="0.0001600" products="445 311 311 111"/>
+ <channel onMode="1" bRatio="0.0001600" products="445 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0001600" products="445 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0000300" products="10441 311 311 111"/>
+ <channel onMode="1" bRatio="0.0000300" products="10441 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0000300" products="10441 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0001600" products="10443 311 311 111"/>
+ <channel onMode="1" bRatio="0.0001600" products="10443 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0001600" products="10443 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0001000" products="20443 221 111 111"/>
+ <channel onMode="1" bRatio="0.0001000" products="20443 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0002600" products="20443 311 311 111"/>
+ <channel onMode="1" bRatio="0.0002600" products="20443 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0002600" products="20443 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 331 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="20443 331 211 -211"/>
+ <channel onMode="1" bRatio="0.0004000" products="20443 333 111 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="20443 333 211 -211"/>
+ <channel onMode="1" bRatio="0.0001200" products="100441 311 311 111"/>
+ <channel onMode="1" bRatio="0.0001200" products="100441 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0001200" products="100441 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 221 111 111"/>
+ <channel onMode="1" bRatio="0.0002000" products="100443 221 211 -211"/>
+ <channel onMode="1" bRatio="0.0003000" products="100443 311 311 111"/>
+ <channel onMode="1" bRatio="0.0003000" products="100443 321 -321 111"/>
+ <channel onMode="1" bRatio="0.0003000" products="100443 -321 311 211"/>
+ <channel onMode="1" bRatio="0.0004000" products="100443 331 111 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="100443 331 211 -211"/>
+ <channel onMode="1" bRatio="0.0003400" products="100443 333 111 111"/>
+ <channel onMode="1" bRatio="0.0003400" products="100443 333 211 -211"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="55" products="-3 3"/>
+ <channel onMode="1" bRatio="0.0200000" meMode="63" products="-4301 2101"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="63" products="-4303 2103"/>
+ <channel onMode="1" bRatio="0.0007000" meMode="23" products="1 -1 -1 3"/>
+ <channel onMode="1" bRatio="0.0016000" meMode="23" products="1 -1 -3 3"/>
+ <channel onMode="1" bRatio="0.3574344" meMode="23" products="2 -1 -4 3"/>
+ <channel onMode="1" bRatio="0.0036000" meMode="23" products="2 -2 -1 3"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="23" products="2 -2 -3 3"/>
+ <channel onMode="1" bRatio="0.0172000" meMode="23" products="2 -3 -4 3"/>
+ <channel onMode="1" bRatio="0.0195000" meMode="23" products="2 -4 -1 3"/>
+ <channel onMode="1" bRatio="0.0009000" meMode="23" products="2 -4 -3 3"/>
+ <channel onMode="1" bRatio="0.0009000" meMode="23" products="3 -3 -1 3"/>
+ <channel onMode="1" bRatio="0.0013000" meMode="23" products="3 -3 -3 3"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="43" products="4 -1 -4 3"/>
+ <channel onMode="1" bRatio="0.0040000" meMode="23" products="4 -3 -2 3"/>
+ <channel onMode="2" bRatio="0.0090000" products="433 -431"/>
+ <channel onMode="2" bRatio="0.0099000" products="-433 431"/>
+ <channel onMode="3" bRatio="0.0099000" products="433 -431"/>
+ <channel onMode="3" bRatio="0.0090000" products="-433 431"/>
+</particle>
+
+<particle id="533" name="B*_s0" antiName="B*_sbar0" spinType="3" chargeType="0" colType="0"
+ m0="5.41280">
+ <channel onMode="1" bRatio="1.0000000" products="531 22"/>
+</particle>
+
+<particle id="535" name="B*_2s0" antiName="B*_2sbar0" spinType="5" chargeType="0" colType="0"
+ m0="6.07000" mWidth="0.02000" mMin="5.87000" mMax="6.27000">
+ <channel onMode="1" bRatio="0.1700000" products="513 311"/>
+ <channel onMode="1" bRatio="0.1700000" products="523 -321"/>
+ <channel onMode="1" bRatio="0.3300000" products="511 311"/>
+ <channel onMode="1" bRatio="0.3300000" products="521 -321"/>
+</particle>
+
+<particle id="541" name="B_c+" antiName="B_c-" spinType="1" chargeType="3" colType="0"
+ m0="6.28600" tau0="1.38000e-01">
+ <channel onMode="1" bRatio="0.0160000" products="16 -15"/>
+ <channel onMode="1" bRatio="0.0034000" meMode="22" products="-11 12 511"/>
+ <channel onMode="1" bRatio="0.0058000" meMode="22" products="-11 12 513"/>
+ <channel onMode="1" bRatio="0.0403000" meMode="22" products="-11 12 531"/>
+ <channel onMode="1" bRatio="0.0506000" meMode="22" products="-11 12 533"/>
+ <channel onMode="1" bRatio="0.0000400" meMode="22" products="12 -11 421"/>
+ <channel onMode="1" bRatio="0.0001800" meMode="22" products="12 -11 423"/>
+ <channel onMode="1" bRatio="0.0075000" meMode="22" products="12 -11 441"/>
+ <channel onMode="1" bRatio="0.0190000" meMode="22" products="12 -11 443"/>
+ <channel onMode="1" bRatio="0.0002000" meMode="22" products="12 -11 100441"/>
+ <channel onMode="1" bRatio="0.0009400" meMode="22" products="12 -11 100443"/>
+ <channel onMode="1" bRatio="0.0034000" meMode="22" products="-13 14 511"/>
+ <channel onMode="1" bRatio="0.0058000" meMode="22" products="-13 14 513"/>
+ <channel onMode="1" bRatio="0.0403000" meMode="22" products="-13 14 531"/>
+ <channel onMode="1" bRatio="0.0506000" meMode="22" products="-13 14 533"/>
+ <channel onMode="1" bRatio="0.0000400" meMode="22" products="14 -13 421"/>
+ <channel onMode="1" bRatio="0.0001800" meMode="22" products="14 -13 423"/>
+ <channel onMode="1" bRatio="0.0075000" meMode="22" products="14 -13 441"/>
+ <channel onMode="1" bRatio="0.0190000" meMode="22" products="14 -13 443"/>
+ <channel onMode="1" bRatio="0.0002000" meMode="22" products="14 -13 100441"/>
+ <channel onMode="1" bRatio="0.0009400" meMode="22" products="14 -13 100443"/>
+ <channel onMode="1" bRatio="0.0000200" meMode="22" products="16 -15 421"/>
+ <channel onMode="1" bRatio="0.0000800" meMode="22" products="16 -15 423"/>
+ <channel onMode="1" bRatio="0.0023000" meMode="22" products="16 -15 441"/>
+ <channel onMode="1" bRatio="0.0048000" meMode="22" products="16 -15 443"/>
+ <channel onMode="1" bRatio="0.0000160" meMode="22" products="16 -15 100441"/>
+ <channel onMode="1" bRatio="0.0000800" meMode="22" products="16 -15 100443"/>
+ <channel onMode="1" bRatio="0.0000200" products="211 113"/>
+ <channel onMode="1" bRatio="0.0000003" products="421 411"/>
+ <channel onMode="1" bRatio="0.0000004" products="421 413"/>
+ <channel onMode="1" bRatio="0.0000530" products="-421 411"/>
+ <channel onMode="1" bRatio="0.0000490" products="-421 413"/>
+ <channel onMode="1" bRatio="0.0000003" products="423 411"/>
+ <channel onMode="1" bRatio="0.0000016" products="423 413"/>
+ <channel onMode="1" bRatio="0.0000750" products="-423 411"/>
+ <channel onMode="1" bRatio="0.0003300" products="-423 413"/>
+ <channel onMode="1" bRatio="0.0000066" products="431 421"/>
+ <channel onMode="1" bRatio="0.0000048" products="431 -421"/>
+ <channel onMode="1" bRatio="0.0000063" products="431 423"/>
+ <channel onMode="1" bRatio="0.0000071" products="431 -423"/>
+ <channel onMode="1" bRatio="0.0000085" products="433 421"/>
+ <channel onMode="1" bRatio="0.0000045" products="433 -421"/>
+ <channel onMode="1" bRatio="0.0000404" products="433 423"/>
+ <channel onMode="1" bRatio="0.0000260" products="433 -423"/>
+ <channel onMode="1" bRatio="0.0020000" products="441 211"/>
+ <channel onMode="1" bRatio="0.0042000" products="441 213"/>
+ <channel onMode="1" bRatio="0.0001300" products="441 321"/>
+ <channel onMode="1" bRatio="0.0002000" products="441 323"/>
+ <channel onMode="1" bRatio="0.0001500" products="441 411"/>
+ <channel onMode="1" bRatio="0.0001000" products="441 413"/>
+ <channel onMode="1" bRatio="0.0028000" products="441 431"/>
+ <channel onMode="1" bRatio="0.0027000" products="441 433"/>
+ <channel onMode="1" bRatio="0.0013000" products="443 211"/>
+ <channel onMode="1" bRatio="0.0040000" products="443 213"/>
+ <channel onMode="1" bRatio="0.0001100" products="443 321"/>
+ <channel onMode="1" bRatio="0.0002200" products="443 323"/>
+ <channel onMode="1" bRatio="0.0000900" products="443 411"/>
+ <channel onMode="1" bRatio="0.0002800" products="443 413"/>
+ <channel onMode="1" bRatio="0.0017000" products="443 431"/>
+ <channel onMode="1" bRatio="0.0067000" products="443 433"/>
+ <channel onMode="1" bRatio="0.0106000" products="511 211"/>
+ <channel onMode="1" bRatio="0.0096000" products="511 213"/>
+ <channel onMode="1" bRatio="0.0007000" products="511 321"/>
+ <channel onMode="1" bRatio="0.0001500" products="511 323"/>
+ <channel onMode="1" bRatio="0.0095000" products="513 211"/>
+ <channel onMode="1" bRatio="0.0257000" products="513 213"/>
+ <channel onMode="1" bRatio="0.0005500" products="513 321"/>
+ <channel onMode="1" bRatio="0.0005800" products="513 323"/>
+ <channel onMode="1" bRatio="0.0003700" products="521 111"/>
+ <channel onMode="1" bRatio="0.0003400" products="521 113"/>
+ <channel onMode="1" bRatio="0.0198000" products="521 311"/>
+ <channel onMode="1" bRatio="0.0003300" products="523 111"/>
+ <channel onMode="1" bRatio="0.0009000" products="523 113"/>
+ <channel onMode="1" bRatio="0.0160000" products="523 311"/>
+ <channel onMode="1" bRatio="0.1640000" products="531 211"/>
+ <channel onMode="1" bRatio="0.0720000" products="531 213"/>
+ <channel onMode="1" bRatio="0.0106000" products="531 321"/>
+ <channel onMode="1" bRatio="0.0650000" products="533 211"/>
+ <channel onMode="1" bRatio="0.2020000" products="533 213"/>
+ <channel onMode="1" bRatio="0.0037000" products="533 321"/>
+ <channel onMode="1" bRatio="0.0600502" meMode="42" products="4 -3"/>
+ <channel onMode="2" bRatio="0.0043000" products="521 313"/>
+ <channel onMode="2" bRatio="0.0167000" products="523 313"/>
+ <channel onMode="3" bRatio="0.0043000" products="521 -313"/>
+ <channel onMode="3" bRatio="0.0167000" products="523 -313"/>
+</particle>
+
+<particle id="543" name="B*_c+" antiName="B*_c-" spinType="3" chargeType="3" colType="0"
+ m0="6.34000">
+ <channel onMode="1" bRatio="1.0000000" products="541 22"/>
+</particle>
+
+<particle id="545" name="B*_2c+" antiName="B*_2c-" spinType="5" chargeType="3" colType="0"
+ m0="7.35000" mWidth="0.02000" mMin="7.20000" mMax="7.50000">
+ <channel onMode="1" bRatio="0.3000000" products="511 411"/>
+ <channel onMode="1" bRatio="0.3000000" products="521 421"/>
+ <channel onMode="1" bRatio="0.2000000" products="513 411"/>
+ <channel onMode="1" bRatio="0.2000000" products="523 421"/>
+</particle>
+
+<particle id="551" name="eta_b" spinType="1" chargeType="0" colType="0"
+ m0="9.40000">
+ <channel onMode="1" bRatio="1.0000000" meMode="91" products="21 21"/>
+</particle>
+
+<particle id="553" name="Upsilon" spinType="3" chargeType="0" colType="0"
+ m0="9.46030" mWidth="0.00005" mMin="9.45980" mMax="9.46080">
+ <channel onMode="1" bRatio="0.7757000" meMode="92" products="21 21 21"/>
+ <channel onMode="1" bRatio="0.0290000" meMode="92" products="22 21 21"/>
+ <channel onMode="1" bRatio="0.0238000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0248000" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0267000" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="91" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0450000" meMode="91" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="91" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0450000" meMode="91" products="4 -4"/>
+</particle>
+
+<particle id="555" name="chi_2b" spinType="5" chargeType="0" colType="0"
+ m0="9.91221">
+ <channel onMode="1" bRatio="0.2200000" products="553 22"/>
+ <channel onMode="1" bRatio="0.7800000" meMode="91" products="21 21"/>
+</particle>
+
+<particle id="990" name="pomeron" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="1103" name="dd_1" antiName="dd_1bar" spinType="3" chargeType="-2" colType="-1"
+ m0="0.77133">
+</particle>
+
+<particle id="1114" name="Delta-" antiName="Deltabar+" spinType="4" chargeType="-3" colType="0"
+ m0="1.23400" mWidth="0.12100" mMin="1.08000" mMax="1.60000">
+ <channel onMode="1" bRatio="1.0000000" products="2112 -211"/>
+</particle>
+
+<particle id="2101" name="ud_0" antiName="ud_0bar" spinType="1" chargeType="1" colType="-1"
+ m0="0.57933">
+</particle>
+
+<particle id="2103" name="ud_1" antiName="ud_1bar" spinType="3" chargeType="1" colType="-1"
+ m0="0.77133">
+</particle>
+
+<particle id="2112" name="n0" antiName="nbar0" spinType="2" chargeType="0" colType="0"
+ m0="0.93957" tau0="2.65500e+14">
+ <channel onMode="1" bRatio="1.0000000" meMode="22" products="-12 11 2212"/>
+</particle>
+
+<particle id="2114" name="Delta0" antiName="Deltabar0" spinType="4" chargeType="0" colType="0"
+ m0="1.23300" mWidth="0.11900" mMin="1.08000" mMax="1.60000">
+ <channel onMode="1" bRatio="0.3314000" products="2212 -211"/>
+ <channel onMode="1" bRatio="0.6630000" products="2112 111"/>
+ <channel onMode="1" bRatio="0.0056000" products="2112 22"/>
+</particle>
+
+<particle id="2203" name="uu_1" antiName="uu_1bar" spinType="3" chargeType="4" colType="-1"
+ m0="0.77133">
+</particle>
+
+<particle id="2212" name="p+" antiName="pbar-" spinType="2" chargeType="3" colType="0"
+ m0="0.93827">
+</particle>
+
+<particle id="2214" name="Delta+" antiName="Deltabar-" spinType="4" chargeType="3" colType="0"
+ m0="1.23200" mWidth="0.11700" mMin="1.08000" mMax="1.60000">
+ <channel onMode="1" bRatio="0.6630000" products="2212 111"/>
+ <channel onMode="1" bRatio="0.3314000" products="2112 211"/>
+ <channel onMode="1" bRatio="0.0056000" products="2212 22"/>
+</particle>
+
+<particle id="2224" name="Delta++" antiName="Deltabar--" spinType="4" chargeType="6" colType="0"
+ m0="1.23100" mWidth="0.11500" mMin="1.08000" mMax="1.60000">
+ <channel onMode="1" bRatio="1.0000000" products="2212 211"/>
+</particle>
+
+<particle id="3101" name="sd_0" antiName="sd_0bar" spinType="1" chargeType="-2" colType="-1"
+ m0="0.80473">
+</particle>
+
+<particle id="3103" name="sd_1" antiName="sd_1bar" spinType="3" chargeType="-2" colType="-1"
+ m0="0.92953">
+</particle>
+
+<particle id="3112" name="Sigma-" antiName="Sigmabar+" spinType="2" chargeType="-3" colType="0"
+ m0="1.19745" tau0="4.43400e+01">
+ <channel onMode="1" bRatio="0.9984760" products="2112 -211"/>
+ <channel onMode="1" bRatio="0.0010170" meMode="22" products="-12 11 2112"/>
+ <channel onMode="1" bRatio="0.0004500" meMode="22" products="-14 13 2112"/>
+ <channel onMode="1" bRatio="0.0000570" meMode="22" products="-12 11 3122"/>
+</particle>
+
+<particle id="3114" name="Sigma*-" antiName="Sigma*bar+" spinType="4" chargeType="-3" colType="0"
+ m0="1.38720" mWidth="0.03940" mMin="1.34000" mMax="1.70000">
+ <channel onMode="1" bRatio="0.8800000" products="3122 -211"/>
+ <channel onMode="1" bRatio="0.0600000" products="3212 -211"/>
+ <channel onMode="1" bRatio="0.0600000" products="3112 111"/>
+</particle>
+
+<particle id="3122" name="Lambda0" antiName="Lambdabar0" spinType="2" chargeType="0" colType="0"
+ m0="1.11568" tau0="7.89000e+01">
+ <channel onMode="1" bRatio="0.6391610" products="2212 -211"/>
+ <channel onMode="1" bRatio="0.3581000" products="2112 111"/>
+ <channel onMode="1" bRatio="0.0017500" products="2112 22"/>
+ <channel onMode="1" bRatio="0.0008320" meMode="22" products="-12 11 2212"/>
+ <channel onMode="1" bRatio="0.0001570" meMode="22" products="-14 13 2212"/>
+</particle>
+
+<particle id="3124" name="Lambda(1520)0" antiName="Lambda(1520)bar0" spinType="4" chargeType="0" colType="0"
+ m0="1.51950" mWidth="0.01560" mMin="1.40000" mMax="1.65000">
+ <channel onMode="1" bRatio="0.2300000" products="2212 -321"/>
+ <channel onMode="1" bRatio="0.2300000" products="2112 -311"/>
+ <channel onMode="1" bRatio="0.1400000" products="3222 -211"/>
+ <channel onMode="1" bRatio="0.1400000" products="3112 211"/>
+ <channel onMode="1" bRatio="0.1400000" products="3212 111"/>
+ <channel onMode="1" bRatio="0.0333000" products="3122 111 111"/>
+ <channel onMode="1" bRatio="0.0667000" products="3122 211 -211"/>
+ <channel onMode="1" bRatio="0.0030000" products="3222 -211 111"/>
+ <channel onMode="1" bRatio="0.0030000" products="3112 211 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="3212 111 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="3212 211 -211"/>
+ <channel onMode="1" bRatio="0.0110000" products="3122 22"/>
+</particle>
+
+<particle id="3201" name="su_0" antiName="su_0bar" spinType="1" chargeType="1" colType="-1"
+ m0="0.80473">
+</particle>
+
+<particle id="3203" name="su_1" antiName="su_1bar" spinType="3" chargeType="1" colType="-1"
+ m0="0.92953">
+</particle>
+
+<particle id="3212" name="Sigma0" antiName="Sigmabar0" spinType="2" chargeType="0" colType="0"
+ m0="1.19264">
+ <channel onMode="1" bRatio="0.9950000" products="3122 22"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="11" products="3122 11 -11"/>
+</particle>
+
+<particle id="3214" name="Sigma*0" antiName="Sigma*bar0" spinType="4" chargeType="0" colType="0"
+ m0="1.38370" mWidth="0.03600" mMin="1.34000" mMax="1.70000">
+ <channel onMode="1" bRatio="0.8700000" products="3122 111"/>
+ <channel onMode="1" bRatio="0.0585000" products="3222 -211"/>
+ <channel onMode="1" bRatio="0.0585000" products="3112 211"/>
+ <channel onMode="1" bRatio="0.0130000" products="3122 22"/>
+</particle>
+
+<particle id="3222" name="Sigma+" antiName="Sigmabar-" spinType="2" chargeType="3" colType="0"
+ m0="1.18937" tau0="2.40400e+01">
+ <channel onMode="1" bRatio="0.5156700" products="2212 111"/>
+ <channel onMode="1" bRatio="0.4830800" products="2112 211"/>
+ <channel onMode="1" bRatio="0.0012300" products="2212 22"/>
+ <channel onMode="1" bRatio="0.0000200" meMode="22" products="-11 12 3122"/>
+</particle>
+
+<particle id="3224" name="Sigma*+" antiName="Sigma*bar-" spinType="4" chargeType="3" colType="0"
+ m0="1.38280" mWidth="0.03580" mMin="1.34000" mMax="1.70000">
+ <channel onMode="1" bRatio="0.8800000" products="3122 211"/>
+ <channel onMode="1" bRatio="0.0600000" products="3222 111"/>
+ <channel onMode="1" bRatio="0.0600000" products="3212 211"/>
+</particle>
+
+<particle id="3303" name="ss_1" antiName="ss_1bar" spinType="3" chargeType="-2" colType="-1"
+ m0="1.09361">
+</particle>
+
+<particle id="3312" name="Xi-" antiName="Xibar+" spinType="2" chargeType="-3" colType="0"
+ m0="1.32131" tau0="4.91000e+01">
+ <channel onMode="1" bRatio="0.9988730" products="3122 -211"/>
+ <channel onMode="1" bRatio="0.0001270" products="3112 22"/>
+ <channel onMode="1" bRatio="0.0005630" meMode="22" products="-12 11 3122"/>
+ <channel onMode="1" bRatio="0.0003500" meMode="22" products="-14 13 3122"/>
+ <channel onMode="1" bRatio="0.0000870" meMode="22" products="-12 11 3212"/>
+</particle>
+
+<particle id="3314" name="Xi*-" antiName="Xi*bar+" spinType="4" chargeType="-3" colType="0"
+ m0="1.53500" mWidth="0.00990" mMin="1.46000" mMax="1.63000">
+ <channel onMode="1" bRatio="0.6670000" products="3322 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="3312 111"/>
+</particle>
+
+<particle id="3322" name="Xi0" antiName="Xibar0" spinType="2" chargeType="0" colType="0"
+ m0="1.31483" tau0="8.71000e+01">
+ <channel onMode="1" bRatio="0.9952250" products="3122 111"/>
+ <channel onMode="1" bRatio="0.0011700" products="3122 22"/>
+ <channel onMode="1" bRatio="0.0033300" products="3212 22"/>
+ <channel onMode="1" bRatio="0.0002700" meMode="22" products="-12 11 3222"/>
+ <channel onMode="1" bRatio="0.0000050" meMode="22" products="-14 13 3222"/>
+</particle>
+
+<particle id="3324" name="Xi*0" antiName="Xi*bar0" spinType="4" chargeType="0" colType="0"
+ m0="1.53180" mWidth="0.00910" mMin="1.46000" mMax="1.63000">
+ <channel onMode="1" bRatio="0.3330000" products="3322 111"/>
+ <channel onMode="1" bRatio="0.6670000" products="3312 211"/>
+</particle>
+
+<particle id="3334" name="Omega-" antiName="Omegabar+" spinType="4" chargeType="-3" colType="0"
+ m0="1.67245" tau0="2.46100e+01">
+ <channel onMode="1" bRatio="0.6737600" products="3122 -321"/>
+ <channel onMode="1" bRatio="0.2340000" products="3322 -211"/>
+ <channel onMode="1" bRatio="0.0860000" products="3312 111"/>
+ <channel onMode="1" bRatio="0.0006400" products="3324 -211"/>
+ <channel onMode="1" bRatio="0.0056000" meMode="22" products="-12 11 3322"/>
+</particle>
+
+<particle id="4101" name="cd_0" antiName="cd_0bar" spinType="1" chargeType="1" colType="-1"
+ m0="1.96908">
+</particle>
+
+<particle id="4103" name="cd_1" antiName="cd_1bar" spinType="3" chargeType="1" colType="-1"
+ m0="2.00808">
+</particle>
+
+<particle id="4112" name="Sigma_c0" antiName="Sigma_cbar0" spinType="2" chargeType="0" colType="0"
+ m0="2.45376" mWidth="0.00220" mMin="2.43176" mMax="2.47576">
+ <channel onMode="1" bRatio="1.0000000" products="4122 -211"/>
+</particle>
+
+<particle id="4114" name="Sigma*_c0" antiName="Sigma*_cbar0" spinType="4" chargeType="0" colType="0"
+ m0="2.51800" mWidth="0.01610" mMin="2.43000" mMax="2.68000">
+ <channel onMode="1" bRatio="1.0000000" products="4122 -211"/>
+</particle>
+
+<particle id="4122" name="Lambda_c+" antiName="Lambda_cbar-" spinType="2" chargeType="3" colType="0"
+ m0="2.28646" tau0="5.99000e-02">
+ <channel onMode="1" bRatio="0.0030000" meMode="22" products="-11 12 2112"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-11 12 2114"/>
+ <channel onMode="1" bRatio="0.0180000" meMode="22" products="-11 12 3122"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-11 12 3212"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-11 12 3214"/>
+ <channel onMode="1" bRatio="0.0030000" meMode="22" products="-13 14 2112"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-13 14 2114"/>
+ <channel onMode="1" bRatio="0.0180000" meMode="22" products="-13 14 3122"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-13 14 3212"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-13 14 3214"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="22" products="-11 12 2112 111"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="22" products="-11 12 2212 -211"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="22" products="-13 14 2112 111"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="22" products="-13 14 2212 -211"/>
+ <channel onMode="1" bRatio="0.0030000" products="2112 211"/>
+ <channel onMode="1" bRatio="0.0030000" products="2112 213"/>
+ <channel onMode="1" bRatio="0.0030000" products="2114 211"/>
+ <channel onMode="1" bRatio="0.0030000" products="2114 213"/>
+ <channel onMode="1" bRatio="0.0020000" products="2212 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="2212 113"/>
+ <channel onMode="1" bRatio="0.0010000" products="2212 221"/>
+ <channel onMode="1" bRatio="0.0020000" products="2212 223"/>
+ <channel onMode="1" bRatio="0.0230000" products="2212 311"/>
+ <channel onMode="1" bRatio="0.0400000" products="2212 -313"/>
+ <channel onMode="1" bRatio="0.0010000" products="2212 331"/>
+ <channel onMode="1" bRatio="0.0013000" products="2212 333"/>
+ <channel onMode="1" bRatio="0.0010000" products="2214 111"/>
+ <channel onMode="1" bRatio="0.0010000" products="2214 113"/>
+ <channel onMode="1" bRatio="0.0010000" products="2214 221"/>
+ <channel onMode="1" bRatio="0.0010000" products="2214 223"/>
+ <channel onMode="1" bRatio="0.0050000" products="2214 311"/>
+ <channel onMode="1" bRatio="0.0050000" products="2214 -313"/>
+ <channel onMode="1" bRatio="0.0010000" products="2214 331"/>
+ <channel onMode="1" bRatio="0.0010000" products="2224 -211"/>
+ <channel onMode="1" bRatio="0.0010000" products="2224 -213"/>
+ <channel onMode="1" bRatio="0.0066000" products="2224 -321"/>
+ <channel onMode="1" bRatio="0.0250000" products="2224 -323"/>
+ <channel onMode="1" bRatio="0.0058000" products="3122 211"/>
+ <channel onMode="1" bRatio="0.0050000" products="3122 213"/>
+ <channel onMode="1" bRatio="0.0050000" products="3122 321"/>
+ <channel onMode="1" bRatio="0.0050000" products="3122 323"/>
+ <channel onMode="1" bRatio="0.0055000" products="3212 211"/>
+ <channel onMode="1" bRatio="0.0040000" products="3212 213"/>
+ <channel onMode="1" bRatio="0.0020000" products="3212 321"/>
+ <channel onMode="1" bRatio="0.0020000" products="3212 323"/>
+ <channel onMode="1" bRatio="0.0040000" products="3214 211"/>
+ <channel onMode="1" bRatio="0.0040000" products="3214 213"/>
+ <channel onMode="1" bRatio="0.0010000" products="3214 321"/>
+ <channel onMode="1" bRatio="0.0010000" products="3214 323"/>
+ <channel onMode="1" bRatio="0.0040000" products="3222 111"/>
+ <channel onMode="1" bRatio="0.0040000" products="3222 113"/>
+ <channel onMode="1" bRatio="0.0020000" products="3222 221"/>
+ <channel onMode="1" bRatio="0.0040000" products="3222 223"/>
+ <channel onMode="1" bRatio="0.0020000" products="3222 311"/>
+ <channel onMode="1" bRatio="0.0020000" products="3222 313"/>
+ <channel onMode="1" bRatio="0.0020000" products="3222 331"/>
+ <channel onMode="1" bRatio="0.0030000" products="3224 111"/>
+ <channel onMode="1" bRatio="0.0030000" products="3224 113"/>
+ <channel onMode="1" bRatio="0.0020000" products="3224 221"/>
+ <channel onMode="1" bRatio="0.0030000" products="3224 223"/>
+ <channel onMode="1" bRatio="0.0010000" products="3224 311"/>
+ <channel onMode="1" bRatio="0.0010000" products="3224 313"/>
+ <channel onMode="1" bRatio="0.0020000" products="3322 321"/>
+ <channel onMode="1" bRatio="0.0020000" products="3322 323"/>
+ <channel onMode="1" bRatio="0.0020000" products="3324 321"/>
+ <channel onMode="1" bRatio="0.0018000" products="9010221 2212"/>
+ <channel onMode="1" bRatio="0.0300000" meMode="43" products="1 2203"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="43" products="2 2101"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="43" products="2 2103"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="43" products="2 3201"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="43" products="2 3203"/>
+ <channel onMode="1" bRatio="0.0950000" meMode="43" products="3 2203"/>
+ <channel onMode="1" bRatio="0.0350000" meMode="43" products="2 -1 1 2101"/>
+ <channel onMode="1" bRatio="0.1300000" meMode="43" products="2 -1 1 3201"/>
+ <channel onMode="1" bRatio="0.0570000" meMode="43" products="2 -1 1 3203"/>
+ <channel onMode="1" bRatio="0.0350000" meMode="43" products="2 -3 1 3201"/>
+</particle>
+
+<particle id="4124" name="Lambda_c(2625)+" antiName="Lambda_c(2625)-" spinType="4" chargeType="3" colType="0"
+ m0="2.62810">
+ <channel onMode="1" bRatio="0.6600000" products="4122 211 -211"/>
+ <channel onMode="1" bRatio="0.3300000" products="4122 111"/>
+ <channel onMode="1" bRatio="0.0100000" products="4122 22"/>
+</particle>
+
+<particle id="4132" name="Xi_c0" antiName="Xi_cbar0" spinType="2" chargeType="0" colType="0"
+ m0="2.47100" tau0="3.36000e-02">
+ <channel onMode="1" bRatio="0.0200000" meMode="22" products="-11 12 3 3101"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-11 12 3 3103"/>
+ <channel onMode="1" bRatio="0.0200000" meMode="22" products="-13 14 3 3101"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-13 14 3 3103"/>
+ <channel onMode="1" bRatio="0.5400000" meMode="42" products="2 -1 3 3101"/>
+ <channel onMode="1" bRatio="0.2100000" meMode="42" products="3 3201"/>
+ <channel onMode="1" bRatio="0.1000000" meMode="42" products="3 3203"/>
+ <channel onMode="1" bRatio="0.1000000" meMode="42" products="2 3303"/>
+</particle>
+
+<particle id="4201" name="cu_0" antiName="cu_0bar" spinType="1" chargeType="4" colType="-1"
+ m0="1.96908">
+</particle>
+
+<particle id="4203" name="cu_1" antiName="cu_1bar" spinType="3" chargeType="4" colType="-1"
+ m0="2.00808">
+</particle>
+
+<particle id="4212" name="Sigma_c+" antiName="Sigma_cbar-" spinType="2" chargeType="3" colType="0"
+ m0="2.45290" mWidth="0.00220" mMin="2.43090" mMax="2.47490">
+ <channel onMode="1" bRatio="1.0000000" products="4122 111"/>
+</particle>
+
+<particle id="4214" name="Sigma*_c+" antiName="Sigma*_cbar-" spinType="4" chargeType="3" colType="0"
+ m0="2.51750" mWidth="0.01550" mMin="2.43000" mMax="2.68000">
+ <channel onMode="1" bRatio="1.0000000" products="4122 111"/>
+</particle>
+
+<particle id="4222" name="Sigma_c++" antiName="Sigma_cbar--" spinType="2" chargeType="6" colType="0"
+ m0="2.45402" mWidth="0.00220" mMin="2.43202" mMax="2.47602">
+ <channel onMode="1" bRatio="1.0000000" products="4122 211"/>
+</particle>
+
+<particle id="4224" name="Sigma*_c++" antiName="Sigma*_cbar--" spinType="4" chargeType="6" colType="0"
+ m0="2.51840" mWidth="0.01490" mMin="2.43000" mMax="2.68000">
+ <channel onMode="1" bRatio="1.0000000" products="4122 211"/>
+</particle>
+
+<particle id="4232" name="Xi_c+" antiName="Xi_cbar-" spinType="2" chargeType="3" colType="0"
+ m0="2.46790" tau0="1.32000e-01">
+ <channel onMode="1" bRatio="0.0280000" meMode="22" products="-11 12 3 3201"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="-11 12 3 3203"/>
+ <channel onMode="1" bRatio="0.0280000" meMode="22" products="-13 14 3 3201"/>
+ <channel onMode="1" bRatio="0.0070000" meMode="22" products="-13 14 3 3203"/>
+ <channel onMode="1" bRatio="0.9300000" meMode="42" products="2 -1 3 3201"/>
+</particle>
+
+<particle id="4301" name="cs_0" antiName="cs_0bar" spinType="1" chargeType="1" colType="-1"
+ m0="2.15432">
+</particle>
+
+<particle id="4303" name="cs_1" antiName="cs_1bar" spinType="3" chargeType="1" colType="-1"
+ m0="2.17967">
+</particle>
+
+<particle id="4312" name="Xi'_c0" antiName="Xi'_cbar0" spinType="2" chargeType="0" colType="0"
+ m0="2.57800">
+ <channel onMode="1" bRatio="1.0000000" products="4132 22"/>
+</particle>
+
+<particle id="4314" name="Xi*_c0" antiName="Xi*_cbar0" spinType="4" chargeType="0" colType="0"
+ m0="2.64610">
+ <channel onMode="1" bRatio="0.5000000" products="4132 111"/>
+ <channel onMode="1" bRatio="0.5000000" products="4132 22"/>
+</particle>
+
+<particle id="4322" name="Xi'_c+" antiName="Xi'_cbar-" spinType="2" chargeType="3" colType="0"
+ m0="2.57570">
+ <channel onMode="1" bRatio="1.0000000" products="4232 22"/>
+</particle>
+
+<particle id="4324" name="Xi*_c+" antiName="Xi*_cbar-" spinType="4" chargeType="3" colType="0"
+ m0="2.64660">
+ <channel onMode="1" bRatio="0.5000000" products="4232 111"/>
+ <channel onMode="1" bRatio="0.5000000" products="4232 22"/>
+</particle>
+
+<particle id="4332" name="Omega_c0" antiName="Omega_cbar0" spinType="2" chargeType="0" colType="0"
+ m0="2.69750" tau0="2.10000e-02">
+ <channel onMode="1" bRatio="0.0180000" meMode="22" products="-11 12 3 3303"/>
+ <channel onMode="1" bRatio="0.0180000" meMode="22" products="-13 14 3 3303"/>
+ <channel onMode="1" bRatio="0.9640000" meMode="42" products="2 -1 3 3303"/>
+</particle>
+
+<particle id="4334" name="Omega*_c0" antiName="Omega*_cbar0" spinType="4" chargeType="0" colType="0"
+ m0="2.80000">
+ <channel onMode="1" bRatio="1.0000000" products="4332 22"/>
+</particle>
+
+<particle id="4403" name="cc_1" antiName="cc_1bar" spinType="3" chargeType="4" colType="-1"
+ m0="3.27531">
+</particle>
+
+<particle id="4412" name="Xi_cc+" antiName="Xi_ccbar-" spinType="2" chargeType="3" colType="0"
+ m0="3.59798" tau0="1.00000e-01">
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-11 12 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-13 14 3 81"/>
+ <channel onMode="1" bRatio="0.7600000" meMode="42" products="2 -1 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="42" products="2 -3 3 81"/>
+</particle>
+
+<particle id="4414" name="Xi*_cc+" antiName="Xi*_ccbar-" spinType="4" chargeType="3" colType="0"
+ m0="3.65648" tau0="1.00000e-01">
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-11 12 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-13 14 3 81"/>
+ <channel onMode="1" bRatio="0.7600000" meMode="42" products="2 -1 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="42" products="2 -3 3 81"/>
+</particle>
+
+<particle id="4422" name="Xi_cc++" antiName="Xi_ccbar--" spinType="2" chargeType="6" colType="0"
+ m0="3.59798" tau0="1.00000e-01">
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-11 12 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-13 14 3 81"/>
+ <channel onMode="1" bRatio="0.7600000" meMode="42" products="2 -1 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="42" products="2 -3 3 81"/>
+</particle>
+
+<particle id="4424" name="Xi*_cc++" antiName="Xi*_ccbar--" spinType="4" chargeType="6" colType="0"
+ m0="3.65648" tau0="1.00000e-01">
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-11 12 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-13 14 3 81"/>
+ <channel onMode="1" bRatio="0.7600000" meMode="42" products="2 -1 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="42" products="2 -3 3 81"/>
+</particle>
+
+<particle id="4432" name="Omega_cc+" antiName="Omega_ccbar-" spinType="2" chargeType="3" colType="0"
+ m0="3.78663" tau0="1.00000e-01">
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-11 12 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-13 14 3 81"/>
+ <channel onMode="1" bRatio="0.7600000" meMode="42" products="2 -1 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="42" products="2 -3 3 81"/>
+</particle>
+
+<particle id="4434" name="Omega*_cc+" antiName="Omega*_ccbar-" spinType="4" chargeType="3" colType="0"
+ m0="3.82466" tau0="1.00000e-01">
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-11 12 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-13 14 3 81"/>
+ <channel onMode="1" bRatio="0.7600000" meMode="42" products="2 -1 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="42" products="2 -3 3 81"/>
+</particle>
+
+<particle id="4444" name="Omega*_ccc++" antiName="Omega*_cccbar--" spinType="4" chargeType="6" colType="0"
+ m0="4.91594" tau0="1.00000e-01">
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-11 12 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-13 14 3 81"/>
+ <channel onMode="1" bRatio="0.7600000" meMode="42" products="2 -1 3 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="42" products="2 -3 3 81"/>
+</particle>
+
+<particle id="5101" name="bd_0" antiName="bd_0bar" spinType="1" chargeType="-2" colType="-1"
+ m0="5.38897">
+</particle>
+
+<particle id="5103" name="bd_1" antiName="bd_1bar" spinType="3" chargeType="-2" colType="-1"
+ m0="5.40145">
+</particle>
+
+<particle id="5112" name="Sigma_b-" antiName="Sigma_bbar+" spinType="2" chargeType="-3" colType="0"
+ m0="5.80000">
+ <channel onMode="1" bRatio="1.0000000" products="5122 -211"/>
+</particle>
+
+<particle id="5114" name="Sigma*_b-" antiName="Sigma*_bbar+" spinType="4" chargeType="-3" colType="0"
+ m0="5.81000">
+ <channel onMode="1" bRatio="1.0000000" products="5122 -211"/>
+</particle>
+
+<particle id="5122" name="Lambda_b0" antiName="Lambda_bbar0" spinType="2" chargeType="0" colType="0"
+ m0="5.62400" tau0="3.69000e-01">
+ <channel onMode="1" bRatio="0.0546000" meMode="22" products="-12 11 4122"/>
+ <channel onMode="1" bRatio="0.0096000" meMode="22" products="-12 11 4124"/>
+ <channel onMode="1" bRatio="0.0128000" meMode="22" products="-12 11 14122"/>
+ <channel onMode="1" bRatio="0.0546000" meMode="22" products="-14 13 4122"/>
+ <channel onMode="1" bRatio="0.0096000" meMode="22" products="-14 13 4124"/>
+ <channel onMode="1" bRatio="0.0128000" meMode="22" products="-14 13 14122"/>
+ <channel onMode="1" bRatio="0.0172000" meMode="22" products="-16 15 4122"/>
+ <channel onMode="1" bRatio="0.0032000" meMode="22" products="-16 15 4124"/>
+ <channel onMode="1" bRatio="0.0043000" meMode="22" products="-16 15 14122"/>
+ <channel onMode="1" bRatio="0.0008000" products="2112 421"/>
+ <channel onMode="1" bRatio="0.0000048" products="2212 -211"/>
+ <channel onMode="1" bRatio="0.0000185" products="2212 -321"/>
+ <channel onMode="1" bRatio="0.0000650" products="3122 22"/>
+ <channel onMode="1" bRatio="0.0000050" products="3122 113"/>
+ <channel onMode="1" bRatio="0.0000200" products="3122 333"/>
+ <channel onMode="1" bRatio="0.0008000" products="3122 -421"/>
+ <channel onMode="1" bRatio="0.0010000" products="3122 441"/>
+ <channel onMode="1" bRatio="0.0004700" products="3122 443"/>
+ <channel onMode="1" bRatio="0.0000590" products="3124 22"/>
+ <channel onMode="1" bRatio="0.0006000" products="4112 111"/>
+ <channel onMode="1" bRatio="0.0004000" products="4112 221"/>
+ <channel onMode="1" bRatio="0.0005000" products="4112 331"/>
+ <channel onMode="1" bRatio="0.0400000" products="4122 -211"/>
+ <channel onMode="1" bRatio="0.0100000" products="4122 -213"/>
+ <channel onMode="1" bRatio="0.0005500" products="4122 -321"/>
+ <channel onMode="1" bRatio="0.0220000" products="4122 -431"/>
+ <channel onMode="1" bRatio="0.0440000" products="4122 -433"/>
+ <channel onMode="1" bRatio="0.0003000" products="4132 311"/>
+ <channel onMode="1" bRatio="0.0006000" products="4212 -211"/>
+ <channel onMode="1" bRatio="0.0005000" products="4312 311"/>
+ <channel onMode="1" bRatio="0.0200000" products="-20213 4122"/>
+ <channel onMode="1" bRatio="0.0000570" products="23122 22"/>
+ <channel onMode="1" bRatio="0.0000560" products="33122 22"/>
+ <channel onMode="1" bRatio="0.0003800" products="100443 3122"/>
+ <channel onMode="1" bRatio="0.0220000" products="4122 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0200000" products="3122 311 211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0120000" meMode="22" products="-2 1 2 2101"/>
+ <channel onMode="1" bRatio="0.4411147" meMode="23" products="-2 1 4 2101"/>
+ <channel onMode="1" bRatio="0.0910000" meMode="43" products="-2 4 1 2101"/>
+ <channel onMode="1" bRatio="0.0120000" meMode="22" products="-4 3 2 2101"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="43" products="-4 3 4 2101"/>
+</particle>
+
+<particle id="5132" name="Xi_b-" antiName="Xi_bbar+" spinType="2" chargeType="-3" colType="0"
+ m0="5.84000" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1080010" meMode="22" products="-12 11 4 3101"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-12 11 2 3101"/>
+ <channel onMode="1" bRatio="0.1080000" meMode="22" products="-14 13 4 3101"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-14 13 2 3101"/>
+ <channel onMode="1" bRatio="0.0250000" meMode="22" products="-16 15 4 3101"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="-16 15 4 3101"/>
+ <channel onMode="1" bRatio="0.0010000" products="443 3312"/>
+ <channel onMode="1" bRatio="0.0004370" products="100443 3312"/>
+ <channel onMode="1" bRatio="0.0004710" products="20443 3312"/>
+ <channel onMode="1" bRatio="0.0000900" products="445 3312"/>
+ <channel onMode="1" bRatio="0.0004900" products="441 3312"/>
+ <channel onMode="1" bRatio="0.0015000" products="443 3314"/>
+ <channel onMode="1" bRatio="0.0006560" products="100443 3314"/>
+ <channel onMode="1" bRatio="0.0007060" products="20443 3314"/>
+ <channel onMode="1" bRatio="0.0001350" products="445 3314"/>
+ <channel onMode="1" bRatio="0.0007350" products="441 3314"/>
+ <channel onMode="1" bRatio="0.0012000" products="443 -321 3122"/>
+ <channel onMode="1" bRatio="0.0005240" products="100443 -321 3122"/>
+ <channel onMode="1" bRatio="0.0005650" products="20443 -321 3122"/>
+ <channel onMode="1" bRatio="0.0001080" products="445 -321 3122"/>
+ <channel onMode="1" bRatio="0.0005880" products="441 -321 3122"/>
+ <channel onMode="1" bRatio="0.0006000" products="443 -311 3112"/>
+ <channel onMode="1" bRatio="0.0002620" products="100443 -311 3112"/>
+ <channel onMode="1" bRatio="0.0002830" products="20443 -311 3112"/>
+ <channel onMode="1" bRatio="0.0000540" products="445 -311 3112"/>
+ <channel onMode="1" bRatio="0.0002940" products="441 -311 3112"/>
+ <channel onMode="1" bRatio="0.0038200" meMode="43" products="443 3 3101"/>
+ <channel onMode="1" bRatio="0.0016690" meMode="43" products="100443 3 3101"/>
+ <channel onMode="1" bRatio="0.0017990" meMode="43" products="20443 3 3101"/>
+ <channel onMode="1" bRatio="0.0003440" meMode="43" products="445 3 3101"/>
+ <channel onMode="1" bRatio="0.0018720" meMode="43" products="441 3 3101"/>
+ <channel onMode="1" bRatio="0.1096770" meMode="22" products="-2 1 4 3101"/>
+ <channel onMode="1" bRatio="0.2632250" meMode="22" products="-2 4 1 3101"/>
+ <channel onMode="1" bRatio="0.0658060" meMode="42" products="-2 1 4 3101"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="42" products="-2 4 1 3101"/>
+ <channel onMode="1" bRatio="0.0057720" meMode="22" products="-2 3 4 3101"/>
+ <channel onMode="1" bRatio="0.0138540" meMode="22" products="-2 4 3 3101"/>
+ <channel onMode="1" bRatio="0.0034630" meMode="42" products="-2 3 4 3101"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="42" products="-2 4 3 3101"/>
+ <channel onMode="1" bRatio="0.0090000" meMode="22" products="-2 1 2 3101"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="22" products="-2 2 1 3101"/>
+ <channel onMode="1" bRatio="0.0230000" meMode="63" products="-431 4 3101"/>
+ <channel onMode="1" bRatio="0.0230000" meMode="63" products="-433 4 3101"/>
+ <channel onMode="1" bRatio="0.0130000" products="-431 4132"/>
+ <channel onMode="1" bRatio="0.0090000" products="-431 4314"/>
+ <channel onMode="1" bRatio="0.0090000" products="-433 4132"/>
+ <channel onMode="1" bRatio="0.0230000" products="-433 4314"/>
+ <channel onMode="1" bRatio="0.0080000" meMode="22" products="-421 -321 4 3101"/>
+ <channel onMode="1" bRatio="0.0080000" meMode="22" products="-411 -311 4 3101"/>
+ <channel onMode="1" bRatio="0.0320000" meMode="22" products="-423 -321 4 3101"/>
+ <channel onMode="1" bRatio="0.0320000" meMode="22" products="-413 -311 4 3101"/>
+ <channel onMode="1" bRatio="0.0770000" meMode="42" products="4122 -2203 3101"/>
+</particle>
+
+<particle id="5142" name="Xi_bc0" antiName="Xi_bcbar0" spinType="2" chargeType="0" colType="0"
+ m0="7.00575" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5201" name="bu_0" antiName="bu_0bar" spinType="1" chargeType="1" colType="-1"
+ m0="5.38897">
+</particle>
+
+<particle id="5203" name="bu_1" antiName="bu_1bar" spinType="3" chargeType="1" colType="-1"
+ m0="5.40145">
+</particle>
+
+<particle id="5212" name="Sigma_b0" antiName="Sigma_bbar0" spinType="2" chargeType="0" colType="0"
+ m0="5.80000">
+ <channel onMode="1" bRatio="1.0000000" products="5122 111"/>
+</particle>
+
+<particle id="5214" name="Sigma*_b0" antiName="Sigma*_bbar0" spinType="4" chargeType="0" colType="0"
+ m0="5.81000">
+ <channel onMode="1" bRatio="1.0000000" products="5122 111"/>
+</particle>
+
+<particle id="5222" name="Sigma_b+" antiName="Sigma_bbar-" spinType="2" chargeType="3" colType="0"
+ m0="5.80000">
+ <channel onMode="1" bRatio="1.0000000" products="5122 211"/>
+</particle>
+
+<particle id="5224" name="Sigma*_b+" antiName="Sigma*_bbar-" spinType="4" chargeType="3" colType="0"
+ m0="5.81000">
+ <channel onMode="1" bRatio="1.0000000" products="5122 211"/>
+</particle>
+
+<particle id="5232" name="Xi_b0" antiName="Xi_bbar0" spinType="2" chargeType="0" colType="0"
+ m0="5.84000" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1080010" meMode="22" products="-12 11 4 3201"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-12 11 2 3201"/>
+ <channel onMode="1" bRatio="0.1080000" meMode="22" products="-14 13 4 3201"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-14 13 2 3201"/>
+ <channel onMode="1" bRatio="0.0250000" meMode="22" products="-16 15 4 3201"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="-16 15 4 3201"/>
+ <channel onMode="1" bRatio="0.0010000" products="443 3322"/>
+ <channel onMode="1" bRatio="0.0004370" products="100443 3322"/>
+ <channel onMode="1" bRatio="0.0004710" products="20443 3322"/>
+ <channel onMode="1" bRatio="0.0000900" products="445 3322"/>
+ <channel onMode="1" bRatio="0.0004900" products="441 3322"/>
+ <channel onMode="1" bRatio="0.0015000" products="443 3324"/>
+ <channel onMode="1" bRatio="0.0006560" products="100443 3324"/>
+ <channel onMode="1" bRatio="0.0007060" products="20443 3324"/>
+ <channel onMode="1" bRatio="0.0001350" products="445 3324"/>
+ <channel onMode="1" bRatio="0.0007350" products="441 3324"/>
+ <channel onMode="1" bRatio="0.0012000" products="443 -321 3222"/>
+ <channel onMode="1" bRatio="0.0005240" products="100443 -321 3222"/>
+ <channel onMode="1" bRatio="0.0005650" products="20443 -321 3222"/>
+ <channel onMode="1" bRatio="0.0001080" products="445 -321 3222"/>
+ <channel onMode="1" bRatio="0.0005880" products="441 -321 3222"/>
+ <channel onMode="1" bRatio="0.0006000" products="443 -311 3212"/>
+ <channel onMode="1" bRatio="0.0002620" products="100443 -311 3212"/>
+ <channel onMode="1" bRatio="0.0002830" products="20443 -311 3212"/>
+ <channel onMode="1" bRatio="0.0000540" products="445 -311 3212"/>
+ <channel onMode="1" bRatio="0.0002940" products="441 -311 3212"/>
+ <channel onMode="1" bRatio="0.0038200" meMode="43" products="443 3 3201"/>
+ <channel onMode="1" bRatio="0.0016690" meMode="43" products="100443 3 3201"/>
+ <channel onMode="1" bRatio="0.0017990" meMode="43" products="20443 3 3201"/>
+ <channel onMode="1" bRatio="0.0003440" meMode="43" products="445 3 3201"/>
+ <channel onMode="1" bRatio="0.0018720" meMode="43" products="441 3 3201"/>
+ <channel onMode="1" bRatio="0.1096770" meMode="22" products="-2 1 4 3201"/>
+ <channel onMode="1" bRatio="0.2632250" meMode="22" products="-2 4 1 3201"/>
+ <channel onMode="1" bRatio="0.0658060" meMode="42" products="-2 1 4 3201"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="42" products="-2 4 1 3201"/>
+ <channel onMode="1" bRatio="0.0057720" meMode="22" products="-2 3 4 3201"/>
+ <channel onMode="1" bRatio="0.0138540" meMode="22" products="-2 4 3 3201"/>
+ <channel onMode="1" bRatio="0.0034630" meMode="42" products="-2 3 4 3201"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="42" products="-2 4 3 3201"/>
+ <channel onMode="1" bRatio="0.0090000" meMode="22" products="-2 1 2 3201"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="22" products="-2 2 1 3201"/>
+ <channel onMode="1" bRatio="0.0230000" meMode="63" products="-431 4 3201"/>
+ <channel onMode="1" bRatio="0.0230000" meMode="63" products="-433 4 3201"/>
+ <channel onMode="1" bRatio="0.0130000" products="-431 4232"/>
+ <channel onMode="1" bRatio="0.0090000" products="-431 4324"/>
+ <channel onMode="1" bRatio="0.0090000" products="-433 4232"/>
+ <channel onMode="1" bRatio="0.0230000" products="-433 4324"/>
+ <channel onMode="1" bRatio="0.0080000" meMode="22" products="-421 -321 4 3201"/>
+ <channel onMode="1" bRatio="0.0080000" meMode="22" products="-411 -311 4 3201"/>
+ <channel onMode="1" bRatio="0.0320000" meMode="22" products="-423 -321 4 3201"/>
+ <channel onMode="1" bRatio="0.0320000" meMode="22" products="-413 -311 4 3201"/>
+ <channel onMode="1" bRatio="0.0770000" meMode="42" products="4122 -2203 3201"/>
+</particle>
+
+<particle id="5242" name="Xi_bc+" antiName="Xi_bcbar-" spinType="2" chargeType="3" colType="0"
+ m0="7.00575" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5301" name="bs_0" antiName="bs_0bar" spinType="1" chargeType="-2" colType="-1"
+ m0="5.56725">
+</particle>
+
+<particle id="5303" name="bs_1" antiName="bs_1bar" spinType="3" chargeType="-2" colType="-1"
+ m0="5.57536">
+</particle>
+
+<particle id="5312" name="Xi'_b-" antiName="Xi'_bbar+" spinType="2" chargeType="-3" colType="0"
+ m0="5.96000">
+ <channel onMode="1" bRatio="1.0000000" products="5132 22"/>
+</particle>
+
+<particle id="5314" name="Xi*_b-" antiName="Xi*_bbar+" spinType="4" chargeType="-3" colType="0"
+ m0="5.97000">
+ <channel onMode="1" bRatio="1.0000000" products="5132 22"/>
+</particle>
+
+<particle id="5322" name="Xi'_b0" antiName="Xi'_bbar0" spinType="2" chargeType="0" colType="0"
+ m0="5.96000">
+ <channel onMode="1" bRatio="1.0000000" products="5232 22"/>
+</particle>
+
+<particle id="5324" name="Xi*_b0" antiName="Xi*_bbar0" spinType="4" chargeType="0" colType="0"
+ m0="5.97000">
+ <channel onMode="1" bRatio="1.0000000" products="5232 22"/>
+</particle>
+
+<particle id="5332" name="Omega_b-" antiName="Omega_bbar+" spinType="2" chargeType="-3" colType="0"
+ m0="6.12000" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1080010" meMode="22" products="-12 11 4 3303"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-12 11 2 3303"/>
+ <channel onMode="1" bRatio="0.1080000" meMode="22" products="-14 13 4 3303"/>
+ <channel onMode="1" bRatio="0.0020000" meMode="22" products="-14 13 2 3303"/>
+ <channel onMode="1" bRatio="0.0250000" meMode="22" products="-16 15 4 3303"/>
+ <channel onMode="1" bRatio="0.0010000" meMode="22" products="-16 15 4 3303"/>
+ <channel onMode="1" bRatio="0.0025000" products="443 3334"/>
+ <channel onMode="1" bRatio="0.0010930" products="100443 3334"/>
+ <channel onMode="1" bRatio="0.0011770" products="20443 3334"/>
+ <channel onMode="1" bRatio="0.0002250" products="445 3334"/>
+ <channel onMode="1" bRatio="0.0012250" products="441 3334"/>
+ <channel onMode="1" bRatio="0.0012000" products="443 -321 3322"/>
+ <channel onMode="1" bRatio="0.0005240" products="100443 -321 3322"/>
+ <channel onMode="1" bRatio="0.0005650" products="20443 -321 3322"/>
+ <channel onMode="1" bRatio="0.0001080" products="445 -321 3322"/>
+ <channel onMode="1" bRatio="0.0005880" products="441 -321 3322"/>
+ <channel onMode="1" bRatio="0.0006000" products="443 -311 3312"/>
+ <channel onMode="1" bRatio="0.0002620" products="100443 -311 3312"/>
+ <channel onMode="1" bRatio="0.0002830" products="20443 -311 3312"/>
+ <channel onMode="1" bRatio="0.0000540" products="445 -311 3312"/>
+ <channel onMode="1" bRatio="0.0002940" products="441 -311 3312"/>
+ <channel onMode="1" bRatio="0.0038200" meMode="43" products="443 3 3303"/>
+ <channel onMode="1" bRatio="0.0016690" meMode="43" products="100443 3 3303"/>
+ <channel onMode="1" bRatio="0.0017990" meMode="43" products="20443 3 3303"/>
+ <channel onMode="1" bRatio="0.0003440" meMode="43" products="445 3 3303"/>
+ <channel onMode="1" bRatio="0.0018720" meMode="43" products="441 3 3303"/>
+ <channel onMode="1" bRatio="0.1096770" meMode="22" products="-2 1 4 3303"/>
+ <channel onMode="1" bRatio="0.2632250" meMode="22" products="-2 4 1 3303"/>
+ <channel onMode="1" bRatio="0.0658060" meMode="42" products="-2 1 4 3303"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="42" products="-2 4 1 3303"/>
+ <channel onMode="1" bRatio="0.0057720" meMode="22" products="-2 3 4 3303"/>
+ <channel onMode="1" bRatio="0.0138540" meMode="22" products="-2 4 3 3303"/>
+ <channel onMode="1" bRatio="0.0034630" meMode="42" products="-2 3 4 3303"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="42" products="-2 4 3 3303"/>
+ <channel onMode="1" bRatio="0.0090000" meMode="22" products="-2 1 2 3303"/>
+ <channel onMode="1" bRatio="0.0060000" meMode="22" products="-2 2 1 3303"/>
+ <channel onMode="1" bRatio="0.0230000" meMode="63" products="-431 4 3303"/>
+ <channel onMode="1" bRatio="0.0230000" meMode="63" products="-433 4 3303"/>
+ <channel onMode="1" bRatio="0.0130000" products="-431 4332"/>
+ <channel onMode="1" bRatio="0.0090000" products="-431 4334"/>
+ <channel onMode="1" bRatio="0.0090000" products="-433 4332"/>
+ <channel onMode="1" bRatio="0.0230000" products="-433 4334"/>
+ <channel onMode="1" bRatio="0.0080000" meMode="22" products="-421 -321 4 3303"/>
+ <channel onMode="1" bRatio="0.0080000" meMode="22" products="-411 -311 4 3303"/>
+ <channel onMode="1" bRatio="0.0320000" meMode="22" products="-423 -321 4 3303"/>
+ <channel onMode="1" bRatio="0.0320000" meMode="22" products="-413 -311 4 3303"/>
+ <channel onMode="1" bRatio="0.0770000" meMode="42" products="4122 -2203 3303"/>
+</particle>
+
+<particle id="5334" name="Omega*_b-" antiName="Omega*_bbar+" spinType="4" chargeType="-3" colType="0"
+ m0="6.13000">
+ <channel onMode="1" bRatio="1.0000000" products="5332 22"/>
+</particle>
+
+<particle id="5342" name="Omega_bc0" antiName="Omega_bcbar0" spinType="2" chargeType="0" colType="0"
+ m0="7.19099" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5401" name="bc_0" antiName="bc_0bar" spinType="1" chargeType="1" colType="-1"
+ m0="6.67143">
+</particle>
+
+<particle id="5403" name="bc_1" antiName="bc_1bar" spinType="3" chargeType="1" colType="-1"
+ m0="6.67397">
+</particle>
+
+<particle id="5412" name="Xi'_bc0" antiName="Xi'_bcbar0" spinType="2" chargeType="0" colType="0"
+ m0="7.03724" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5414" name="Xi*_bc0" antiName="Xi*_bcbar0" spinType="4" chargeType="0" colType="0"
+ m0="7.04850" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5422" name="Xi'_bc+" antiName="Xi'_bcbar-" spinType="2" chargeType="3" colType="0"
+ m0="7.03724" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5424" name="Xi*_bc+" antiName="Xi*_bcbar-" spinType="4" chargeType="3" colType="0"
+ m0="7.04850" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5432" name="Omega'_bc0" antiName="Omega'_bcbar0" spinType="2" chargeType="0" colType="0"
+ m0="7.21101" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5434" name="Omega*_bc0" antiName="Omega*_bcbar0" spinType="4" chargeType="0" colType="0"
+ m0="7.21900" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5442" name="Omega_bcc+" antiName="Omega_bccbar-" spinType="2" chargeType="3" colType="0"
+ m0="8.30945" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5444" name="Omega*_bcc+" antiName="Omega*_bccbar-" spinType="4" chargeType="3" colType="0"
+ m0="8.31325" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5503" name="bb_1" antiName="bb_1bar" spinType="3" chargeType="-2" colType="-1"
+ m0="10.07354">
+</particle>
+
+<particle id="5512" name="Xi_bb-" antiName="Xi_bbbar+" spinType="2" chargeType="-3" colType="0"
+ m0="10.42272" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5514" name="Xi*_bb-" antiName="Xi*_bbbar+" spinType="4" chargeType="-3" colType="0"
+ m0="10.44144" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5522" name="Xi_bb0" antiName="Xi_bbbar0" spinType="2" chargeType="0" colType="0"
+ m0="10.42272" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5524" name="Xi*_bb0" antiName="Xi*_bbbar0" spinType="4" chargeType="0" colType="0"
+ m0="10.44144" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5532" name="Omega_bb-" antiName="Omega_bbbar+" spinType="2" chargeType="-3" colType="0"
+ m0="10.60209" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5534" name="Omega*_bb-" antiName="Omega*_bbbar+" spinType="4" chargeType="-3" colType="0"
+ m0="10.61426" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5542" name="Omega_bbc0" antiName="Omega_bbcbar0" spinType="2" chargeType="0" colType="0"
+ m0="11.70767" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5544" name="Omega*_bbc0" antiName="Omega*_bbcbar0" spinType="4" chargeType="0" colType="0"
+ m0="11.71147" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="5554" name="Omega*_bbb-" antiName="Omega*_bbbbar+" spinType="4" chargeType="-3" colType="0"
+ m0="15.11061" tau0="3.64000e-01">
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-12 11 4 81"/>
+ <channel onMode="1" bRatio="0.1050000" meMode="22" products="-14 13 4 81"/>
+ <channel onMode="1" bRatio="0.0400000" meMode="22" products="-16 15 4 81"/>
+ <channel onMode="1" bRatio="0.5000000" meMode="22" products="-2 1 4 81"/>
+ <channel onMode="1" bRatio="0.0800000" meMode="22" products="-2 4 1 81"/>
+ <channel onMode="1" bRatio="0.1400000" meMode="22" products="-4 3 4 81"/>
+ <channel onMode="1" bRatio="0.0100000" meMode="22" products="-4 4 3 81"/>
+ <channel onMode="1" bRatio="0.0150000" meMode="22" products="-2 1 2 81"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="22" products="-4 3 2 81"/>
+</particle>
+
+<particle id="10111" name="a_0(1450)0" spinType="1" chargeType="0" colType="0"
+ m0="1.47400" mWidth="0.26500" mMin="1.00000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.3000000" products="111 221"/>
+ <channel onMode="1" bRatio="0.1000000" products="111 331"/>
+ <channel onMode="1" bRatio="0.1200000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0600000" products="130 130"/>
+ <channel onMode="1" bRatio="0.0600000" products="310 310"/>
+ <channel onMode="1" bRatio="0.1800000" products="223 211 -211"/>
+ <channel onMode="1" bRatio="0.1800000" products="223 111 111"/>
+</particle>
+
+<particle id="10113" name="b_1(1235)0" spinType="3" chargeType="0" colType="0"
+ m0="1.23000" mWidth="0.14200" mMin="0.95000" mMax="1.70000">
+ <channel onMode="1" bRatio="1.0000000" products="223 111"/>
+</particle>
+
+<particle id="10211" name="a_0(1450)+" antiName="a_0(1450)-" spinType="1" chargeType="3" colType="0"
+ m0="1.47400" mWidth="0.26500" mMin="1.00000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.3000000" products="211 221"/>
+ <channel onMode="1" bRatio="0.1000000" products="211 331"/>
+ <channel onMode="1" bRatio="0.2400000" products="321 -311"/>
+ <channel onMode="1" bRatio="0.3600000" products="223 211 111"/>
+</particle>
+
+<particle id="10213" name="b_1(1235)+" antiName="b_1(1235)-" spinType="3" chargeType="3" colType="0"
+ m0="1.23000" mWidth="0.14200" mMin="0.95000" mMax="1.70000">
+ <channel onMode="1" bRatio="0.9984000" products="223 211"/>
+ <channel onMode="1" bRatio="0.0016000" products="211 22"/>
+</particle>
+
+<particle id="10221" name="f_0(1370)" spinType="1" chargeType="0" colType="0"
+ m0="1.35000" mWidth="0.20000" mMin="1.00000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.2000000" products="113 111"/>
+ <channel onMode="1" bRatio="0.2000000" products="213 -213"/>
+ <channel onMode="1" bRatio="0.1000000" products="111 111 111 111"/>
+ <channel onMode="1" bRatio="0.2000000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.1000000" products="111 111"/>
+ <channel onMode="1" bRatio="0.0500000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0250000" products="130 130"/>
+ <channel onMode="1" bRatio="0.0250000" products="310 310"/>
+ <channel onMode="1" bRatio="0.1000000" products="221 221"/>
+</particle>
+
+<particle id="10223" name="h_1(1170)" spinType="3" chargeType="0" colType="0"
+ m0="1.17000" mWidth="0.36000" mMin="0.95000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.3330000" products="213 -211"/>
+ <channel onMode="1" bRatio="0.3340000" products="113 111"/>
+ <channel onMode="1" bRatio="0.3330000" products="-213 211"/>
+</particle>
+
+<particle id="10311" name="K*_0(1430)0" antiName="K*_0(1430)bar0" spinType="1" chargeType="0" colType="0"
+ m0="1.41400" mWidth="0.29000" mMin="0.70000" mMax="2.20000">
+ <channel onMode="1" bRatio="0.6670000" products="321 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="311 111"/>
+</particle>
+
+<particle id="10313" name="K_1(1270)0" antiName="K_1(1270)bar0" spinType="3" chargeType="0" colType="0"
+ m0="1.27200" mWidth="0.09000" mMin="1.00000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.2900000" products="321 -213"/>
+ <channel onMode="1" bRatio="0.1450000" products="311 113"/>
+ <channel onMode="1" bRatio="0.1900000" products="10321 -211"/>
+ <channel onMode="1" bRatio="0.0950000" products="10311 111"/>
+ <channel onMode="1" bRatio="0.1100000" products="323 -211"/>
+ <channel onMode="1" bRatio="0.0550000" products="313 111"/>
+ <channel onMode="1" bRatio="0.1150000" products="311 223"/>
+</particle>
+
+<particle id="10321" name="K*_0(1430)+" antiName="K*_0(1430)-" spinType="1" chargeType="3" colType="0"
+ m0="1.41400" mWidth="0.29000" mMin="0.70000" mMax="2.20000">
+ <channel onMode="1" bRatio="0.6670000" products="311 211"/>
+ <channel onMode="1" bRatio="0.3330000" products="321 111"/>
+</particle>
+
+<particle id="10323" name="K_1(1270)+" antiName="K_1(1270)-" spinType="3" chargeType="3" colType="0"
+ m0="1.27200" mWidth="0.09000" mMin="1.00000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.2900000" products="311 213"/>
+ <channel onMode="1" bRatio="0.1450000" products="321 113"/>
+ <channel onMode="1" bRatio="0.1900000" products="10311 211"/>
+ <channel onMode="1" bRatio="0.0950000" products="10321 111"/>
+ <channel onMode="1" bRatio="0.1100000" products="313 211"/>
+ <channel onMode="1" bRatio="0.0550000" products="323 111"/>
+ <channel onMode="1" bRatio="0.1150000" products="321 223"/>
+</particle>
+
+<particle id="10331" name="f_0(1710)" spinType="1" chargeType="0" colType="0"
+ m0="1.71800" mWidth="0.13700" mMin="1.10000" mMax="2.40000">
+ <channel onMode="1" bRatio="0.3000000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.1500000" products="130 130"/>
+ <channel onMode="1" bRatio="0.1500000" products="310 310"/>
+ <channel onMode="1" bRatio="0.3000000" products="221 221"/>
+ <channel onMode="1" bRatio="0.0500000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0500000" products="111 111"/>
+</particle>
+
+<particle id="10333" name="h_1(1380)" spinType="3" chargeType="0" colType="0"
+ m0="1.38600" mWidth="0.09100" mMin="1.38000" mMax="1.60000">
+ <channel onMode="1" bRatio="0.2500000" products="313 -311"/>
+ <channel onMode="1" bRatio="0.2500000" products="-313 311"/>
+ <channel onMode="1" bRatio="0.2500000" products="323 -321"/>
+ <channel onMode="1" bRatio="0.2500000" products="-323 321"/>
+</particle>
+
+<particle id="10411" name="D*_0+" antiName="D*_0-" spinType="1" chargeType="3" colType="0"
+ m0="2.27200" mWidth="0.05000" mMin="2.05000" mMax="2.50000">
+ <channel onMode="1" bRatio="0.6670000" products="421 211"/>
+ <channel onMode="1" bRatio="0.3330000" products="411 111"/>
+</particle>
+
+<particle id="10413" name="D_1+" antiName="D_1-" spinType="3" chargeType="3" colType="0"
+ m0="2.42400" mWidth="0.02000" mMin="2.22400" mMax="2.62400">
+ <channel onMode="1" bRatio="0.6670000" products="423 211"/>
+ <channel onMode="1" bRatio="0.3330000" products="413 111"/>
+</particle>
+
+<particle id="10421" name="D*_00" antiName="D*_0bar0" spinType="1" chargeType="0" colType="0"
+ m0="2.27200" mWidth="0.05000" mMin="2.05000" mMax="2.50000">
+ <channel onMode="1" bRatio="0.6670000" products="411 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="421 111"/>
+</particle>
+
+<particle id="10423" name="D_10" antiName="D_1bar0" spinType="3" chargeType="0" colType="0"
+ m0="2.42230" mWidth="0.02040" mMin="2.21830" mMax="2.62630">
+ <channel onMode="1" bRatio="0.6670000" products="413 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="423 111"/>
+</particle>
+
+<particle id="10431" name="D*_0s+" antiName="D*_0s-" spinType="1" chargeType="3" colType="0"
+ m0="2.50000" mWidth="0.05000" mMin="2.40000" mMax="2.80000">
+ <channel onMode="1" bRatio="0.5000000" products="411 311"/>
+ <channel onMode="1" bRatio="0.5000000" products="421 321"/>
+</particle>
+
+<particle id="10433" name="D_1s+" antiName="D_1s-" spinType="3" chargeType="3" colType="0"
+ m0="2.53535">
+ <channel onMode="1" bRatio="0.5000000" products="423 321"/>
+ <channel onMode="1" bRatio="0.5000000" products="413 311"/>
+</particle>
+
+<particle id="10441" name="chi_0c" spinType="1" chargeType="0" colType="0"
+ m0="3.41476" mWidth="0.01040" mMin="3.31076" mMax="3.51876">
+ <channel onMode="1" bRatio="0.0002600" products="22 22"/>
+ <channel onMode="1" bRatio="0.0021000" products="130 130"/>
+ <channel onMode="1" bRatio="0.0049000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0021000" products="221 221"/>
+ <channel onMode="1" bRatio="0.0021000" products="310 310"/>
+ <channel onMode="1" bRatio="0.0016000" products="313 -313"/>
+ <channel onMode="1" bRatio="0.0060000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0010000" products="333 333"/>
+ <channel onMode="1" bRatio="0.0200000" products="443 22"/>
+ <channel onMode="1" bRatio="0.0002200" products="2212 -2212"/>
+ <channel onMode="1" bRatio="0.0005000" products="3122 -3122"/>
+ <channel onMode="1" bRatio="0.0028000" products="9010221 9010221"/>
+ <channel onMode="1" bRatio="0.0100000" products="211 -211 113"/>
+ <channel onMode="1" bRatio="0.0100000" products="213 -211 111"/>
+ <channel onMode="1" bRatio="0.0100000" products="-213 211 111"/>
+ <channel onMode="1" bRatio="0.0032000" products="321 -313 -211"/>
+ <channel onMode="1" bRatio="0.0032000" products="-321 313 211"/>
+ <channel onMode="1" bRatio="0.0043000" products="323 311 -211"/>
+ <channel onMode="1" bRatio="0.0043000" products="-323 311 211"/>
+ <channel onMode="1" bRatio="0.0134000" products="211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0021000" products="321 321 -321 -321"/>
+ <channel onMode="1" bRatio="0.0153000" products="321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0022000" products="2212 -2212 211 -211"/>
+ <channel onMode="1" bRatio="0.0098000" products="211 211 211 -211 -211 -211"/>
+ <channel onMode="1" bRatio="0.8686200" meMode="52" products="83 -83"/>
+</particle>
+
+<particle id="10443" name="h_1c" spinType="3" chargeType="0" colType="0"
+ m0="3.46000" mWidth="0.01000" mMin="3.36000" mMax="3.56000">
+ <channel onMode="1" bRatio="0.5000000" products="441 22"/>
+ <channel onMode="1" bRatio="0.0100000" products="443 111"/>
+ <channel onMode="1" bRatio="0.4900000" meMode="42" products="83 -83"/>
+</particle>
+
+<particle id="10511" name="B*_00" antiName="B*_0bar0" spinType="1" chargeType="0" colType="0"
+ m0="5.68000" mWidth="0.05000" mMin="5.58000" mMax="5.78000">
+ <channel onMode="1" bRatio="0.6670000" products="521 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="511 111"/>
+</particle>
+
+<particle id="10513" name="B_10" antiName="B_1bar0" spinType="3" chargeType="0" colType="0"
+ m0="5.73000" mWidth="0.05000" mMin="5.63000" mMax="5.83000">
+ <channel onMode="1" bRatio="0.6670000" products="523 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="513 111"/>
+</particle>
+
+<particle id="10521" name="B*_0+" antiName="B*_0-" spinType="1" chargeType="3" colType="0"
+ m0="5.68000" mWidth="0.05000" mMin="5.58000" mMax="5.78000">
+ <channel onMode="1" bRatio="0.6670000" products="511 211"/>
+ <channel onMode="1" bRatio="0.3330000" products="521 111"/>
+</particle>
+
+<particle id="10523" name="B_1+" antiName="B_1-" spinType="3" chargeType="3" colType="0"
+ m0="5.73000" mWidth="0.05000" mMin="5.63000" mMax="5.83000">
+ <channel onMode="1" bRatio="0.6670000" products="513 211"/>
+ <channel onMode="1" bRatio="0.3330000" products="523 111"/>
+</particle>
+
+<particle id="10531" name="B*_0s0" antiName="B*_0sbar0" spinType="1" chargeType="0" colType="0"
+ m0="5.92000" mWidth="0.05000" mMin="5.82000" mMax="6.02000">
+ <channel onMode="1" bRatio="0.5000000" products="521 -321"/>
+ <channel onMode="1" bRatio="0.5000000" products="511 -311"/>
+</particle>
+
+<particle id="10533" name="B_1s0" antiName="B_1sbar0" spinType="3" chargeType="0" colType="0"
+ m0="5.97000" mWidth="0.05000" mMin="5.87000" mMax="6.07000">
+ <channel onMode="1" bRatio="0.5000000" products="523 -321"/>
+ <channel onMode="1" bRatio="0.5000000" products="513 -311"/>
+</particle>
+
+<particle id="10541" name="B*_0c+" antiName="B*_0c-" spinType="1" chargeType="3" colType="0"
+ m0="7.25000" mWidth="0.05000" mMin="7.20000" mMax="7.30000">
+ <channel onMode="1" bRatio="0.5000000" products="511 411"/>
+ <channel onMode="1" bRatio="0.5000000" products="521 421"/>
+</particle>
+
+<particle id="10543" name="B_1c+" antiName="B_1c-" spinType="3" chargeType="3" colType="0"
+ m0="7.30000" mWidth="0.05000" mMin="7.20000" mMax="7.40000">
+ <channel onMode="1" bRatio="0.5000000" products="513 411"/>
+ <channel onMode="1" bRatio="0.5000000" products="523 421"/>
+</particle>
+
+<particle id="10551" name="chi_0b" spinType="1" chargeType="0" colType="0"
+ m0="9.85944">
+ <channel onMode="1" bRatio="0.9800000" meMode="91" products="21 21"/>
+ <channel onMode="1" bRatio="0.0200000" products="553 22"/>
+</particle>
+
+<particle id="10553" name="h_1b" spinType="3" chargeType="0" colType="0"
+ m0="9.87500" mWidth="0.01000" mMin="9.85500" mMax="9.89500">
+ <channel onMode="1" bRatio="1.0000000" meMode="91" products="21 21"/>
+</particle>
+
+<particle id="13122" name="Lambda(1405)0" antiName="Lambda(1405)bar0" spinType="2" chargeType="0" colType="0"
+ m0="1.40600" mWidth="0.05000" mMin="1.32000" mMax="1.80000">
+ <channel onMode="1" bRatio="0.3333000" products="3222 -211"/>
+ <channel onMode="1" bRatio="0.3333000" products="3112 211"/>
+ <channel onMode="1" bRatio="0.3334000" products="3212 111"/>
+</particle>
+
+<particle id="14122" name="Lambda_c(2593)+" antiName="Lambda_c(2593)-" spinType="2" chargeType="3" colType="0"
+ m0="2.59540" mWidth="0.00360" mMin="2.57000" mMax="2.63000">
+ <channel onMode="1" bRatio="0.2400000" products="4222 -211"/>
+ <channel onMode="1" bRatio="0.2400000" products="4112 211"/>
+ <channel onMode="1" bRatio="0.1800000" products="4122 211 -211"/>
+ <channel onMode="1" bRatio="0.2400000" products="4212 111"/>
+ <channel onMode="1" bRatio="0.0900000" products="4122 111 111"/>
+ <channel onMode="1" bRatio="0.0100000" products="4122 22"/>
+</particle>
+
+<particle id="20113" name="a_1(1260)0" spinType="3" chargeType="0" colType="0"
+ m0="1.23000" mWidth="0.40000" mMin="0.93000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.3300000" products="213 -211"/>
+ <channel onMode="1" bRatio="0.3300000" products="-213 211"/>
+ <channel onMode="1" bRatio="0.3400000" products="113 111"/>
+</particle>
+
+<particle id="20213" name="a_1(1260)+" antiName="a_1(1260)-" spinType="3" chargeType="3" colType="0"
+ m0="1.23000" mWidth="0.40000" mMin="0.93000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.5000000" products="113 211"/>
+ <channel onMode="1" bRatio="0.5000000" products="213 111"/>
+</particle>
+
+<particle id="20223" name="f_1(1285)" spinType="3" chargeType="0" colType="0"
+ m0="1.28180" mWidth="0.02420" mMin="1.20000" mMax="1.50000">
+ <channel onMode="1" bRatio="0.1200000" products="9000211 -211"/>
+ <channel onMode="1" bRatio="0.1200000" products="9000111 111"/>
+ <channel onMode="1" bRatio="0.1200000" products="-9000211 211"/>
+ <channel onMode="1" bRatio="0.0800000" products="221 211 -211"/>
+ <channel onMode="1" bRatio="0.0800000" products="221 111 111"/>
+ <channel onMode="1" bRatio="0.1100000" products="113 211 -211"/>
+ <channel onMode="1" bRatio="0.0740000" products="213 -211 111"/>
+ <channel onMode="1" bRatio="0.0740000" products="113 111 111"/>
+ <channel onMode="1" bRatio="0.0740000" products="-213 211 111"/>
+ <channel onMode="1" bRatio="0.0230000" products="321 -321 111"/>
+ <channel onMode="1" bRatio="0.0230000" products="321 -311 -211"/>
+ <channel onMode="1" bRatio="0.0230000" products="311 -311 111"/>
+ <channel onMode="1" bRatio="0.0230000" products="311 -321 211"/>
+ <channel onMode="1" bRatio="0.0552600" products="113 22"/>
+ <channel onMode="1" bRatio="0.0007400" products="333 22"/>
+</particle>
+
+<particle id="20313" name="K_1(1400)0" antiName="K_1(1400)bar0" spinType="3" chargeType="0" colType="0"
+ m0="1.40200" mWidth="0.17400" mMin="1.10000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.6270000" products="323 -211"/>
+ <channel onMode="1" bRatio="0.3130000" products="313 111"/>
+ <channel onMode="1" bRatio="0.0200000" products="321 -213"/>
+ <channel onMode="1" bRatio="0.0100000" products="311 113"/>
+ <channel onMode="1" bRatio="0.0200000" products="311 10221"/>
+ <channel onMode="1" bRatio="0.0100000" products="311 223"/>
+</particle>
+
+<particle id="20323" name="K_1(1400)+" antiName="K_1(1400)-" spinType="3" chargeType="3" colType="0"
+ m0="1.40200" mWidth="0.17400" mMin="1.10000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.6270000" products="313 211"/>
+ <channel onMode="1" bRatio="0.3130000" products="323 111"/>
+ <channel onMode="1" bRatio="0.0200000" products="311 213"/>
+ <channel onMode="1" bRatio="0.0100000" products="321 113"/>
+ <channel onMode="1" bRatio="0.0200000" products="321 10221"/>
+ <channel onMode="1" bRatio="0.0100000" products="321 223"/>
+</particle>
+
+<particle id="20333" name="f_1(1420)" spinType="3" chargeType="0" colType="0"
+ m0="1.42630" mWidth="0.05490" mMin="1.40000" mMax="1.80000">
+ <channel onMode="1" bRatio="0.2500000" products="313 -311"/>
+ <channel onMode="1" bRatio="0.2500000" products="-313 311"/>
+ <channel onMode="1" bRatio="0.2500000" products="323 -321"/>
+ <channel onMode="1" bRatio="0.2500000" products="-323 321"/>
+</particle>
+
+<particle id="20413" name="D*_1+" antiName="D*_1-" spinType="3" chargeType="3" colType="0"
+ m0="2.42700" mWidth="0.38400" mMin="2.15000" mMax="3.00000">
+ <channel onMode="1" bRatio="0.6670000" products="423 211"/>
+ <channel onMode="1" bRatio="0.3330000" products="413 111"/>
+</particle>
+
+<particle id="20423" name="D*_10" antiName="D*_1bar0" spinType="3" chargeType="0" colType="0"
+ m0="2.42700" mWidth="0.38400" mMin="2.15000" mMax="3.00000">
+ <channel onMode="1" bRatio="0.6670000" products="413 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="423 111"/>
+</particle>
+
+<particle id="20433" name="D*_1s+" antiName="D*_1s-" spinType="3" chargeType="3" colType="0"
+ m0="2.46000" mWidth="0.03000" mMin="2.40000" mMax="2.60000">
+ <channel onMode="1" bRatio="0.7600000" products="433 111"/>
+ <channel onMode="1" bRatio="0.2400000" products="433 22"/>
+</particle>
+
+<particle id="20443" name="chi_1c" spinType="3" chargeType="0" colType="0"
+ m0="3.51066" mWidth="0.00089" mMin="3.50176" mMax="3.51956">
+ <channel onMode="1" bRatio="0.3560000" products="443 22"/>
+ <channel onMode="1" bRatio="0.0000100" products="130 130"/>
+ <channel onMode="1" bRatio="0.0000100" products="310 310"/>
+ <channel onMode="1" bRatio="0.0016000" products="313 -313"/>
+ <channel onMode="1" bRatio="0.0000720" products="2212 -2212"/>
+ <channel onMode="1" bRatio="0.0003000" products="3122 -3122"/>
+ <channel onMode="1" bRatio="0.0020000" products="211 -211 113"/>
+ <channel onMode="1" bRatio="0.0020000" products="213 -211 111"/>
+ <channel onMode="1" bRatio="0.0020000" products="-213 211 111"/>
+ <channel onMode="1" bRatio="0.0025000" products="321 311 -211"/>
+ <channel onMode="1" bRatio="0.0002000" products="321 -313 -211"/>
+ <channel onMode="1" bRatio="0.0025000" products="-321 311 211"/>
+ <channel onMode="1" bRatio="0.0002000" products="-321 313 211"/>
+ <channel onMode="1" bRatio="0.0009000" products="323 311 -211"/>
+ <channel onMode="1" bRatio="0.0009000" products="-323 311 211"/>
+ <channel onMode="1" bRatio="0.0062000" products="211 211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0008000" products="310 310 211 -211"/>
+ <channel onMode="1" bRatio="0.0004000" products="321 321 -321 -321"/>
+ <channel onMode="1" bRatio="0.0038000" products="321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0003000" products="321 -321 310 310"/>
+ <channel onMode="1" bRatio="0.0005000" products="2212 -2212 211 -211"/>
+ <channel onMode="1" bRatio="0.0058000" products="211 211 211 -211 -211 -211"/>
+ <channel onMode="1" bRatio="0.6110080" meMode="52" products="83 -83"/>
+</particle>
+
+<particle id="20513" name="B*_10" antiName="B*_1bar0" spinType="3" chargeType="0" colType="0"
+ m0="5.78000" mWidth="0.05000" mMin="5.68000" mMax="5.88000">
+ <channel onMode="1" bRatio="0.6670000" products="523 -211"/>
+ <channel onMode="1" bRatio="0.3330000" products="513 111"/>
+</particle>
+
+<particle id="20523" name="B*_1+" antiName="B*_1-" spinType="3" chargeType="3" colType="0"
+ m0="5.78000" mWidth="0.05000" mMin="5.68000" mMax="5.88000">
+ <channel onMode="1" bRatio="0.6670000" products="513 211"/>
+ <channel onMode="1" bRatio="0.3330000" products="523 111"/>
+</particle>
+
+<particle id="20533" name="B*_1s0" antiName="B*_1sbar0" spinType="3" chargeType="0" colType="0"
+ m0="6.02000" mWidth="0.05000" mMin="5.92000" mMax="6.12000">
+ <channel onMode="1" bRatio="0.5000000" products="523 -321"/>
+ <channel onMode="1" bRatio="0.5000000" products="513 -311"/>
+</particle>
+
+<particle id="20543" name="B*_1c+" antiName="B*_1c-" spinType="3" chargeType="3" colType="0"
+ m0="7.30000" mWidth="0.05000" mMin="7.20000" mMax="7.40000">
+ <channel onMode="1" bRatio="0.5000000" products="513 411"/>
+ <channel onMode="1" bRatio="0.5000000" products="523 421"/>
+</particle>
+
+<particle id="20553" name="chi_1b" spinType="3" chargeType="0" colType="0"
+ m0="9.89278">
+ <channel onMode="1" bRatio="0.3500000" products="553 22"/>
+ <channel onMode="1" bRatio="0.6500000" meMode="91" products="21 21"/>
+</particle>
+
+<particle id="23122" name="Lambda(1600)0" antiName="Lambda(1600)bar0" spinType="2" chargeType="0" colType="0"
+ m0="1.60000" mWidth="0.15000" mMin="1.42000" mMax="2.20000">
+ <channel onMode="1" bRatio="0.1760000" products="2212 -321"/>
+ <channel onMode="1" bRatio="0.1760000" products="2112 -311"/>
+ <channel onMode="1" bRatio="0.2160000" products="3222 -211"/>
+ <channel onMode="1" bRatio="0.2160000" products="3112 211"/>
+ <channel onMode="1" bRatio="0.2160000" products="3212 111"/>
+</particle>
+
+<particle id="30313" name="K*(1680)0" antiName="K*(1680)bar0" spinType="3" chargeType="0" colType="0"
+ m0="1.71700" mWidth="0.32200" mMin="1.05000" mMax="2.50000">
+ <channel onMode="1" bRatio="0.2580000" products="321 -211"/>
+ <channel onMode="1" bRatio="0.1290000" products="311 111"/>
+ <channel onMode="1" bRatio="0.2093000" products="323 -211"/>
+ <channel onMode="1" bRatio="0.1047000" products="313 111"/>
+ <channel onMode="1" bRatio="0.1993000" products="-213 321"/>
+ <channel onMode="1" bRatio="0.0997000" products="113 311"/>
+</particle>
+
+<particle id="30323" name="K*(1680)+" antiName="K*(1680)-" spinType="3" chargeType="3" colType="0"
+ m0="1.71700" mWidth="0.32200" mMin="1.05000" mMax="2.50000">
+ <channel onMode="1" bRatio="0.2580000" products="311 211"/>
+ <channel onMode="1" bRatio="0.1290000" products="321 111"/>
+ <channel onMode="1" bRatio="0.2093000" products="313 211"/>
+ <channel onMode="1" bRatio="0.1047000" products="323 111"/>
+ <channel onMode="1" bRatio="0.1993000" products="213 311"/>
+ <channel onMode="1" bRatio="0.0997000" products="113 321"/>
+</particle>
+
+<particle id="30443" name="psi(3770)" spinType="3" chargeType="0" colType="0"
+ m0="3.77110" mWidth="0.02300" mMin="3.54110" mMax="4.00110">
+ <channel onMode="1" bRatio="0.4243000" products="411 -411"/>
+ <channel onMode="1" bRatio="0.5723000" products="421 -421"/>
+ <channel onMode="1" bRatio="0.0034000" products="443 211 -211"/>
+</particle>
+
+<particle id="33122" name="Lambda(1670)0" antiName="Lambda(1670)bar0" spinType="2" chargeType="0" colType="0"
+ m0="1.67000" mWidth="0.03500" mMin="1.42000" mMax="2.00000">
+ <channel onMode="1" bRatio="0.1000000" products="2212 -321"/>
+ <channel onMode="1" bRatio="0.1000000" products="2112 -311"/>
+ <channel onMode="1" bRatio="0.1600000" products="3222 -211"/>
+ <channel onMode="1" bRatio="0.1600000" products="3112 211"/>
+ <channel onMode="1" bRatio="0.1600000" products="3212 111"/>
+ <channel onMode="1" bRatio="0.3200000" products="3122 221"/>
+</particle>
+
+<particle id="100113" name="rho(1450)0" spinType="3" chargeType="0" colType="0"
+ m0="1.45900" mWidth="0.14700" mMin="1.00000" mMax="2.20000">
+ <channel onMode="1" bRatio="0.4000000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.3500000" products="211 -211 211 -211"/>
+ <channel onMode="1" bRatio="0.1500000" products="211 -211 111 111"/>
+ <channel onMode="1" bRatio="0.1000000" products="111 111 111 111"/>
+</particle>
+
+<particle id="100213" name="rho(1450)+" antiName="rho(1450)-" spinType="3" chargeType="3" colType="0"
+ m0="1.45900" mWidth="0.14700" mMin="1.00000" mMax="2.20000">
+ <channel onMode="1" bRatio="0.4000000" products="211 111"/>
+ <channel onMode="1" bRatio="0.4000000" products="211 211 -211 111"/>
+ <channel onMode="1" bRatio="0.2000000" products="211 111 111 111"/>
+</particle>
+
+<particle id="100441" name="eta_c(2S)" spinType="1" chargeType="0" colType="0"
+ m0="3.63800" mWidth="0.01400" mMin="3.49800" mMax="3.77800">
+ <channel onMode="1" bRatio="0.0190000" products="321 -311 -211"/>
+ <channel onMode="1" bRatio="0.0190000" products="-321 311 211"/>
+ <channel onMode="1" bRatio="0.0095000" products="111 321 -321"/>
+ <channel onMode="1" bRatio="0.0095000" products="311 -311 111"/>
+ <channel onMode="1" bRatio="0.9430000" meMode="52" products="83 -83"/>
+</particle>
+
+<particle id="100443" name="psi(2S)" spinType="3" chargeType="0" colType="0"
+ m0="3.68609" mWidth="0.00034" mMin="3.68269" mMax="3.68949">
+ <channel onMode="1" bRatio="0.0073500" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0073000" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0028000" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0000080" products="113 111"/>
+ <channel onMode="1" bRatio="0.0000800" products="211 -211"/>
+ <channel onMode="1" bRatio="0.0000080" products="213 -211"/>
+ <channel onMode="1" bRatio="0.0000080" products="-213 211"/>
+ <channel onMode="1" bRatio="0.0000300" products="221 113"/>
+ <channel onMode="1" bRatio="0.0000250" products="223 111"/>
+ <channel onMode="1" bRatio="0.0000010" products="223 221"/>
+ <channel onMode="1" bRatio="0.0002100" products="225 22"/>
+ <channel onMode="1" bRatio="0.0000520" products="310 130"/>
+ <channel onMode="1" bRatio="0.0000460" products="313 311"/>
+ <channel onMode="1" bRatio="0.0000460" products="-313 311"/>
+ <channel onMode="1" bRatio="0.0001000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0000065" products="323 -321"/>
+ <channel onMode="1" bRatio="0.0000065" products="-323 321"/>
+ <channel onMode="1" bRatio="0.0001500" products="331 22"/>
+ <channel onMode="1" bRatio="0.0000010" products="333 111"/>
+ <channel onMode="1" bRatio="0.0000200" products="333 221"/>
+ <channel onMode="1" bRatio="0.0032000" products="441 22"/>
+ <channel onMode="1" bRatio="0.0013000" products="443 111"/>
+ <channel onMode="1" bRatio="0.0324000" products="443 221"/>
+ <channel onMode="1" bRatio="0.0933000" products="445 22"/>
+ <channel onMode="1" bRatio="0.0002100" products="2212 -2212"/>
+ <channel onMode="1" bRatio="0.0001300" products="2224 -2224"/>
+ <channel onMode="1" bRatio="0.0001800" products="3122 -3122"/>
+ <channel onMode="1" bRatio="0.0001200" products="3212 -3212"/>
+ <channel onMode="1" bRatio="0.0001100" products="3224 -3224"/>
+ <channel onMode="1" bRatio="0.0000900" products="3312 -3312"/>
+ <channel onMode="1" bRatio="0.0002140" products="10113 111"/>
+ <channel onMode="1" bRatio="0.0002140" products="10213 -211"/>
+ <channel onMode="1" bRatio="0.0002140" products="-10213 211"/>
+ <channel onMode="1" bRatio="0.0010000" products="10323 -321"/>
+ <channel onMode="1" bRatio="0.0010000" products="-10323 321"/>
+ <channel onMode="1" bRatio="0.0922000" products="10441 22"/>
+ <channel onMode="1" bRatio="0.0008000" products="10443 111"/>
+ <channel onMode="1" bRatio="0.0907000" products="20443 22"/>
+ <channel onMode="1" bRatio="0.0001640" products="211 -211 111"/>
+ <channel onMode="1" bRatio="0.0004200" products="211 -211 113"/>
+ <channel onMode="1" bRatio="0.0001500" products="321 -321 223"/>
+ <channel onMode="1" bRatio="0.0001500" products="333 211 -211"/>
+ <channel onMode="1" bRatio="0.0000600" products="333 321 -321"/>
+ <channel onMode="1" bRatio="0.1658000" products="443 111 111"/>
+ <channel onMode="1" bRatio="0.3366000" products="443 211 -211"/>
+ <channel onMode="1" bRatio="0.0001400" products="2212 -2212 111"/>
+ <channel onMode="1" bRatio="0.0002200" products="310 310 211 -211"/>
+ <channel onMode="1" bRatio="0.0016000" products="321 -321 211 -211"/>
+ <channel onMode="1" bRatio="0.0008000" products="2212 -2212 211 -211"/>
+ <channel onMode="1" bRatio="0.0030000" products="211 211 -211 -211 111"/>
+ <channel onMode="1" bRatio="0.0001500" products="211 211 211 -211 -211 -211"/>
+ <channel onMode="1" bRatio="0.0035000" products="211 211 211 -211 -211 -211 111"/>
+ <channel onMode="1" bRatio="0.0168000" meMode="53" products="83 -83"/>
+ <channel onMode="1" bRatio="0.1258780" meMode="92" products="21 21 21"/>
+ <channel onMode="1" bRatio="0.0089380" meMode="92" products="22 21 21"/>
+</particle>
+
+<particle id="100553" name="Upsilon(2S)" spinType="3" chargeType="0" colType="0"
+ m0="10.02327" mWidth="0.00003" mMin="10.02297" mMax="10.02357">
+ <channel onMode="1" bRatio="0.0191000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0193000" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0170000" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0670000" products="555 22"/>
+ <channel onMode="1" bRatio="0.0430000" products="10551 22"/>
+ <channel onMode="1" bRatio="0.0660000" products="20553 22"/>
+ <channel onMode="1" bRatio="0.0900000" products="553 111 111"/>
+ <channel onMode="1" bRatio="0.1850000" products="553 211 -211"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="91" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0200000" meMode="91" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0050000" meMode="91" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0200000" meMode="91" products="4 -4"/>
+ <channel onMode="1" bRatio="0.4276000" meMode="92" products="21 21 21"/>
+ <channel onMode="1" bRatio="0.0160000" meMode="92" products="22 21 21"/>
+</particle>
+
+<particle id="1000001" name="~d_L" antiName="~d_Lbar" spinType="1" chargeType="-1" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -5"/>
+</particle>
+
+<particle id="1000002" name="~u_L" antiName="~u_Lbar" spinType="1" chargeType="2" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5"/>
+</particle>
+
+<particle id="1000003" name="~s_L" antiName="~s_Lbar" spinType="1" chargeType="-1" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -5"/>
+</particle>
+
+<particle id="1000004" name="~c_L" antiName="~c_Lbar" spinType="1" chargeType="2" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5"/>
+</particle>
+
+<particle id="1000005" name="~b_1" antiName="~b_1bar" spinType="1" chargeType="-1" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3"/>
+</particle>
+
+<particle id="1000006" name="~t_1" antiName="~t_1bar" spinType="1" chargeType="2" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5"/>
+</particle>
+
+<particle id="1000011" name="~e_L-" antiName="~e_L+" spinType="1" chargeType="-3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 5"/>
+</particle>
+
+<particle id="1000012" name="~nu_eL" antiName="~nu_eLbar" spinType="1" chargeType="0" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 5"/>
+</particle>
+
+<particle id="1000013" name="~mu_L-" antiName="~mu_L+" spinType="1" chargeType="-3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 5"/>
+</particle>
+
+<particle id="1000014" name="~nu_muL" antiName="~nu_muLbar" spinType="1" chargeType="0" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 5"/>
+</particle>
+
+<particle id="1000015" name="~tau_1-" antiName="~tau_1+" spinType="1" chargeType="-3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 5"/>
+</particle>
+
+<particle id="1000016" name="~nu_tauL" antiName="~nu_tauLbar" spinType="1" chargeType="0" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-5 5"/>
+</particle>
+
+<particle id="1000021" name="~g" spinType="2" chargeType="0" colType="2"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 21"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 5 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 5 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 3 5"/>
+</particle>
+
+<particle id="1000022" name="~chi_10" spinType="2" chargeType="0" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="20.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 3 5"/>
+</particle>
+
+<particle id="1000023" name="~chi_20" spinType="2" chargeType="0" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 12 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 14 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 11 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 13 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 15 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 11 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 13 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 15 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000011 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000012 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000012 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000013 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000014 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000014 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000015 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000016 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000016 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 3 5"/>
+</particle>
+
+<particle id="1000024" name="~chi_1+" antiName="~chi_1-" spinType="2" chargeType="3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000001 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000003 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000005 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000011 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000013 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000015 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 14 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 14 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 14 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 16 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 16 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 16 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 16 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 16 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 16 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 6 3"/>
+</particle>
+
+<particle id="1000025" name="~chi_30" spinType="2" chargeType="0" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 12 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 14 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 12 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 14 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 11 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 13 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 15 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 11 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 13 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 15 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000011 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000012 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000012 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000013 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000014 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000014 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000015 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000016 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000016 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 3 5"/>
+</particle>
+
+<particle id="1000035" name="~chi_40" spinType="2" chargeType="0" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 12 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 14 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 12 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 14 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 22"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 12 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 14 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 11 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 13 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 15 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 11 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 13 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 15 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 1 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 3 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000001 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000002 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000003 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000004 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000005 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000006 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000011 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000011 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000012 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000012 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000013 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000013 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000014 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000014 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000015 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000015 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000016 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000016 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 3 5"/>
+</particle>
+
+<particle id="1000037" name="~chi_2+" antiName="~chi_2-" spinType="2" chargeType="3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 11 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 13 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 12 -12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 14 -14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 16 -16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000001 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000001 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000003 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000003 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000005 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000005 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000011 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000011 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000013 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000013 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000015 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2000015 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 14 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 14 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -13 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 14 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 16 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 16 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 16 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 12 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 12 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -11 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 12 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 16 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -15 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 16 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -15 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -15 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 16 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -15 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 12 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -11 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 12 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -11 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -11 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 12 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -11 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 14 -11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -13 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 14 -13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -13 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -13 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 14 -15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -13 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -1 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -2 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -3 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -4 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -6 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -1 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -2 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -3 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -4 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -6 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -1 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -1 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -1 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -2 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -1 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -3 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -3 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -3 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -4 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -3 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -5 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -5 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 -5 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -6 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 -5 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 6 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2 6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -3 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="4 6 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="6 6 3"/>
+</particle>
+
+<particle id="1000039" name="~Gravitino" spinType="0" chargeType="0" colType="0"
+ m0="1.000e-03">
+</particle>
+
+<particle id="2000001" name="~d_R" antiName="~d_Rbar" spinType="1" chargeType="-1" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000002 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -5"/>
+</particle>
+
+<particle id="2000002" name="~u_R" antiName="~u_Rbar" spinType="1" chargeType="2" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000002 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000001 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000001 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5"/>
+</particle>
+
+<particle id="2000003" name="~s_R" antiName="~s_Rbar" spinType="1" chargeType="-1" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000004 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -5"/>
+</particle>
+
+<particle id="2000004" name="~c_R" antiName="~c_Rbar" spinType="1" chargeType="2" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000004 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000003 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000003 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5"/>
+</particle>
+
+<particle id="2000005" name="~b_2" antiName="~b_2bar" spinType="1" chargeType="-1" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000006 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="11 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="13 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 2"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 4"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="15 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 -3"/>
+</particle>
+
+<particle id="2000006" name="~t_2" antiName="~t_2bar" spinType="1" chargeType="2" colType="1"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000024 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000037 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000006 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000005 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000005 37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000021 6"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-11 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-13 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-15 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1 -5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-3 -5"/>
+</particle>
+
+<particle id="2000011" name="~e_R-" antiName="~e_R+" spinType="1" chargeType="-3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 12"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000011 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000012 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000012 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 5"/>
+</particle>
+
+<particle id="2000012" name="~nu_eR" antiName="~nu_eRbar" spinType="1" chargeType="0" colType="0"
+ m0="500.00000">
+</particle>
+
+<particle id="2000013" name="~mu_R-" antiName="~mu_R+" spinType="1" chargeType="-3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 14"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000013 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000014 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000014 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-16 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 5"/>
+</particle>
+
+<particle id="2000014" name="~nu_muR" antiName="~nu_muRbar" spinType="1" chargeType="0" colType="0"
+ m0="500.00000">
+</particle>
+
+<particle id="2000015" name="~tau_2-" antiName="~tau_2+" spinType="1" chargeType="-3" colType="0"
+ m0="500.00000" mWidth="1.00000" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000039 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000024 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-1000037 16"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000022 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000023 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000025 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000035 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 23"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 25"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 35"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000015 36"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -24"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="1000016 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="2000016 -37"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="16 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-12 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 11"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 13"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-14 15"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-2 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-4 5"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 1"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 3"/>
+ <channel onMode="1" bRatio="0.0000000" meMode="103" products="-6 5"/>
+</particle>
+
+<particle id="2000016" name="~nu_tauR" antiName="~nu_tauRbar" spinType="1" chargeType="0" colType="0"
+ m0="500.00000">
+</particle>
+
+<particle id="3000111" name="pi_tc0" spinType="1" chargeType="0" colType="0"
+ m0="110.00000" mWidth="0.02911" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0174310" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0540480" products="4 -4"/>
+ <channel onMode="1" bRatio="0.8576940" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0002500" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0705780" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" products="21 21"/>
+</particle>
+
+<particle id="3000113" name="rho_tc0" spinType="3" chargeType="0" colType="0"
+ m0="210.00000" mWidth="0.86860" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1440510" products="24 -24"/>
+ <channel onMode="1" bRatio="0.3519020" products="24 -3000211"/>
+ <channel onMode="1" bRatio="0.3519020" products="3000211 -24"/>
+ <channel onMode="1" bRatio="0.0000000" products="3000211 -3000211"/>
+ <channel onMode="1" bRatio="0.0821070" products="22 3000111"/>
+ <channel onMode="1" bRatio="0.0295660" products="22 3000221"/>
+ <channel onMode="1" bRatio="0.0015110" products="23 3000111"/>
+ <channel onMode="1" bRatio="0.0007260" products="23 3000221"/>
+ <channel onMode="1" bRatio="0.0045180" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0065220" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0045180" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0065220" products="4 -4"/>
+ <channel onMode="1" bRatio="0.0045130" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0029080" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0009730" products="12 -12"/>
+ <channel onMode="1" bRatio="0.0029080" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0009730" products="14 -14"/>
+ <channel onMode="1" bRatio="0.0029080" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0009730" products="16 -16"/>
+</particle>
+
+<particle id="3000211" name="pi_tc+" antiName="pi_tc-" spinType="1" chargeType="3" colType="0"
+ m0="110.00000" mWidth="0.01741" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0227480" products="4 -1"/>
+ <channel onMode="1" bRatio="0.0265760" products="4 -3"/>
+ <channel onMode="1" bRatio="0.3594860" products="2 -5"/>
+ <channel onMode="1" bRatio="0.5615810" products="4 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="24 5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="-11 12"/>
+ <channel onMode="1" bRatio="0.0001040" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0295040" products="-15 16"/>
+</particle>
+
+<particle id="3000213" name="rho_tc+" antiName="rho_tc-" spinType="3" chargeType="3" colType="0"
+ m0="210.00000" mWidth="0.62395" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1439820" products="24 23"/>
+ <channel onMode="1" bRatio="0.4898880" products="24 3000111"/>
+ <channel onMode="1" bRatio="0.1951000" products="3000211 23"/>
+ <channel onMode="1" bRatio="0.0000000" products="3000211 3000111"/>
+ <channel onMode="1" bRatio="0.1143020" products="3000211 22"/>
+ <channel onMode="1" bRatio="0.0084260" products="24 3000221"/>
+ <channel onMode="1" bRatio="0.0148680" products="-1 2"/>
+ <channel onMode="1" bRatio="0.0007630" products="-1 4"/>
+ <channel onMode="1" bRatio="0.0000000" products="-1 6"/>
+ <channel onMode="1" bRatio="0.0007630" products="-3 2"/>
+ <channel onMode="1" bRatio="0.0148400" products="-3 4"/>
+ <channel onMode="1" bRatio="0.0000030" products="-3 6"/>
+ <channel onMode="1" bRatio="0.0000000" products="-5 2"/>
+ <channel onMode="1" bRatio="0.0000270" products="-5 4"/>
+ <channel onMode="1" bRatio="0.0019450" products="-5 6"/>
+ <channel onMode="1" bRatio="0.0050300" products="-11 12"/>
+ <channel onMode="1" bRatio="0.0050300" products="-13 14"/>
+ <channel onMode="1" bRatio="0.0050300" products="-15 16"/>
+</particle>
+
+<particle id="3000221" name="pi'_tc0" spinType="1" chargeType="0" colType="0"
+ m0="110.00000" mWidth="0.04536" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0111850" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0346810" products="4 -4"/>
+ <channel onMode="1" bRatio="0.5503540" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0001600" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0452870" products="15 -15"/>
+ <channel onMode="1" bRatio="0.3583330" products="21 21"/>
+</particle>
+
+<particle id="3000223" name="omega_tc" spinType="3" chargeType="0" colType="0"
+ m0="210.00000" mWidth="0.19192" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1337760" products="22 3000111"/>
+ <channel onMode="1" bRatio="0.0032840" products="23 3000111"/>
+ <channel onMode="1" bRatio="0.3716900" products="22 3000221"/>
+ <channel onMode="1" bRatio="0.0068380" products="23 3000221"/>
+ <channel onMode="1" bRatio="0.0309540" products="24 -3000211"/>
+ <channel onMode="1" bRatio="0.0309540" products="3000211 -24"/>
+ <channel onMode="1" bRatio="0.0016300" products="24 -24"/>
+ <channel onMode="1" bRatio="0.0000000" products="3000211 -3000211"/>
+ <channel onMode="1" bRatio="0.0472240" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0737370" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0472240" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0737320" products="4 -4"/>
+ <channel onMode="1" bRatio="0.0471790" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0347610" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0091660" products="12 -12"/>
+ <channel onMode="1" bRatio="0.0347610" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0091660" products="14 -14"/>
+ <channel onMode="1" bRatio="0.0347590" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0091660" products="16 -16"/>
+</particle>
+
+<particle id="3000331" name="eta_tc0" spinType="1" chargeType="0" colType="2"
+ m0="350.00000" mWidth="0.09511" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.4457810" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.5542190" products="21 21"/>
+</particle>
+
+<particle id="3100021" name="V8_tc" spinType="1" chargeType="0" colType="2"
+ m0="500.00000" mWidth="123.27638" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0090690" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0090690" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0090690" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0090690" products="4 -4"/>
+ <channel onMode="1" bRatio="0.5101470" products="5 -5"/>
+ <channel onMode="1" bRatio="0.4535760" products="6 -6"/>
+</particle>
+
+<particle id="3100111" name="pi_22_1_tc" spinType="1" chargeType="0" colType="0"
+ m0="125.00000" mWidth="0.02296" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" products="4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="1.0000000" products="21 21"/>
+</particle>
+
+<particle id="3100113" name="rho_11_tc" spinType="3" chargeType="0" colType="2"
+ m0="400.00000" mWidth="23.26819" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0011280" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0011280" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0011280" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0011280" products="4 -4"/>
+ <channel onMode="1" bRatio="0.5710470" products="5 -5"/>
+ <channel onMode="1" bRatio="0.3822880" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0421530" products="21 21"/>
+</particle>
+
+<particle id="3200111" name="pi_22_8_tc" spinType="1" chargeType="0" colType="2"
+ m0="250.00000" mWidth="0.18886" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0000000" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0000000" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0000000" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0000000" products="4 -4"/>
+ <channel onMode="1" bRatio="0.0000000" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="1.0000000" products="21 21"/>
+</particle>
+
+<particle id="3200113" name="rho_12_tc" spinType="3" chargeType="0" colType="2"
+ m0="350.00000" mWidth="2.86306" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0165970" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0165970" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0165970" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0165970" products="4 -4"/>
+ <channel onMode="1" bRatio="0.9336100" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+</particle>
+
+<particle id="3300113" name="rho_21_tc" spinType="3" chargeType="0" colType="2"
+ m0="350.00000">
+ <channel onMode="1" bRatio="0.0165970" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0165970" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0165970" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0165970" products="4 -4"/>
+ <channel onMode="1" bRatio="0.9336100" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+</particle>
+
+<particle id="3400113" name="rho_22_tc" spinType="3" chargeType="0" colType="2"
+ m0="300.00000" mWidth="3.45903" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0551500" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0551500" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0551500" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0551500" products="4 -4"/>
+ <channel onMode="1" bRatio="0.3446900" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0000000" products="6 -6"/>
+ <channel onMode="1" bRatio="0.2289980" products="21 21"/>
+ <channel onMode="1" bRatio="0.1642080" products="3100111 21"/>
+ <channel onMode="1" bRatio="0.0415030" products="3200111 21"/>
+</particle>
+
+<particle id="4000001" name="d*" antiName="d*bar" spinType="2" chargeType="-1" colType="1"
+ m0="400.00000" mWidth="2.59359" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.8509730" products="21 1"/>
+ <channel onMode="1" bRatio="0.0054110" products="22 1"/>
+ <channel onMode="1" bRatio="0.0450250" products="23 1"/>
+ <channel onMode="1" bRatio="0.0985910" products="-24 2"/>
+</particle>
+
+<particle id="4000002" name="u*" antiName="u*bar" spinType="2" chargeType="2" colType="1"
+ m0="400.00000" mWidth="2.59687" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.8498980" products="21 2"/>
+ <channel onMode="1" bRatio="0.0216170" products="22 2"/>
+ <channel onMode="1" bRatio="0.0300180" products="23 2"/>
+ <channel onMode="1" bRatio="0.0984660" products="24 1"/>
+</particle>
+
+<particle id="4000003" name="s*" antiName="s*bar" spinType="2" chargeType="-1" colType="1"
+ m0="400.00000" mWidth="2.59359" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.8509730" products="21 3"/>
+ <channel onMode="1" bRatio="0.0054110" products="22 3"/>
+ <channel onMode="1" bRatio="0.0450250" products="23 3"/>
+ <channel onMode="1" bRatio="0.0985910" products="-24 4"/>
+</particle>
+
+<particle id="4000004" name="c*" antiName="c*bar" spinType="2" chargeType="2" colType="1"
+ m0="400.00000" mWidth="2.59687" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.8498980" products="21 4"/>
+ <channel onMode="1" bRatio="0.0216170" products="22 4"/>
+ <channel onMode="1" bRatio="0.0300180" products="23 4"/>
+ <channel onMode="1" bRatio="0.0984660" products="24 3"/>
+</particle>
+
+<particle id="4000005" name="b*" antiName="b*bar" spinType="2" chargeType="-1" colType="1"
+ m0="400.00000" mWidth="2.59359" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.8509730" products="21 5"/>
+ <channel onMode="1" bRatio="0.0054110" products="22 5"/>
+ <channel onMode="1" bRatio="0.0450250" products="23 5"/>
+ <channel onMode="1" bRatio="0.0985910" products="-24 6"/>
+</particle>
+
+<particle id="4000006" name="t*" antiName="t*bar" spinType="2" chargeType="2" colType="1"
+ m0="400.00000" mWidth="2.59687" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.8498980" products="21 6"/>
+ <channel onMode="1" bRatio="0.0216170" products="22 6"/>
+ <channel onMode="1" bRatio="0.0300180" products="23 6"/>
+ <channel onMode="1" bRatio="0.0984660" products="24 5"/>
+</particle>
+
+<particle id="4000011" name="e*-" antiName="e*bar+" spinType="2" chargeType="-3" colType="0"
+ m0="400.00000" mWidth="0.42896" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.2944480" products="22 11"/>
+ <channel onMode="1" bRatio="0.1094500" products="23 11"/>
+ <channel onMode="1" bRatio="0.5961020" products="-24 12"/>
+</particle>
+
+<particle id="4000012" name="nu*_e0" antiName="nu*_ebar0" spinType="2" chargeType="0" colType="0"
+ m0="400.00000" mWidth="0.41912" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.3899060" products="23 12"/>
+ <channel onMode="1" bRatio="0.6100940" products="24 11"/>
+</particle>
+
+<particle id="4000013" name="mu*-" antiName="mu*bar+" spinType="2" chargeType="-3" colType="0"
+ m0="400.00000" mWidth="0.42896" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.2944480" products="22 13"/>
+ <channel onMode="1" bRatio="0.1094500" products="23 13"/>
+ <channel onMode="1" bRatio="0.5961020" products="-24 14"/>
+</particle>
+
+<particle id="4000014" name="nu*_mu0" antiName="nu*_mubar0" spinType="2" chargeType="0" colType="0"
+ m0="400.00000" mWidth="0.41912" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.3899060" products="23 14"/>
+ <channel onMode="1" bRatio="0.6100940" products="24 13"/>
+</particle>
+
+<particle id="4000015" name="tau*-" antiName="tau*bar+" spinType="2" chargeType="-3" colType="0"
+ m0="400.00000" mWidth="0.42896" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.2944480" products="22 15"/>
+ <channel onMode="1" bRatio="0.1094500" products="23 15"/>
+ <channel onMode="1" bRatio="0.5961020" products="-24 126"/>
+</particle>
+
+<particle id="4000016" name="nu*_tau0" antiName="nu*_taubar0" spinType="2" chargeType="0" colType="0"
+ m0="400.00000" mWidth="0.41912" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.3899060" products="23 16"/>
+ <channel onMode="1" bRatio="0.6100940" products="24 15"/>
+</particle>
+
+<particle id="5000039" name="Graviton*" spinType="5" chargeType="0" colType="0"
+ m0="1.000e+03" mWidth="1.415e-01" mMin="5.000e+01" mMax="0.000e+00">
+ <channel onMode="1" bRatio="0.0633000" products="1 -1"/>
+ <channel onMode="1" bRatio="0.0633000" products="2 -2"/>
+ <channel onMode="1" bRatio="0.0633000" products="3 -3"/>
+ <channel onMode="1" bRatio="0.0632990" products="4 -4"/>
+ <channel onMode="1" bRatio="0.0632950" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0562810" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0204950" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0204950" products="12 -12"/>
+ <channel onMode="1" bRatio="0.0204950" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0204950" products="14 -14"/>
+ <channel onMode="1" bRatio="0.0204950" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0204950" products="16 -16"/>
+ <channel onMode="1" bRatio="0.3279190" products="21 21"/>
+ <channel onMode="1" bRatio="0.0409900" products="22 22"/>
+ <channel onMode="1" bRatio="0.0452360" products="23 23"/>
+ <channel onMode="1" bRatio="0.0901120" products="24 -24"/>
+</particle>
+
+<particle id="9000111" name="a_0(980)0" spinType="1" chargeType="0" colType="0"
+ m0="0.98350" mWidth="0.06000" mMin="0.70000" mMax="1.50000">
+ <channel onMode="1" bRatio="0.9000000" products="221 111"/>
+ <channel onMode="1" bRatio="0.0250000" products="130 130"/>
+ <channel onMode="1" bRatio="0.0250000" products="310 310"/>
+ <channel onMode="1" bRatio="0.0500000" products="321 -321"/>
+</particle>
+
+<particle id="9000211" name="a_0(980)+" antiName="a_0(980)-" spinType="1" chargeType="3" colType="0"
+ m0="0.98350" mWidth="0.06000" mMin="0.70000" mMax="1.50000">
+ <channel onMode="1" bRatio="0.9000000" products="221 211"/>
+ <channel onMode="1" bRatio="0.1000000" products="321 311"/>
+</particle>
+
+<particle id="9010221" name="f_0(980)" spinType="1" chargeType="0" colType="0"
+ m0="1.00000">
+ <channel onMode="1" bRatio="0.5200000" products="211 -211"/>
+ <channel onMode="1" bRatio="0.2600000" products="111 111"/>
+ <channel onMode="1" bRatio="0.1100000" products="321 -321"/>
+ <channel onMode="1" bRatio="0.0550000" products="130 130"/>
+ <channel onMode="1" bRatio="0.0550000" products="310 310"/>
+</particle>
+
+<particle id="9900012" name="nu_Re" spinType="2" chargeType="0" colType="0"
+ m0="500.00000" mWidth="0.00098" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1987400" products="11 -1 2"/>
+ <channel onMode="1" bRatio="0.0102040" products="11 -1 4"/>
+ <channel onMode="1" bRatio="0.0000030" products="11 -1 6"/>
+ <channel onMode="1" bRatio="0.0102050" products="11 -3 2"/>
+ <channel onMode="1" bRatio="0.1983560" products="11 -3 4"/>
+ <channel onMode="1" bRatio="0.0001510" products="11 -3 6"/>
+ <channel onMode="1" bRatio="0.0000060" products="11 -5 2"/>
+ <channel onMode="1" bRatio="0.0003670" products="11 -5 4"/>
+ <channel onMode="1" bRatio="0.0819670" products="11 -5 6"/>
+ <channel onMode="1" bRatio="0.1987400" products="-11 1 -2"/>
+ <channel onMode="1" bRatio="0.0102040" products="-11 1 -4"/>
+ <channel onMode="1" bRatio="0.0000030" products="-11 1 -6"/>
+ <channel onMode="1" bRatio="0.0102050" products="-11 3 -2"/>
+ <channel onMode="1" bRatio="0.1983560" products="-11 3 -4"/>
+ <channel onMode="1" bRatio="0.0001510" products="-11 3 -6"/>
+ <channel onMode="1" bRatio="0.0000060" products="-11 5 -2"/>
+ <channel onMode="1" bRatio="0.0003670" products="-11 5 -4"/>
+ <channel onMode="1" bRatio="0.0819670" products="-11 5 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="11 -13 9900014"/>
+ <channel onMode="1" bRatio="0.0000000" products="11 -13 9900014"/>
+ <channel onMode="1" bRatio="0.0000000" products="-11 15 9900016"/>
+ <channel onMode="1" bRatio="0.0000000" products="-11 15 9900016"/>
+</particle>
+
+<particle id="9900014" name="nu_Rmu" spinType="2" chargeType="0" colType="0"
+ m0="500.00000" mWidth="0.00098" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1987760" products="13 -1 2"/>
+ <channel onMode="1" bRatio="0.0102060" products="13 -1 4"/>
+ <channel onMode="1" bRatio="0.0000030" products="13 -1 6"/>
+ <channel onMode="1" bRatio="0.0102070" products="13 -3 2"/>
+ <channel onMode="1" bRatio="0.1983900" products="13 -3 4"/>
+ <channel onMode="1" bRatio="0.0001510" products="13 -3 6"/>
+ <channel onMode="1" bRatio="0.0000060" products="13 -5 2"/>
+ <channel onMode="1" bRatio="0.0003670" products="13 -5 4"/>
+ <channel onMode="1" bRatio="0.0818930" products="13 -5 6"/>
+ <channel onMode="1" bRatio="0.1987760" products="-13 1 -2"/>
+ <channel onMode="1" bRatio="0.0102060" products="-13 1 -4"/>
+ <channel onMode="1" bRatio="0.0000030" products="-13 1 -6"/>
+ <channel onMode="1" bRatio="0.0102070" products="-13 3 -2"/>
+ <channel onMode="1" bRatio="0.1983900" products="-13 3 -4"/>
+ <channel onMode="1" bRatio="0.0001510" products="-13 3 -6"/>
+ <channel onMode="1" bRatio="0.0000060" products="-13 5 -2"/>
+ <channel onMode="1" bRatio="0.0003670" products="-13 5 -4"/>
+ <channel onMode="1" bRatio="0.0818930" products="-13 5 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="13 -11 9900012"/>
+ <channel onMode="1" bRatio="0.0000000" products="13 -11 9900012"/>
+ <channel onMode="1" bRatio="0.0000000" products="-13 15 9900016"/>
+ <channel onMode="1" bRatio="0.0000000" products="-13 15 9900016"/>
+</particle>
+
+<particle id="9900016" name="nu_Rtau" spinType="2" chargeType="0" colType="0"
+ m0="500.00000" mWidth="0.00097" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.1993440" products="15 -1 2"/>
+ <channel onMode="1" bRatio="0.0102340" products="15 -1 4"/>
+ <channel onMode="1" bRatio="0.0000030" products="15 -1 6"/>
+ <channel onMode="1" bRatio="0.0102360" products="15 -3 2"/>
+ <channel onMode="1" bRatio="0.1989280" products="15 -3 4"/>
+ <channel onMode="1" bRatio="0.0001490" products="15 -3 6"/>
+ <channel onMode="1" bRatio="0.0000060" products="15 -5 2"/>
+ <channel onMode="1" bRatio="0.0003680" products="15 -5 4"/>
+ <channel onMode="1" bRatio="0.0807330" products="15 -5 6"/>
+ <channel onMode="1" bRatio="0.1993440" products="-15 1 -2"/>
+ <channel onMode="1" bRatio="0.0102340" products="-15 1 -4"/>
+ <channel onMode="1" bRatio="0.0000030" products="-15 1 -6"/>
+ <channel onMode="1" bRatio="0.0102360" products="-15 3 -2"/>
+ <channel onMode="1" bRatio="0.1989280" products="-15 3 -4"/>
+ <channel onMode="1" bRatio="0.0001490" products="-15 3 -6"/>
+ <channel onMode="1" bRatio="0.0000060" products="-15 5 -2"/>
+ <channel onMode="1" bRatio="0.0003680" products="-15 5 -4"/>
+ <channel onMode="1" bRatio="0.0807330" products="-15 5 -6"/>
+ <channel onMode="1" bRatio="0.0000000" products="15 -11 9900012"/>
+ <channel onMode="1" bRatio="0.0000000" products="15 -11 9900012"/>
+ <channel onMode="1" bRatio="0.0000000" products="-15 13 9900014"/>
+ <channel onMode="1" bRatio="0.0000000" products="-15 13 9900014"/>
+</particle>
+
+<particle id="9900023" name="Z_R0" spinType="3" chargeType="0" colType="0"
+ m0="1.200e+03" mWidth="2.672e+01" mMin="5.000e+01" mMax="0.000e+00">
+ <channel onMode="1" bRatio="0.1847380" products="1 -1"/>
+ <channel onMode="1" bRatio="0.1045880" products="2 -2"/>
+ <channel onMode="1" bRatio="0.1847380" products="3 -3"/>
+ <channel onMode="1" bRatio="0.1045870" products="4 -4"/>
+ <channel onMode="1" bRatio="0.1847310" products="5 -5"/>
+ <channel onMode="1" bRatio="0.0958200" products="6 -6"/>
+ <channel onMode="1" bRatio="0.0229020" products="11 -11"/>
+ <channel onMode="1" bRatio="0.0084290" products="12 -12"/>
+ <channel onMode="1" bRatio="0.0156020" products="9900012 9900012"/>
+ <channel onMode="1" bRatio="0.0229020" products="13 -13"/>
+ <channel onMode="1" bRatio="0.0084290" products="14 -14"/>
+ <channel onMode="1" bRatio="0.0156020" products="9900014 9900014"/>
+ <channel onMode="1" bRatio="0.0229020" products="15 -15"/>
+ <channel onMode="1" bRatio="0.0084290" products="16 -16"/>
+ <channel onMode="1" bRatio="0.0156020" products="9900016 9900016"/>
+</particle>
+
+<particle id="9900024" name="W_R+" antiName="W_R-" spinType="3" chargeType="3" colType="0"
+ m0="750.00000" mWidth="21.74916" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.2895900" products="-1 2"/>
+ <channel onMode="1" bRatio="0.0148700" products="-1 4"/>
+ <channel onMode="1" bRatio="0.0000080" products="-1 6"/>
+ <channel onMode="1" bRatio="0.0148700" products="-3 2"/>
+ <channel onMode="1" bRatio="0.2890610" products="-3 4"/>
+ <channel onMode="1" bRatio="0.0004920" products="-3 6"/>
+ <channel onMode="1" bRatio="0.0000090" products="-5 2"/>
+ <channel onMode="1" bRatio="0.0005360" products="-5 4"/>
+ <channel onMode="1" bRatio="0.2791100" products="-5 6"/>
+ <channel onMode="1" bRatio="0.0371510" products="-11 9900012"/>
+ <channel onMode="1" bRatio="0.0371510" products="-13 9900014"/>
+ <channel onMode="1" bRatio="0.0371500" products="-15 9900016"/>
+</particle>
+
+<particle id="9900041" name="H_L++" antiName="H_L--" spinType="1" chargeType="6" colType="0"
+ m0="200.00000" mWidth="0.88159" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0902660" products="-11 -11"/>
+ <channel onMode="1" bRatio="0.0018050" products="-11 -13"/>
+ <channel onMode="1" bRatio="0.0018050" products="-11 -15"/>
+ <channel onMode="1" bRatio="0.0902660" products="-13 -13"/>
+ <channel onMode="1" bRatio="0.0018050" products="-13 -15"/>
+ <channel onMode="1" bRatio="0.8122630" products="-15 -15"/>
+ <channel onMode="1" bRatio="0.0017900" products="24 24"/>
+</particle>
+
+<particle id="9900042" name="H_R++" antiName="H_R--" spinType="1" chargeType="6" colType="0"
+ m0="200.00000" mWidth="0.88001" mMin="50.00000" mMax="0.00000">
+ <channel onMode="1" bRatio="0.0904280" products="-11 -11"/>
+ <channel onMode="1" bRatio="0.0018090" products="-11 -13"/>
+ <channel onMode="1" bRatio="0.0018080" products="-11 -15"/>
+ <channel onMode="1" bRatio="0.0904280" products="-13 -13"/>
+ <channel onMode="1" bRatio="0.0018080" products="-13 -15"/>
+ <channel onMode="1" bRatio="0.8137200" products="-15 -15"/>
+ <channel onMode="1" bRatio="0.0000000" products="9900024 9900024"/>
+</particle>
+
+<particle id="9900110" name="rho_diff0" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="9900210" name="pi_diffr+" antiName="pi_diffr-" spinType="0" chargeType="3" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="9900220" name="omega_di" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="9900330" name="phi_diff" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="9900440" name="J/psi_di" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="9900441" name="ccbar[1S0(8)]" spinType="1" chargeType="0" colType="2"
+ m0="3.10000" mWidth="0.01000" mMin="3.10000" mMax="3.10000">
+ <channel onMode="1" bRatio="1.0000000" products="443 21"/>
+</particle>
+
+<particle id="9900443" name="ccbar[3S1(8)]" spinType="3" chargeType="0" colType="2"
+ m0="3.10000" mWidth="0.01000" mMin="3.10000" mMax="3.10000">
+ <channel onMode="1" bRatio="1.0000000" products="443 21"/>
+</particle>
+
+<particle id="9900551" name="bbbar[1S0(8)]" spinType="1" chargeType="0" colType="2"
+ m0="9.50000" mWidth="0.01000" mMin="9.50000" mMax="9.50000">
+ <channel onMode="1" bRatio="1.0000000" products="553 21"/>
+</particle>
+
+<particle id="9900553" name="bbbar[3S1(8)]" spinType="3" chargeType="0" colType="2"
+ m0="9.50000" mWidth="0.01000" mMin="9.50000" mMax="9.50000">
+ <channel onMode="1" bRatio="1.0000000" products="553 21"/>
+</particle>
+
+<particle id="9902110" name="n_diffr0" antiName="n_diffrbar0" spinType="0" chargeType="0" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="9902210" name="p_diffr+" antiName="p_diffrbar-" spinType="0" chargeType="3" colType="0"
+ m0="0.00000">
+</particle>
+
+<particle id="9910441" name="ccbar[3P0(8)]" spinType="1" chargeType="0" colType="2"
+ m0="3.10000" mWidth="0.01000" mMin="3.10000" mMax="3.10000">
+ <channel onMode="1" bRatio="1.0000000" products="443 21"/>
+</particle>
+
+<particle id="9910551" name="bbbar[3P0(8)]" spinType="1" chargeType="0" colType="2"
+ m0="9.50000" mWidth="0.01000" mMin="9.50000" mMax="9.50000">
+ <channel onMode="1" bRatio="1.0000000" products="553 21"/>
+</particle>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="The Particle Data Scheme">
+
+<h2>The Particle Data Scheme</h2>
+
+The particle data scheme may take somewhat longer to understand than
+the settings one. In particular the set of methods to access information
+is rather more varied, to allow better functionality for advanced usage.
+However, PYTHIA does come with a sensible default set of particle
+properties and decay tables. Thus there is no need to learn any of the
+methods on this page to get going. Only when you perceive a specific need
+does it make sense to learn the basics.
+
+<p/>
+The central section on this page is the Operation one. The preceding
+sections are mainly there to introduce the basic structure and the set
+of properties that can be accessed.
+
+<h3>Databases</h3>
+
+The management of particle data is based on the four classes:
+<ul>
+<li><code>ParticleDataEntry</code>, which stores the relevant information
+on a particle species, and</li>
+<li><code>ParticleDataTable</code>, which is a map of PDG particle
+<code>id</code> numbers <ref>Yao06</ref> onto the relevant
+<code>ParticleDataEntry</code>.</li>
+<li><code>DecayChannel</code>, which stores info on one particular decay
+mode.</li>
+<li><code>DecayTable</code>, which is a vector of
+<code>DecayChannel</code>'s, containing all the decay modes of a
+particle, and also methods for picking a decay mode.</li>
+</ul>
+The objects of these classes together form a database that is
+continuously being used as the program has to assign particle masses,
+decay modes etc.
+
+<p/>
+The <code>ParticleDataTable</code> class is purely static, i.e. you
+can interact with it directly by
+<code>ParticleDataTable::command(argument)</code>.
+However, a <code>particleData</code> object of the
+<code>ParticleDataTable</code> class is a public member of the
+<code>Pythia</code> class, so an alternative
+notation would be <code>pythia.particleData.command(argument)</code>,
+assuming that <code>pythia</code> is an instance of the
+<code>Pythia</code> class. Further, for some of the most frequent user
+tasks, <code>Pythia</code> methods have been defined, so that
+<code>pythia.command(argument)</code>
+would work, see further below.
+
+<p/>
+A fundamental difference between the <code>ParticleData</code>
+classes and the <code>Settings</code> ones is that the former
+are accessed regularly during the event generation process, as a new
+particle is produced and its mass need to be set, e.g., while
+<code>Settings</code> is mainly/only used at the initialization stage.
+Nevertheless, it is not a good idea to change data in either of them
+in mid-run, since this may lead to inconsistencies.
+
+<h3>Stored properties for particles</h3>
+
+Currently the following particle properties are stored in the
+<code>ParticleDataTable</code> for a given PDG particle identity code
+<code>id</code>, here presented by the name used to access this property:
+
+<method name="name(id)">
+particle and antiparticle names are stored separately, the sign of
+<code>id</code> determines which of the two is returned, with
+<code>void</code> used to indicate the absence of an antiparticle.
+</method>
+
+<method name="spinType(id)">
+the spin type, of the form <ei>2 s + 1</ei>, with special code 0
+for entries of unknown or indeterminate spin.
+</method>
+
+<method name="chargeType(id)">
+three times the charge (to make it an integer), taking into account
+the sign of <code>id</code>.
+</method>
+
+<method name="colType(id)">
+the colour type, with 0 uncoloured, 1 triplet, -1 antitriplet and 2
+octet, taking into account the sign of <code>id</code>.
+</method>
+
+<method name="m0(id)">
+the nominal mass <ei>m_0</ei> (in GeV).
+</method>
+
+<method name="mWidth(id)">
+the width <ei>Gamma</ei> of the Breit-Wigner distribution (in GeV).
+</method>
+
+<method name="mMin(id), mMax(id)">
+the lower and upper limit, respectively, of the allowed mass range
+generated by the Breit-Wigner (in GeV). If <ei>mMax < mMin</ei>
+then no upper limit is imposed. Have no meanings for particles
+without width, and would typically be 0 there.
+</method>
+
+<method name="tau0(id)">
+the nominal proper lifetime <ei>tau_0</ei> (in mm/c).
+</method>
+
+<method name="isResonance(id)">
+a flag telling whether a particle species are considered as a resonance
+or not. Here <aloc href="ResonanceDecays">"resonance"</aloc>
+is used as shorthand for any massive particle
+where the decay process should be counted as part of the hard process
+itself, and thus be performed before showers and other event aspects
+are added. Restrictions on allowed decay channels is also directly
+reflected in the cross section of simulated processes, while those of
+normal hadrons and other light particles are not.
+In practice, it is reserved for states above the <ei>b bbar</ei>
+bound systems in mass, i.e. for <ei>W, Z, t</ei>, Higgs states,
+supersymmetric states and (most?) other states in any new theory.
+All particles with <code>m0</code> above 20 GeV are by default
+initialized to be considered as resonances.
+</method>
+
+<method name="mayDecay(id)">
+a flag telling whether a particle species may decay or not, offering
+the main user switch. Whether a given particle of this kind then actually
+will decay also depends on it having allowed decay channels, and on
+other flags for <aloc href="ParticleDecays">particle decays</aloc>.
+All particles with <code>tau0</code> below 1000 mm are
+by default initialized to allow decays.
+</method>
+
+<method name="doExternalDecay(id)">
+a flag telling whether a particle should be handled by an external
+decay package or not, with the latter default. Can be manipulated as
+described on this page, but should normally not be. Instead the
+<aloc href="ExternalDecays"><code>pythia.decayPtr</code></aloc>
+method should be provided with the list of relevant particles.
+</method>
+
+<method name="isVisible(id)">
+a flag telling whether a particle species is to be considered as
+visible in a detector or not, as used e.g. in analysis routines.
+By default this includes neutrinos and a few BSM particles
+(gravitino, sneutrinos, neutralinos) that have neither strong nor
+electromagnetic charge, and are not made up of constituents that
+have it. The value of this flag is only relevant if a particle is
+long-lived enough actually to make it to a detector.
+</method>
+
+<method name="doForceWidth(id)">
+a flag valid only for resonances where PYTHIA contains code to
+calculate the width of the resonance from encoded matrix-element
+expressions, i.e. the <ei>Z^0</ei>, <ei>W^+-</ei>, <ei>t</ei>,
+<ei>h^0</ei>, and a few more. The normal behaviour (<code>false</code>)
+is then that the width is calculated from the mass, but it is
+possible to <aloc href="ResonanceDecays">force</aloc> the resonance
+to retain the nominal width. Branching ratios and the running of the
+total width are unaffected.
+</method>
+
+<p/>
+Similarly-named methods can also be used to set these properties.
+We do not provide the details here, since other methods to be
+introduced below are the ones likely to be used for such tasks.
+(Normally the correspondence is obvious in the header file, but
+for the name you either can use two methods to set name and
+antiparticle name separately, or use one method that takes them
+both as input.)
+
+<p/>
+There are some further methods for output only, i.e. properties
+that cannot be set directly:
+
+<method name="particleDataPtr(id)">
+returns a pointer to the <code>ParticleDataEntry</code> object.
+</method>
+
+<method name="hasAnti(id)">
+bool whether a distinct antiparticle exists or not. Is true if an
+antiparticle name has been set (and is different from
+<code>void</code>).
+</method>
+
+<method name="charge(id)">
+the electrical charge of a particle, as a <code>double</code> equal
+to <code>chargeType(id)/3</code>.
+
+<method name="mass(id)">
+returns a mass distributed according to a truncated Breit-Wigner,
+with parameters as above (see also the
+<code>ParticleData:modeBreitWigner</code> switch). Is equal to
+<code>m0(id)</code> for particles without width.
+</method>
+
+<method name="constituentMass(id)">
+is the constituent mass for a quark, hardcoded as
+<ei>m_u = m_d = 0.325</ei>, <ei>m_s = 0.50</ei>, <ei>m_c = 1.60</ei>
+and <ei>m_b = 5.0</ei> GeV, for a diquark the sum of quark constituent
+masses, and for everything else the same as the ordinary mass.
+</method>
+
+<method name="m0Min(id), m0Max(id)">
+similar to <code>mMin()</code> and <code>mMax()</code>, except that
+for particles with no width the <code>m0(id)</code> value is returned.
+</method>
+
+<method name="isLepton(id)">
+true for a lepton or an antilepton (including neutrinos).
+</method>
+
+<method name="isQuark(id)">
+true for a quark or an antiquark.
+</method>
+
+<method name="isGluon(id)">
+true for a gluon.
+</method>
+
+<method name="isHadron(id)">
+true for a hadron (made up out of normal quarks and gluons,
+i.e. not for R-hadrons and other exotic states).
+</method>
+
+<method name="heaviestQuark(id)">
+extracts the heaviest quark or antiquark, i.e. one with largest
+<code>id</code> number, for a hadron.
+</method>
+
+<h3>Stored properties for decays</h3>
+
+The following properties are stored for each decay channel:
+
+<method name="onMode()">
+0 if a channel is off,<br/>
+1 if on,<br/>
+2 if on for a particle but off for an antiparticle,<br/>
+3 if on for an antiparticle but off for a particle.<br/>
+If a particle is its own antiparticle then 2 is on and 3 off
+but, of course, for such particles it is much simpler and safer
+to use only 1 and 0.<br/>
+The 2 and 3 options can be used e.g. to encode CP violation in
+B decays, or to let the <ei>W</ei>'s in a <ei>q qbar -> W^+ W^-</ei>
+process decay in different channels.
+</method>
+
+<method name="bRatio()">
+the branching ratio.
+</method>
+
+<method name="meMode()">
+the mode of processing this channel, possibly with matrix elements
+(see the <aloc href="ParticleDecays">particle decays</aloc> description);
+</method>
+
+<method name="multiplicity()">
+the number of decay products in a channel, at most 8.
+(Is not set as such, but obtained from the products list below.)
+</method>
+
+<method name="product(i)">
+a list of the decay products, 8 products 0 <= i < 8,
+with trailing unused ones set to 0.
+</method>
+
+<p/>
+The decay table, a vector of decay channels, also defines a
+few methods:
+
+<method name="addChannel( branchingRatio, meMode, product1, ...)">
+adds a decay channel with up to 8 products.
+</method>
+
+<method name="size()">
+gives the number of decay channels for a particle.
+</method>
+
+<method name="rescaleBR(newSumBR)">
+rescale all branching ratios to the provided new sum,
+by default unity.
+</method>
+
+<method name="pick()">
+picks one decay channel according to their respective branching
+ratios.
+</method>
+
+<method name="dynamicPick()">
+intended for resonances specifically, this picks one decay channel
+according to the respective partial widths for the specific mass
+value of the resonance; assumes that the partial widths are input
+beforehand, using a special <code>dynamicBR()</code> method.
+</method>
+
+<h3>Operation</h3>
+
+The normal flow of the particle data operations is:
+
+<ol>
+
+<li>
+When a <code>Pythia</code> object <code>pythia</code> is created, the
+<code>ParticleDataTable</code> member <code>pythia.particleData</code>
+is asked to scan the <code>ParticleData.xml</code> file.
+
+<p/>
+All lines beginning with <code><particle</code> are scanned for
+information on a particle species, and all lines beginning with
+<code><channel</code> are assumed to contain a decay channel of the
+enclosing particle. In both cases XML syntax is used, with attributes
+used to identify the stored properties, and with omitted properties
+defaulting back to 0 where meaningful. The particle and channel
+information may be split over several lines, up to the > endtoken.
+The format of a <code><particle</code> tag is:
+<pre>
+ <particle id="..." name="..." antiName="..." spinType="..." chargeType="..." colType="..."
+ m0="..." mWidth="..." mMin="..." mMax="..." tau0="...">
+ </particle>
+</pre>
+where the fields are the properties already introduced above.
+Note that <code>isResonance</code>, <code>mayDecay</code>,
+<code>doExternalDecay</code>, <code>isVisible</code> and
+<code>doForceWidth</code> are not set here, but are provided with
+default values by the rules described above. Once initialized, also
+these latter properties can be changed, see below.<br/>
+
+The format of a <code><channel></code> tag is:
+<pre>
+ <channel onMode="..." bRatio="..." meMode="..." products="..." />
+</pre>
+again see properties above. The products are given as a blank-separated
+list of <code>id</code> codes.
+<note>Important</note>: the values in the <code>.xml</code> file should not
+be changed, except by the PYTHIA authors. Any changes should be done
+with the help of the methods described below.
+</li>
+
+<li> <p/>
+Between the creation of the <code>Pythia</code> object and the
+<code>init</code> call for it, you may use the methods of the
+<code>ParticleDataTable</code> class to modify some of the default values.
+Several different approaches can be chosen for this.
+
+<p/>
+a) Inside your main program you can directly set values with
+<pre>
+ pythia.readString(string);
+</pre>
+where both the variable name and the value are contained inside
+the character string, separated by blanks and/or a =, e.g.
+<pre>
+ pythia.readString("111:mayDecay = off");
+</pre>
+switches off the decays of the <ei>pi^0</ei>.<br/>
+
+The particle id (> 0) and the property to be changed must be given,
+separated by a colon.<br/>
+
+The allowed properties are: <code>name</code>, <code>antiName</code>,
+<code>spinType</code>, <code>chargeType</code>, <code>colType</code>,
+<code>m0</code>, <code>mWidth</code>, <code>mMin</code>,
+<code>mMax</code>, <code>tau0</code>, <code>isResonance</code>,
+<code>mayDecay</code>, <code>doExternalDecay</code>,
+<code>isVisible</code> and <code>doForceWidth</code>. All of these names
+are case-insensitive. Names that do not match an existing variable
+are ignored. A warning is printed, however, unless an optional
+second argument <code>false</code> is used.<br/>
+Strings beginning with a non-alphanumeric character, like # or !,
+are assumed to be comments and are not processed at all. For
+<code>bool</code> values, the following notation may be used
+interchangeably: <code>true = on = yes = ok = 1</code>, while everything
+else gives <code>false</code> (including but not limited to
+<code>false</code>, <code>off</code>, <code>no</code> and 0).
+
+<p/>
+Particle data often comes in sets of closely related information.
+Therefore some properties expect the value to consist of several
+numbers. These can then be separated by blanks (or by commas).
+A simple example is <code>names</code>, which expects both the
+name and antiname to be given. A more interesting one is the
+<code>all</code> property,
+<pre>
+ id:all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0
+</pre>
+where all the current information on the particle itself is replaced,
+but any decay channels are kept unchanged. Using <code>new</code> instead
+of <code>all</code> also removes any previous decay channels.
+If the string contains fewer fields than expected the trailing
+properties are set to vanish ("void", 0 or 0.). Note that such a
+truncated string should not be followed by a comment, since this
+comment would then be read in as if it contained the missing properties.
+The truncation can be done anywhere, specifically a string with only
+<code>id:new</code> defines a new "empty" particle.
+As before, <code>isResonance</code>, <code>mayDecay</code>,
+<code>doExternalDecay</code>, <code>isVisible</code> and
+<code>doForceWidth</code>are (re)set to their default values, and
+would have to be changed separately if required.
+
+<p/>
+A further command is <code>rescaleBR</code>, which rescales each of the
+existing branching ratios with a common factor, such that their new
+sum is the provided value. This may be a first step towards adding
+new decay channels, see further below.
+
+<p/>
+Alternatively the <code>id</code> code may be followed by another integer,
+which then gives the decay channel number. This then has to be
+followed by the property specific to this channel, either
+<code>onMode</code>, <code>bRatio</code>, <code>meMode</code> or
+<code>products</code>. In the latter case all the products of the channel
+should be given:
+<pre>
+ id:channel:products = product1 product2 ....
+</pre>
+The line will be scanned until the end of the line, or until a
+non-number word is encountered, or until the maximum allowed number
+of eight products is encountered, whichever happens first. It is also
+possible to replace all the properties of a channel in a similar way:
+<pre>
+ id:channel:all = onMode bRatio meMode product1 product2 ....
+</pre>
+To add a new channel at the end, use
+<pre>
+ id:addChannel = onMode bRatio meMode product1 product2 ....
+</pre>
+
+<p/>
+It is currently not possible to remove a channel selectively, but
+setting its branching ratio vanishing is as effective. If you want to
+remove all existing channels and force decays into one new channel
+you can use
+<pre>
+ id:oneChannel = onMode bRatio meMode product1 product2 ....
+</pre>
+ A first <code>oneChannel</code> command could be followed by
+several subsequent <code>addChannel</code> ones, to build
+up a completely new decay table for an existing particle.
+
+<p/>
+When adding new channels or changing branching ratios in general,
+note that, once a particle is to be decayed, the sum of branching
+ratios is always rescaled to unity. Beforehand, <code>rescaleBR</code>
+may be used to rescale an existing branching ratio by the given factor.
+
+<p/>
+There are a few commands that will study all the decay channels of the
+given particle, to switch them on or off as desired. The
+<pre>
+ id:onMode = onMode
+</pre>
+will set the <code>onMode</code> property of all channels to the
+desired value. The
+<pre>
+ id:offIfAny = product1 product2 ....
+ id:onIfAny = product1 product2 ....
+ id:onPosIfAny = product1 product2 ....
+ id:onNegIfAny = product1 product2 ....
+</pre>
+will set the <code>onMode</code> 0, 1, 2 or 3, respectively, for all
+channels which contain any of the enumerated products, where the matching
+to these products is done without distinction of particles and
+antiparticles. Note that "<code>Pos</code>" and "<code>Neg</code>"
+are slightly misleading since it refers to the particle and antiparticle
+of the <code>id</code> species rather than charge, but should still be
+simpler to remember and understand than alternative notations.
+Correspondingly
+<pre>
+ id:offIfAll = product1 product2 ....
+ id:onIfAll = product1 product2 ....
+ id:onPosIfAll = product1 product2 ....
+ id:onNegIfAll = product1 product2 ....
+</pre>
+will set the <code>onMode</code> 0, 1, 2 or 3, respectively, for all
+channels which contain all of the enumerated products, again without
+distinction of particles and antiparticles. If the same product appears
+twice in the list it must also appear twice in the decay channel, and
+so on. The decay channel is allowed to contain further particles,
+beyond the product list. By contrast,
+<pre>
+ id:offIfMatch = product1 product2 ....
+ id:onIfMatch = product1 product2 ....
+ id:onPosIfMatch = product1 product2 ....
+ id:onPosIfMatch = product1 product2 ....
+</pre>
+requires the decay-channel multiplicity to agree with that of the product
+list, but otherwise works as the <code>onIfAll/offIfAll</code> methods.
+
+<p/>
+Note that the action of several of the commands depends on the order
+in which they are executed, as one would logically expect. For instance,
+<code>id:oneChannel</code> removes all decay channels of <code>id</code>
+and thus all previous changes in this decay table, while subsequent
+additions or changes would still take effect. Another example would be that
+<code>23:onMode = off</code> followed by <code>23:onIfAny = 1 2 3 4 5</code>
+would let the <ei>Z^0</ei> decay to quarks, while no decays would be
+allowed if the order were to be reversed.
+
+<p/>
+b) The <code>Pythia</code> <code>readString(string)</code> method actually
+does not do changes itself, but sends on the string either to the
+<code>ParticleData</code> class or to the <code>Settings</code> one.
+If desired, it is possible to communicate directly with the corresponding
+<code>ParticleData</code> method:
+<pre>
+ pythia.particleData.readString("111:mayDecay = off");
+ pythia.particleData.readString("15:2:products = 16 -211");
+</pre>
+In this case, changes intended for <code>Settings</code> would not be
+understood.
+
+<p/>
+c) Underlying this are commands for all the individual properties in
+the <code>ParticleDataTable</code> class, one for each. Thus, an example
+now reads
+<pre>
+ pythia.particleData.mayDecay(111, false);
+</pre>
+Boolean values should here be given as <code>true</code> or
+<code>false</code>.
+
+<p/>
+d) A simpler and more useful way is to collect all your changes
+in a separate file, with one line per change, e.g.
+<pre>
+ 111:mayDecay = off
+</pre>
+The file can be read by the
+<pre>
+ pythia.readFile(fileName);
+</pre>
+method, where <code>fileName</code> is a string, e.g.
+<code>pythia.readFile("main.cmnd")</code>. Each line is process as
+described for the string in 2a). This file can freely mix commands to
+the <code>Settings</code> and <code>ParticleData</code> classes.
+</li>
+
+<li> <p/>
+A routine <code>reInit(fileName)</code> is provided, and can be used to
+zero the particle data table and reinitialize from scratch. Such a call
+might be required if several <code>Pythia</code> objects are created in the
+same run, and requested to have different values - by default the
+<code>init()</code> call is only made the first time. Several
+<code>pythia</code> with different values would have to run sequentially
+and not in parallel, though; recall that there is only one instance of
+the particle data table.
+</li>
+
+<li> <p/>
+You may at any time obtain a listing of all the particle data by calling
+<pre>
+ pythia.particleData.listAll();
+</pre>
+The listing is by increasing <code>id</code> number. It shows the basic
+quantities introduced above. Some are abbreviated in the header to fit on
+the lines: <code>spn = spinType</code>, <code>chg = chargeType</code>,
+<code>col = colType</code>, <code>res = isResonance</code>,
+<code>dec = mayDecay && canDecay</code> (the latter checks that decay
+channels have been defined), <code>ext = doExternalDecay</code>,
+<code>vis = isVisible</code> and <code>wid = doForceWidth</code>.<br/>
+
+To list only those particles that were changed (one way or another, the
+listing will not tell what property or decay channel was changed), instead use
+<pre>
+ pythia.particleData.listChanged();
+</pre>
+(This info is based on a further <code>hasChanged</code> flag of a particle
+or a channel, set <code>true</code> whenever any of the changing methods are
+used. It is possible to manipulate this value, but this is not recommended.)
+By default the internal initialization of the widths of resonances such as
+<ei>gamma^*/Z^0, W^+-, t/tbar, H^0</ei> do not count as changes; if you want
+to list also those changes instead call <code>listChanged(true)</code>.
+<br/>
+
+To list only one particle, give its <code>id</code> code as argument to
+the <code>list(...)</code> function.. To list a restricted set of particles,
+give in their <code>id</code> codes to <code>list(...)</code> as a
+<code>vector<int></code>.
+</li>
+
+<li> <p/>
+For wholesale changes of particle properties all available data can be
+written out, edited, and then read back in again. These methods are
+mainly intended for expert users. You can choose between two alternative
+syntaxes.
+
+<p/>
+a) XML syntax, using the <code><particle</code> and
+<code><channel</code> lines already described. You use the method
+<code>particleData.listXML(fileName)</code> to produce such an XML
+file and <code>particleData.readXML(fileName)</code> to read it back
+in after editing.
+
+<p/>
+b) Fixed/free format, using exactly the same information as illustrated
+for the <code><particle</code> and <code><channel</code> lines
+above, but now without any tags. This means that all information fields
+must be provided (if there is no antiparticle then write
+<code>void</code>), in the correct order (while the order is irrelevant
+with XML syntax), and all on one line. Information is written out in
+properly lined-up columns, but the reading is done using free format,
+so fields need only be separated by at least one blank. Each new particle
+is supposed to be separated by (at least) one blank line, whereas no
+blank lines are allowed between the particle line and the subsequent
+decay channel lines, if any. You use the method
+<code>particleData.listFF(fileName)</code> to produce such a fixed/free
+file and <code>particleData.readFF(fileName)</code> to read it back
+in after editing.
+
+<p/>
+As an alternative to the <code>readXML</code> and <code>readFF</code>
+methods you can also use the
+<code>particleData.reInit(fileName, xmlFormat)</code> method, where
+<code>xmlFormat = true</code> (default) corresponds to reading an XML
+file and <code>xmlFormat = false</code> to a fixed/free format one.
+
+<p/>
+To check that the new particle and decay tables makes sense, you can use
+the <code>particleData.checkTable()</code> method, either directly or by
+switching it on among the standard
+<aloc href="ErrorChecks">error checks</aloc>.
+</li>
+
+</ol>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Particle Decays">
+
+<h2>Particle Decays</h2>
+
+The <code>ParticleDecays</code> class performs the sequential decays of
+all unstable hadrons produced in the string fragmentation stage,
+i.e. up to and including <ei>b</ei> hadrons and their decay products,
+such as the <ei>tau</ei> lepton. It is not to be used for the decay of
+more massive <aloc href="ResonanceDecays">resonances</aloc>, such as top,
+<ei>Z^0</ei> or SUSY, where decays must be performed already at the
+<code>ProcessLevel</code> of the event generation.
+
+<p/>
+The decay description essentially copies the one present in
+PYTHIA since many years, but with some improvements, e.g. in the decay
+tables and the number of decay models available. Some issues may need
+further polishing.
+
+<h3>Variables determining whether a particle decays</h3>
+
+Before a particle is actually decayed, a number of checks are made.
+
+<p/>
+(i) Decay modes must have been defined for the particle kind;
+tested by the <code>canDecay()</code> method of <code>Event</code>
+(and <code>ParticleData</code>).
+
+<p/>
+(ii) The main switch for allowing this particle kind to decay must
+be on; tested by the <code>mayDecay()</code> method of <code>Event</code>
+(and <code>ParticleData</code>).
+
+<p/>
+(iii) Particles may be requested to have a nominal proper lifetime
+<ei>tau0</ei> below a threshold.
+
+<flag name="ParticleDecays:limitTau0" default="off">
+When on, only particles with <ei>tau0 < tau0Max</ei> are decayed.
+</flag>
+
+<parm name="ParticleDecays:tau0Max" default="1." min="0.">
+The above <ei>tau0Max</ei>, expressed in mm/c.
+</parm>
+
+<p/>
+(iv) Particles may be requested to have an actual proper lifetime
+<ei>tau</ei> below a threshold.
+
+<flag name="ParticleDecays:limitTau" default="off">
+When on, only particles with <ei>tau < tauMax</ei> are decayed.
+</flag>
+
+<parm name="ParticleDecays:tauMax" default="1." min="0.">
+The above <ei>tauMax</ei>, expressed in mm/c.<br/>
+In order for this and the subsequent tests to work, a <ei>tau</ei>
+is selected and stored for each particle, whether in the end it
+decays or not. (If each test would use a different temporary
+<ei>tau</ei> it would lead to inconsistencies.)
+</parm>
+
+<p/>
+(v) Particles may be requested to decay within a given distance
+of the origin.
+
+<flag name="ParticleDecays:limitRadius" default="off">
+When on, only particles with a decay within a radius <ei>r < rMax</ei>
+are decayed. There is assumed to be no magnetic field or other
+detector effects.
+</flag>
+
+<parm name="ParticleDecays:rMax" default="1." min="0.">
+The above <ei>rMax</ei>, expressed in mm/c.
+</parm>
+
+<p/>
+(vi) Particles may be requested to decay within a given cylidrical
+volume around the origin.
+
+<flag name="ParticleDecays:limitCylinder" default="off">
+When on, only particles with a decay within a volume limited by
+<ei>rho = sqrt(x^2 + y^2) < xyMax</ei> and <ei>|z| < zMax</ei>
+are decayed. There is assumed to be no magnetic field or other
+detector effects.
+</flag>
+
+<parm name="ParticleDecays:xyMax" default="1." min="0.">
+The above <ei>xyMax</ei>, expressed in mm/c.
+</parm>
+
+<parm name="ParticleDecays:zMax" default="1." min="0.">
+The above <ei>zMax</ei>, expressed in mm/c.
+</parm>
+
+<h3>Mixing</h3>
+
+<flag name="ParticleDecays:mixB" default="on">
+Allow or not <ei>B^0 - B^0bar</ei> and <ei>B_s^0 - B_s^0bar</ei> mixing.
+</flag>
+
+<parm name="ParticleDecays:xBdMix" default="0.776" min="0.74" max="0.81">
+The mixing parameter <ei>x_d = Delta(m_B^0)/Gamma_B^0</ei> in the
+<ei>B^0 - B^0bar</ei> system. (Default from RPP2006.)
+</parm>
+
+<parm name="ParticleDecays:xBsMix" default="26.05" min="22.0" max="30.0">
+The mixing parameter <ei>x_s = Delta(m_B_s^0)/Gamma_B_s^0</ei> in the
+<ei>B_s^0 - B_s^0bar</ei> system. (Delta-m from CDF hep-ex-0609040,
+Gamma from RPP2006.)
+</parm>
+
+<h3>Other variables</h3>
+
+<parm name="ParticleDecays:mSafety" default="0.0005" min="0." max="0.01">
+Minimum mass difference required between the decaying mother mass
+and the sum of the daughter masses, kept as a safety margin to avoid
+numerical problems in the decay generation.
+</parm>
+
+<parm name="ParticleDecays:sigmaSoft" default="0.5" min="0.2" max="2.">
+In semileptonic decays to more than one hadron, such as
+<ei>B -> nu l D pi</ei>, decay products after the first three are
+dampened in momentum by an explicit weight factor
+<ei>exp(-p^2/sigmaSoft^2)</ei>, where <ei>p</ei> is the
+three-momentum in the rest frame of the decaying particle.
+This takes into account that such further particles come from the
+fragmentation of the spectator parton and thus should be soft.
+</parm>
+
+<p/>
+When a decay mode is defined in terms of a partonic content, a random
+multiplicity (and a random flavour set) of hadrons is to be picked,
+especially for some charm and bottom decays. This is done according to
+a Poissonian distribution, for <ei>n_p</ei> normal particles and
+<ei>n_q</ei> quarks the average value is chosen as
+<eq>
+ n_p/ 2 + n_q/4 + multIncrease * ln ( mDiff / multRefMass)
+</eq>
+with <ei>mDiff</ei> the difference between the decaying particle mass
+and the sum of the normal-particle masses and the constituent quark masses.
+For gluonic systems <ei>multGoffset</ei> offers and optional additional
+term to the multiplicity. The lowest possible multiplicity is
+<ei>n_p + n_q/2</ei> (but at least 2) and the highest possible 10.
+If the picked hadrons have a summed mass above that of the mother a
+new try is made, including a new multiplicity. These constraints
+imply that the actual average multiplicity does not quite agree with
+the formula above.
+
+<parm name="ParticleDecays:multIncrease" default="4.5" min="3." max="6.">
+The above <ei>multIncrease</ei> parameter.
+</parm>
+
+<parm name="ParticleDecays:multRefMass" default="0.7"min="0.2" max="2.0">
+The above <ei>multRefMass</ei> parameter.
+</parm>
+
+<parm name="ParticleDecays:multGoffset" default="0.5" min="0.0" max="2.0">
+The above <ei>multGoffset</ei> parameter.
+</parm>
+
+<parm name="ParticleDecays:colRearrange" default="0.5" min="0." max="1.0">
+When a decay is given as a list of four partons to be turned into
+hadrons (primarily for modes 41 - 80) it is assumed that they are
+listed in pairs, as a first and a second colour singlet, which could
+give rise to separate sets of hadrons. Here <ei>colRearrange</ei> is
+the probability that this original assignment is not respected, and
+default corresponds to no memory of this original colour topology.
+</parm>
+
+<flag name="ParticleDecays:FSRinDecays" default="true">
+When a particle decays to <ei>q qbar</ei>, <ei>g g</ei>, <ei>g g g</ei>
+or <ei>gamma g g</ei>, with <code>meMode > 90</code>, allow or not a
+shower to develop from it, before the partonic system is hadronized.
+(The typical example is <ei>Upsilon</ei> decay.)
+</flag>
+
+In addition, some variables defined for string fragmentation and for
+flavour production are used also here.
+
+<h3>Modes for Matrix Element Processing</h3>
+
+Some decays can be treated better than what pure phase space allows,
+by reweighting with appropriate matrix elements. In others a partonic
+content has to be converted to a set of hadrons. The presence of such
+corrections is signalled by a nonvanishing <code>meMode()</code> value
+for a decay mode in the <aloc href="ParticleDataScheme">particle
+data table</aloc>. The list of allowed possibilities almost agrees with the
+PYTHIA 6 ones, but several obsolete choices have been removed,
+a few new introduced, and most have been moved for better consistency.
+Here is the list of currently allowed <code>meMode()</code> codes:
+<ul>
+<li> 0 : pure phace space of produced particles ("default");
+input of partons is allowed and then the partonic content is
+converted into the minimal number of hadrons (i.e. one per
+parton pair, but at least two particles in total)</li>
+<li> 1 : <ei>omega</ei> and <ei>phi -> pi+ pi- pi0</ei></li>
+<li> 2 : polarization in <ei>V -> PS + PS</ei> (<ei>V</ei> = vector,
+<ei>PS</ei> = pseudoscalar), when <ei>V</ei> is produced by
+<ei>PS -> PS + V</ei> or <ei>PS -> gamma + V</ei></li>
+<li> 11 : Dalitz decay into one particle, in addition to the
+lepton pair (also allowed to specify a quark-antiquark pair that
+should collapse to a single hadron)</li>
+<li> 12 : Dalitz decay into two or more particles in addition
+to the lepton pair</li>
+<li> 13 : double Dalitz decay into two lepton pairs</li>
+<li> 21 : decay to phase space, but weight up <ei>neutrino_tau</ei> spectrum
+in <ei>tau</ei> decay</li>
+<li> 22 : weak decay; if there is a quark spectator system it collapses to
+one hadron; for leptonic/semileptonic decays the <ei>V-A</ei> matrix element
+is used, for hadronic decays simple phase space</li>
+<li> 23 : as 22, but require at least three particles in decay</li>
+<li> 31 : decays of type B -> gamma X, very primitive simulation where
+X is given in terms of its flavour content, the X multiplicity is picked
+according to a geometrical distribution with average number 2, and
+the photon energy spectrum is weighted up relative to pure phase space</li>
+<li> 42 - 50 : turn partons into a random number of hadrons, picked according
+to a Poissonian with average value as described above, but at least
+<code>code</code> - 40 and at most 10, and then distribute then in pure
+phase space; make a new try with another multiplicity if the sum of daughter
+masses exceed the mother one </li>
+<li> 52 - 60 : as 42 - 50, with multiplicity between <code>code</code> - 50
+and 10, but avoid already explicitly listed non-partonic channels</li>
+<li> 62 - 70 : as 42 - 50, but fixed multiplicity <code>code</code> - 60</li>
+<li> 72 - 80 : as 42 - 50, but fixed multiplicity <code>code</code> - 70,
+and avoid already explicitly listed non-partonic channels</li>
+<li> 91 : decay to <ei>q qbar</ei> or <ei>g g</ei>, which should shower
+and hadronize</li>
+<li> 92 : decay onium to <ei>g g g</ei> or <ei>g g gamma</ei>
+(with matrix element), which should shower and hadronize</li>
+<li> 100 - : reserved for the description of partial widths of
+<aloc href="ResonanceDecays">resonances</aloc></li>
+</ul>
+
+Three special decay product identity codes are defined.
+<ul>
+<li>81: remnant flavour. Used for weak decays of c and b hadrons, where the
+c or b quark decays and the other quarks are considered as a spectator
+remnant in this decay. In practice only used for baryons with multiple
+c and b quarks, which presumably would never be used, but have simple
+(copied) just-in-case decay tables. Assumed to be last decay product.</li>
+<li>82: random flavour, picked by the standard fragmentation flavour
+machinery, used to start a sequence of hadrons, for matrix element
+codes in 41 - 80. Assumed to be first decay product, with -82 as second
+and last. Where multiplicity is free to be picked it is selected as for
+normal quarkonic systems. Currently unused.</li>
+<li>83: as for 82, with matched pair 83, -83 of decay products. The
+difference is that here the pair is supposed to come from a closed gluon
+loop (e.g. <ei>eta_c -> g g</ei>) and so have a somewhat higher average
+multiplicity than the simple string assumed for 82, see the
+<code>ParticleDecays:multGoffset</code> parameter above.</li>
+</ul>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Particle Properties">
+
+<h2>Particle Properties</h2>
+
+A <code>Particle</code> corresponds to one entry/slot in the
+event record. Its properties therefore is a mix of ones belonging
+to a particle-as-such, like its identity code or four-momentum,
+and ones related to the event-as-a-whole, like which mother it has.
+
+<p/>
+What is stored for each particle is
+<ul>
+<li>the identity code,</li>
+<li>the status code,</li>
+<li>two mother indices,</li>
+<li>two daughter indices,</li>
+<li>a colour and an anticolour index,</li>
+<li>the four-momentum and mass,</li>
+<li>the production vertex and proper lifetime,</li>
+<li>a pointer to the particle kind in the particle data tables.</li>
+</ul>
+From these, a number of further quantities may be derived.
+
+<h3>Basic methods</h3>
+
+The following member functions can be used to extract the information:
+
+<method name="id()">
+the identity of a particle, according to the PDG particle codes
+<ref>Yao06</ref>.
+</method>
+
+<method name="status()">
+status code. The status code includes information on how a particle was
+produced, i.e. where in the program execution it was inserted into the
+event record, and why. It also tells whether the particle is still present
+or not. It does not tell how a particle disappeared, whether by a decay,
+a shower branching, a hadronization process, or whatever, but this is
+implicit in the status code of its daughter(s). The basic scheme is:
+<ul>
+<li>status = +- (10 * i + j)</li>
+<li> + : still remaining particles</li>
+<li> - : decayed/branched/fragmented/... and not remaining</li>
+<li> i = 1 - 9 : stage of event generation inside PYTHIA</li>
+<li> i = 10 -19 : reserved for future expansion</li>
+<li> i >= 20 : free for add-on programs</li>
+<li> j = 1 - 9 : further specification</li>
+</ul>
+In detail, the list of used or foreseen status codes is:
+<ul>
+<li>11 - 19 : beam particles</li>
+ <ul>
+ <li>11 : the event as a whole</li>
+ <li>12 : incoming beam</li>
+ <li>13 : incoming beam-inside-beam (e.g. <ei>gamma</ei>
+ inside <ei>e</ei>)</li>
+ <li>14 : outgoing elastically scattered</li>
+ <li>15 : outgoing diffractively scattered</li>
+ </ul>
+<li>21 - 29 : particles of the hardest subprocess</li>
+ <ul>
+ <li>21 : incoming</li>
+ <li>22 : intermediate (intended to have preserved mass)</li>
+ <li>23 : outgoing</li>
+ </ul>
+<li>31 - 39 : particles of subsequent subprocesses</li>
+ <ul>
+ <li>31 : incoming</li>
+ <li>32 : intermediate (intended to have preserved mass)</li>
+ <li>33 : outgoing</li>
+ </ul>
+<li>41 - 49 : particles produced by initial-state-showers</li>
+ <ul>
+ <li>41 : incoming on spacelike main branch</li>
+ <li>42 : incoming copy of recoiler</li>
+ <li>43 : outgoing produced in timelike sidebranch of shower</li>
+ <li>44 : outgoing shifted by the branching</li>
+ </ul>
+<li>51 - 59 : particles produced by final-state-showers</li>
+ <ul>
+ <li>51 : outgoing produced by parton branching</li>
+ <li>52 : outgoing copy of recoiler, with changed momentum</li>
+ <li>53 : copy of recoiler when this is incoming parton,
+ with changed momentum</li>
+ </ul>
+<li>61 - 69 : particles produced by beam-remnant treatment</li>
+ <ul>
+ <li>61 : incoming subprocess particle with primordial <ei>kT</ei>
+ included</li>
+ <li>62 : outgoing subprocess particle with primordial <ei>kT</ei>
+ included</li>
+ <li>63 : outgoing beam remnant</li>
+ </ul>
+<li>71 - 79 : partons in preparation of hadronization process</li>
+ <ul>
+ <li>71 : copied partons to collect into contiguous colour singlet</li>
+ <li>72 : copied recoiling singlet when ministring collapses to
+ one hadron and momentum has to be reshuffled</li>
+ <li>73 : combination of very nearby partons into one</li>
+ <li>74 : combination of two junction quarks (+ nearby gluons)
+ to a diquark</li>
+ <li>75 : gluons split to decouple a junction-antijunction pair</li>
+ <li>76 : partons with momentum shuffled to decouple a
+ junction-antijunction pair </li>
+ <li>77 : temporary opposing parton when fragmenting first two
+ strings in to junction (should disappear again)</li>
+ <li>78 : temporary combined diquark end when fragmenting last
+ string in to junction (should disappear again)</li>
+ </ul>
+<li>81 - 89 : primary hadrons produced by hadronization process</li>
+ <ul>
+ <li>81 : from ministring into one hadron</li>
+ <li>82 : from ministring into two hadrons</li>
+ <li>83, 84 : from normal string (the difference between the two
+ is technical, whether fragmented off from the top of the
+ string system or from the bottom, useful for debug only)</li>
+ <li>85, 86 : primary produced hadrons in junction frogmentation of
+ the first two string legs in to the junction,
+ in order of treatment</li>
+ </ul>
+<li>91 - 99 : particles produced in decay process, or by Bose-Einstein
+ effects</li>
+ <ul>
+ <li>91 : normal decay products</li>
+ <li>92 : decay products after oscillation <ei>B0 <-> B0bar</ei> or
+ <ei>B_s0 <-> B_s0bar</ei></li>
+ <li>93, 94 : decay handled by external program, normally
+ or with oscillation</li>
+ <li>99 : particles with momenta shifted by Bose-Einstein effects
+ (not a proper decay, but bookkept as an <ei>1 -> 1</ei> such,
+ happening after decays of short-lived resonances but before
+ decays of longer-lived particles)</li>
+ </ul>
+<li>101 - 199 : reserved for future expansion</li>
+<li>201 - : free to be used by anybody</li>
+</ul>
+</method>
+
+<method name="mother1(), mother2()">
+the indices in the event record where the first and last mothers are
+stored, if any. There are five allowed combinations of <code>mother1</code>
+and <code>mother2</code>:
+<ol>
+<li><code>mother1 = mother2 = 0</code>: for lines 0 - 2, where line 0
+represents the event as a whole, and 1 and 2 the two incoming
+beam particles; </li>
+<li><code>mother1 = mother2 > 0</code>: the particle is a "carbon copy"
+of its mother, but with changed momentum as a "recoil" effect,
+e.g. in a shower;</li>
+<li><code>mother1 > 0, mother2 = 0</code>: the "normal" mother case, where
+it is meaningful to speak of one single mother to several products,
+in a shower or decay;</li>
+<li><code>mother1 < mother2</code>, both > 0, for
+<code>abs(status) = 81 - 86</code>: primary hadrons produced from the
+fragmentation of a string spanning the range from <code>mother1</code>
+to <code>mother2</code>, so that all partons in this range should be
+considered mothers;</li>
+<li><code>mother1 < mother2</code>, both > 0, except case 4: particles
+with two truly different mothers, in particular the particles emerging
+from a hard <ei>2 -> n</ei> interaction.</li>
+</ol>
+<note>Note 1:</note> in backwards evolution of initial-state showers,
+the mother may well appear below the daughter in the event record.
+<note>Note 2:</note> the <code>motherList(i)</code> method of the
+<code>Event</code> class returns a vector of all the mothers,
+providing a uniform representation for all five cases.
+</method>
+
+<method name="daughter1(), daughter2()">
+the indices in the event record where the first and last daughters
+are stored, if any. There are five allowed combinations of
+<code>daughter1</code> and <code>daughter2</code>:
+<ol>
+<li><code>daughter1 = daughter2 = 0</code>: there are no daughters
+(so far);</li>
+<li><code>daughter1 = daughter2 > 0</code>: the particle has a
+"carbon copy" as its sole daughter, but with changed momentum
+as a "recoil" effect, e.g. in a shower;</li>
+<li><code>daughter1 > 0, daughter2 = 0</code>: each of the incoming beams
+has only (at most) one daughter, namely the initiator parton of the
+hardest interaction; further, in a <ei>2 -> 1</ei> hard interaction,
+like <ei>q qbar -> Z^0</ei>, or in a clustering of two nearby partons,
+the initial partons only have this one daughter;</li>
+<li><code>daughter1 < daughter2</code>, both > 0: the particle has
+a range of decay products from <code>daughter1</code> to
+<code>daughter2</code>;</li> <li><code>daughter2 < daughter1</code>,
+both > 0: the particle has two separately stored decay products (e.g.
+in backwards evolution of initial-state showers).</li>
+</ol>
+<note>Note 1:</note> in backwards evolution of initial-state showers, the
+daughters may well appear below the mother in the event record.
+<note>Note 2:</note> the mother-daughter relation normally is reciprocal,
+but not always. An example is hadron beams (indices 1 and 2), where each
+beam remnant and the initiator of each multiple interaction has the
+respective beam as mother, but the beam itself only has the initiator
+of the hardest interaction as daughter.
+<note>Note 3:</note> the <code>daughterList(i)</code> method of the
+<code>Event</code> class returns a vector of all the daughters,
+providing a uniform representation for all five cases. With this method,
+also all the daughters of the beams are caught, with the initiators of
+the basic process given first, while the rest are in no guaranteed order
+(since they are found by a scanning of the event record for particles
+with the beam as mother, with no further information).
+</method>
+
+<method name="col(), acol()">
+the colour and anticolour tags, Les Houches Accord <ref>Boo01</ref>
+style (starting from tag 101 by default, see below).
+</method>
+
+<method name="px(), py(), pz(), e()">
+the particle four-momentum components, alternatively extracted as a
+<code>Vec4 p()</code>.
+</method>
+
+<method name="m()">
+the particle mass.
+</method>
+
+<method name="scale()">
+the scale at which a parton was produced, which can be used to restrict
+its radiation to lower scales in subsequent steps of the shower evolution.
+Note that scale is linear in momenta, not quadratic (i.e. <ei>Q</ei>,
+not <ei>Q^2</ei>).
+</method>
+
+<method name="xProd(), yProd(), zProd(), tProd()">
+the production vertex coordinates, in mm or mm/c, alternatively extracted
+as a <code>Vec4 vProd()</code>. The initial process is assumed to occur
+at the origin.
+<note>Note:</note>the <code>Vec4</code> has components px(), py(),
+pz() and e(), which of course should be reinterpreted as above.
+</method>
+
+<method name="tau()">
+the proper lifetime, in mm/c; is assigned for all hadrons with
+positive nominal <ei>tau</ei>, <ei>tau_0 > 0</ei>, even if not
+decayed by PYTHIA (because of one veto or another).
+</method>
+
+<p/>
+The same method names are overloaded to take an argument, in which case
+the corresponding property is set accordingly.
+
+<h3>Further methods</h3>
+
+ There are a few alternative methods for input:
+
+<method name="statusPos(), statusNeg()">
+sets the status sign positive or negative, without changing the absolute value.
+</method>
+
+<method name="statusCode(code)">
+changes the absolute value but retains the original sign.
+</method>
+
+<method name="mothers(m1, m2)">
+sets both mothers in one go.
+</method>
+
+<method name="daughters(d1, d2)">
+sets both daughters in one go.
+</method>
+
+<method name="cols(c, ac)">
+sets both colour and anticolour in one go.
+</method>
+
+<method name="p( px, py, pz, e)">
+sets the four-momentum in one go;
+alternative input as a <code>Vec4</code> object.
+</method>
+
+<method name="vProd( xProd, yProd, zProd, tProd)">
+sets the production vertex in one go; alternative input as a
+<code>Vec4</code>
+object.
+</method>
+
+<p/>
+In addition, a number of derived quantities can easily be obtained
+(but cannot be set), such as:
+
+<method name="idAbs()">
+the absolute value of the particle identity code.
+</method>
+
+<method name="statusAbs()">
+the absolute value of the status code.
+</method>
+
+<method name="isFinal()">
+true for a remaining particle, i.e. one with positive status code,
+else false. Thus, after an event has been fully generated, it
+separates the final-state particles from intermediate-stage ones.
+(If used earlier in the generation process, a particle then
+considered final may well decay later.)
+</method>
+
+<method name="m2()">
+squared mass.
+</method>
+
+<method name="mCalc(), m2Calc()">
+(squared) mass calculated from the four-momentum; should agree
+with <code>m(), m2()</code> up to roundoff.
+</method>
+
+<method name="eCalc()">
+energy calculated from the mass and three-momentum;
+should agree with <code>e()</code> up to roundoff.
+</method>
+
+<method name="pT(), pT2()">
+(squared) transverse momentum.
+</method>
+
+<method name="mT(), mT2()">
+(squared) transverse mass.
+</method>
+
+<method name="pAbs(), pAbs2()">
+(squared) three-momentum size.
+</method>
+
+<method name="theta(), phi()">
+polar and azimuthal angle.
+</method>
+
+<method name="thetaXZ()">
+angle in the <ei>(p_x, p_z)</ei> plane, between <ei>-pi</ei> and
+<ei>+pi</ei>, with 0 along the <ei>+z</ei> axis
+</method>
+
+<method name="pPlus(), pMinus()">
+<ei>E +- p_z</ei>.
+</method>
+
+<method name="y(), eta()">
+rapidity and pseudorapidity.
+</method>
+
+<method name="xDec(), yDec(), zDec(), tDec()">
+the decay vertex coordinates, in mm or mm/c, alternatively extracted as
+a <code>Vec4 vDec()</code>; this decay vertex is calculated from the
+production vertex, the proper lifetime and the four-momentum assuming
+no magnetic field or other detector interference; it can be used to
+decide whether a decay should be performed or not, and thus is defined
+also for particles which PYTHIA did not let decay.
+</method>
+
+<p/>
+Each Particle contains a pointer to the respective
+<code>ParticleDataEntry</code> object in the
+<aloc href="ParticleDataScheme">particle data tables</aloc>.
+This gives access to properties of the particle species as such. It is
+there mainly for convenience, and should be thrown if an event is
+written to disk, to avoid any problems of object persistency. Should
+an event later be read back in, the pointer will be recreated from the
+<code>id</code> code if the normal input methods are used. (Use the
+<aloc href="EventRecord"><code>Event::restorePtrs()</code></aloc> method
+if your persistency scheme bypasses the normal methods.) This pointer is
+used by the following member functions:
+
+<method name="name()">
+the name of the particle, as a string.
+</method>
+
+<method name="nameWithStatus()">
+as above, but for negative-status particles the name is given in
+brackets to emphasize that they are intermediaries.
+</method>
+
+<method name="spinType()">
+<ei>2 *spin + 1</ei> when defined, else 0.
+</method>
+
+<method name="charge(), chargeType()">
+charge, and three times it to make an integer.
+</method>
+
+<method name="isCharged(), isNeutral()">
+charge different from or equal to 0.
+</method>
+
+<method name="colType()">
+0 for colour singlets, 1 for triplets,
+-1 for antitriplets and 2 for octets.
+</method>
+
+<method name="m0()">
+the nominal mass of the particle, according to the data tables.
+</method>
+
+<method name="mWidth(), mMin(), mMax()">
+the width of the particle, and the minimum and maximum allowed mass value
+for particles with a width, according to the data tables.
+</method>
+
+<method name="mass()">
+the mass of the particle, picked according to a Breit-Wigner
+distribution for particles with width, and thus different each
+time called.
+</method>
+
+<method name="constituentMass()">
+will give the constituent masses for quarks and diquarks,
+else the same masses as with <code>m0()</code>.
+</method>
+
+<method name="isResonance()">
+particles where the decay is to be treated as part of the hard process,
+typically with nominal mass above 20 GeV (<ei>W^+-, Z^0, t, ...</ei>).
+</method>
+
+<method name="mayDecay()">
+flag whether particle has been declared unstable or not, offering
+the main user switch to select which particle species to decay.
+</method>
+
+<method name="canDecay()">
+flag whether decay modes have been declared for a particle,
+so that it could be decayed, should that be requested.
+</method>
+
+<method name="doExternalDecay()">
+particles that are decayed by an external program.
+</method>
+
+<method name="isVisible()">
+particles with strong or electric charge, or composed of ones having it,
+which thereby should be considered visible in a normal detector.
+</method>
+
+<method name="doForceWidth()">
+resonances that have code to recalculate the width in <code>mWidth</ei>
+from the nominal mass value <code>m0</code>, but where nevertheless the
+stored <code>mWidth</ei> value is used.
+</method>
+
+<method name="isLepton()">
+true for a lepton or an antilepton (including neutrinos).
+</method>
+
+<method name="isQuark()">
+true for a quark or an antiquark.
+</method>
+
+<method name="isGluon()">
+true for a gluon.
+</method>
+
+<method name="isHadron()">
+true for a hadron (made up out of normal quarks and gluons,
+i.e. not for R-hadrons and other exotic states).
+</method>
+
+<method name="particleData()">
+a reference to the ParticleDataEntry.
+</method>
+
+<p/>
+There are some further methods, inherited from <code>Vec4</code>,
+to rotate and boost the four-momentum.
+
+<p/>
+Not part of the event class proper, but obviously tightly linked,
+are the metods <code>m(Particle, Particle)</code> and
+<code>m2(Particle, Particle)</code> to calculate the (squared)
+invariant mass of two particles.
+
+<p/>
+The
+<aloc href="EventRecord"><code>Event</code></aloc>
+class also contains a few methods defined for individual particles,
+but these may require some search in the event record and therefore
+cannot be defined as a <code>Particle</code> method.
+
+<p/>
+Currently there is no information on polarization states.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Parton Distributions">
+
+<h2>Parton Distributions</h2>
+
+The parton distributions file contains the <code>PDF</code> class.
+<code>PDF</code> is the base class, from which specific <code>PDF</code>
+classes are derived.
+
+<p/>
+The choice of which PDF to use is made by settings in the
+<code>Pythia</code> class, see <aloc href="PDFSelection">here</aloc>.
+These settings also allow to access all the proton PDF's available in the
+LHAPDF library <ref>Wha05</ref>. Thus there is no need for a normal user
+to study the <code>PDF</code> class. The structure must only be understood
+when interfacing new PDF's, e.g. ones not yet found in LHAPDF.
+
+<h3>The PDF base class</h3>
+
+<code>PDF</code> defines the interface that all PDF classes should respect.
+The constructor requires the incoming beam species to be given:
+even if used for a proton PDF, one needs to know whether the beam
+is actually an antiproton. This is one of the reasons why <code>Pythia</code>
+always defines two PDF objects in an event, one for each beam.
+
+<p/>
+Once a <code>PDF</code> object has been constructed, call it <code>pdf</code>,
+the main method is <code>pdf.xf( id, x, Q2)</code>, which returns
+<ei>x*f_id(x, Q2)</ei>, properly taking into account whether the beam
+is an antiparticle or not.
+
+<p/>
+Whenever the <code>xf</code> member is called with a new flavour, <ei>x</ei>
+or <ei>Q^2</ei>, the <code>xfUpdate</code> member is called to do the actual
+updating. This routine may either update that particular flavour or all
+flavours at this <ei>(x, Q^2)</ei> point. (In the latter case the saved
+<code>id</code> value <code>idSav</code> should be set to 9.) The choice is
+to be made by the producer of a given set, based on what he/she deems most
+effective, given that sometimes only one flavour need be evaluated, and
+about equally often all flavours are needed at the same <ei>x</ei> and
+<ei>Q^2</ei>. Anyway, the latest value is always kept in memory. This is
+the other reason why <code>Pythia</code> has one separate <code>PDF</code>
+object for each beam, so that values at different <ei>x</ei> can be kept
+in memory.
+
+<p/>
+Two further public methods are <code>xfVal( id, x, Q2)</code> and
+<code>xfSea( id, x, Q2)</code>. These are simple variants whereby
+the quark distributions can be subdivided into a valence and a sea part.
+If these are not directly accessible in the parametrization, onc can
+make the simplified choices <ei>u_sea = ubar_sea, u_val = u_tot - u_sea</ei>,
+and correspondingly for <ei>d</ei>. (Positivity will always be guaranteed
+at output.) The <code>xfUpdate</code> method should also take care of
+updating this information.
+
+<p/>
+A method <code>setExtrapolate(bool)</code> allows you to switch between
+freezing parametrizations at the <ei>x</ei> and <ei>Q^2</ei> boundaries
+(<code>false</code>) or extrapolating them outside the boundaries
+(<code>true</code>). This method is only implemented for the LHAPDF class
+below. If you implement a new PDF you are free to use this method, but it
+would be smarter to hardcode the desired limiting behaviour.
+
+<h3>Derived classes</h3>
+
+There is only one pure virtual method, <code>xfUpdate</code>, that therefore
+must be implemented in any derived class. Currently the list of such
+classes is tiny:
+
+<p/>
+For protons:
+<ul>
+<li><code>GRV94L</code> gives the GRV 94 L parametrization
+<ref>Glu95</ref>.</li>
+<li><code>CTEQ5L</code> gives the CTEQ 5 L parametrization
+<ref>Lai00</ref>.</li>
+<li><code>LHAPDFinterface</code> provides an interface to the
+LHAPDF library<ref>Wha05</ref>.</li>
+</ul>
+The default is CTEQ 5L, which is the most recent of the two hardcoded sets.
+
+<p/>
+For charged leptons (e, mu, tau):
+<ul>
+<li>Lepton gives a QED parametrization <ref>Kle89</ref>.
+In QED there are not so many ambiguities, so here one set should be
+enough. On the other hand, there is the problem that the
+lepton-inside-lepton pdf is integrably divergent for <ei>x -> 1</ei>,
+which gives numerical problems. Like in PYTHIA 6, the pdf is therefore
+made to vanish for <ei>x > 1 - 10^{-10}</ei>, and scaled up in the range
+<ei>1 - 10^{-7} < x < 1 - 10^{-10}</ei> in such a way that the
+total area under the pdf is preserved.</li>
+</ul>
+
+There is another method, <code>isSetup()</code>, that returns the
+base-class boolean variable <code>isSet</code>. This variable is
+initially <code>true</code>, but could be set <code>false</code> if the
+setup procedure of a PDF failed, e.g. if the user has chosen an unknown
+PDF set.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Phase Space Cuts">
+
+<h2>Phase Space Cuts</h2>
+
+<code>PhaseSpace</code> is base class for all hard-process phase-space
+generators, either generic <ei>2 -> 1</ei> or <ei>2 -> 2</ei> ones,
+or specialized ones like for elastic and diffractive scattering.
+
+<p/>
+In it, it is possible to constrain the kinematics of most processes.
+(Exceptions are "soft physics", i.e. minimum bias, elastic and
+diffractive processes. The Coulomb singularity for elastic scatterings,
+if simulated, is <aloc href="TotalCrossSections">handled separately</aloc>.)
+These constraints apply in the rest frame of the hard subprocess, and
+topologies normally would be changed e.g. by subsequent showering
+activity. The cross section of a process is adjusted to only
+correspond to the allowed phase space.
+
+<p/>
+The more particles in the final state, the more cuts could be applied.
+Here we have tried to remain with the useful minimum, however. More
+generic possibilities could be handled by the
+<aloc href="UserHooks">user hooks</aloc> facility.
+
+<h3>Cuts in all processes</h3>
+
+<parm name="PhaseSpace:mHatMin" default="4." min="0.">
+The minimum invariant mass.
+</parm>
+
+<parm name="PhaseSpace:mHatMax" default="-1.">
+The maximum invariant mass.
+A value below <code>mHatMin</code> means there is no upper limit.
+</parm>
+
+<h3>Cuts in <ei>2 -> 1</ei> processes</h3>
+
+When a resonance <code>id</code> is produced, the
+<aloc href="ParticleDataScheme"><code>mMin(id)</code>and
+<code>mMax(id)</code></aloc> methods restrict the allowed mass range
+of this resonance. Therefore the allowed range is chosen to be the
+overlap of this range and the <code>mHatMin</code> to
+<code>mHatMax</code> range above. Most resonances by default have no
+upper mass limit, so effects mainly concern the lower limit.
+Should there be no overlap between the two ranges then the process
+will be switched off.
+
+<h3>Cuts in <ei>2 -> 2</ei> processes</h3>
+
+<parm name="PhaseSpace:pTHatMin" default="0." min="0.">
+The minimum invariant <ei>pT</ei>.
+</parm>
+
+<parm name="PhaseSpace:pTHatMax" default="-1.">
+The maximum invariant <ei>pT</ei>.
+A value below <code>pTHatMin</code> means there is no upper limit.
+</parm>
+
+<parm name="PhaseSpace:pTHatMinDiverge" default="1." min="0.5">
+Extra <ei>pT</ei> cut to avoid the divergences of some processes
+in the limit <ei>pT -> 0</ei>. Specifically, if either or both
+produced particles have a mass below <code>pTHatMinDiverge</code>
+then <ei>pT</ei> is limited from below by the larger of
+<code>pTHatMin</code> and <code>pTHatMinDiverge</code>.
+</parm>
+
+<flag name="PhaseSpace:useBreitWigners" default="on">
+Allows masses to be selected according to Breit-Wigner shapes in
+<ei>2 -> 2</ei> processes, whenever particles have been declared
+with a nonvanishing width above the threshold below. In those cases
+also the limits below will be used for the mass selection. For
+<ei>2 -> 1</ei> processes the Breit-Wigner shape is part of the
+cross section itself, and therefore always included.
+</flag>
+
+<parm name="PhaseSpace:minWidthBreitWigners" default="0.01" min="1e-6">
+The minimum width a resonance must have for the mass to be dynamically
+selected according to a Breit-Wigner shape, within the limits set below.
+Only applies when <code>useBreitWigners</code> is on; else the nominal
+mass value is always used.
+</parm>
+
+<p/>
+For a particle with a Breit-Wigner shape selected, according to the
+rules above and to the rules of the particle species itself, the
+<aloc href="ParticleDataScheme"><code>mMin(id)</code>
+and <code>mMax(id)</code></aloc> methods restrict the allowed mass range
+of the particle, just like for the <ei>2 -> 1 </ei> processes.
+
+<h3>Cuts in <ei>2 -> 3</ei> processes</h3>
+
+Currently no further cuts have been introduced for <ei>2 -> 3</ei>
+processes than those already available for <ei>2 -> 2</ei> ones.
+A <ei>2 -> 3</ei> process in principle would allow to define a
+separate <ei>pT</ei> range for each of the three particles (with some
+correlations), but for now all three are restricted exactly the
+same way by <code>pTHatMin</code> and <code>pTHatMax</code>.
+As above, Breit-Wigner mass ranges can be restricted.
+
+<h3>Documentation</h3>
+
+<flag name="PhaseSpace:showSearch" default="off">
+Possibility to print information on the search for phase-space
+coefficients that (in a multichannel approach) provides an analytical
+upper envelope of the differential cross section, and the
+corresponding upper estimate of the cross section. Of interest
+for crosschecks by expert users only.
+</flag>
+
+<flag name="PhaseSpace:showViolation" default="off">
+Possibility to print information whenever the assumed maximum
+differential cross section of a process is violated, i.e. when
+the initial maximization procedure did not find the true maximum.
+Also, should negative cross sections occur, print whenever a more
+negative value is encountered.
+</flag>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Process Selection">
+
+<h2>Process Selection</h2>
+
+There is no way PYTHIA could contain all processes of interest,
+neither in terms of potential physics topics nor in terms of
+high-multiplicity final states. What exists is a reasonably
+complete setup of all <ei>2 -> 1</ei> and <ei>2 -> 2</ei>
+processes within the Standard Model, plus some examples of
+processes beyond that, again for low multiplicities. Combined with
+the PYTHIA parton showers, this should be enough to get a flying
+start in the study of many physics scenarios.
+Other processes could be fed in via the
+<aloc href="LesHouchesAccord">Les Houches Accord</aloc>
+or be implemented as a
+<aloc href="SemiInternalProcesses">Semi-Internal Process</aloc>.
+In the latter case the existing processes would act as obvious
+templates.
+
+<p/>
+By default all processes are switched off. You should switch on
+those you want to simulate. This may be done at two (occasionally
+three) levels, either for each individual process or for a group of
+processes. That is, a process is going to be generated either if its
+own flag or its group flag is on. There is no built-in construction
+to switch on a group and then switch off a few of its members.
+
+<p/>
+Each process is assigned an integer code. This code is not used in
+the internal administration of events (so having the same code for
+two completely different processes would not be a problem), but only
+intended to allow a simpler user separation of different processes.
+Also the process name is available, as a string.
+
+<p/>
+To ease navigation, the list of processes has been split into several
+separate pages, by main topic. The classification is hopefully
+intuitive, but by no means unambiguous. For instance, essentially
+all processes involve QCD, so the "QCD processes" are the ones that
+only involve QCD. (And also that is not completely true, once one
+includes all that may happen in multiple interactions.) On these
+separate pages also appear the settings that are completely local
+to that particular process class, but not the ones that have a
+broader usage.
+
+<h3><aloc href="QCDProcesses">QCD Processes</aloc></h3>
+
+QCD processes fall in two main categories: soft and hard. The soft ones
+contain elastic, diffractive and "minimum-bias" events, together
+covering the total cross section. Hard processea are the normal
+<ei>2 -> 2</ei> ones, including charm and bottom production.
+<br/>Reserved code range: 101 - 199.
+
+<h3><aloc href="ElectroweakProcesses">Electroweak Processes</aloc></h3>
+
+Prompt-photon, <ei>gamma^*/Z^0</ei> and <ei>W^+-</ei> production,
+plus a few processes with <ei>t</ei>-channel boson exchange.
+<br/>Reserved code range: 201 - 299.
+
+<h3><aloc href="OniaProcesses">Onia Processes</aloc></h3>
+
+Colour singlet and octet production of charmonium and bottomonium.
+<br/>Reserved code range: 401 - 499 for charmonium and
+501 - 599 for bottomonium.
+
+<h3><aloc href="TopProcesses">Top Processes</aloc></h3>
+
+Top production, singly or doubly.
+<br/>Reserved code range: 601 - 699.
+
+<h3><aloc href="FourthGenerationProcesses">Fourth-Generation
+Processes</aloc></h3>
+
+Production of hypothetical fourth-generation fermions.
+<br/>Reserved code range: 801 - 899.
+
+<h3><aloc href="HiggsProcesses">Higgs Processes</aloc></h3>
+
+Higgs production, within or beyond the Standard Model.
+See section on Left-Right-Symmetry processes for doubly charged Higgses.
+<br/>Reserved code range: 901 - 999 for a Standard Model Higgs
+and 1001 - 1199 for MSSM Higgses.
+
+<h3><aloc href="SUSYProcesses">SUSY Processes</aloc></h3>
+
+Production of supersymmetric particles, currently barely begun.
+<br/>Reserved code range: 1001 - 2999. (Whereof 1001 - 1199
+for Higgses; see above.)
+
+<h3><aloc href="NewGaugeBosonProcesses">New-Gauge-Boson
+Processes</aloc></h3>
+
+Production of new gauge bosons such as <ei>Z'</ei> and <ei>W'</ei>.
+<br/>Reserved code range: 3001 - 3099.
+
+<h3><aloc href="LeftRightSymmetryProcesses">Left-Right-Symmetry
+Processes</aloc></h3>
+
+Production of righthanded <ei>Z_R</ei> and <ei>W_R</ei> bosons and of
+doubly charged Higgses.
+<br/>Reserved code range: 3101 - 3199.
+
+<h3><aloc href="LeptoquarkProcesses">Leptoquark Processes</aloc></h3>
+
+Production of a simple scalar leptoquark state.
+<br/>Reserved code range: 3201 - 3299.
+
+<h3><aloc href="CompositenessProcesses">Compositeness Processes</aloc></h3>
+
+Production of excited fermion states and contact-interaction modification
+to interactions between fermions (excluding technicolor; see below).
+<br/>Reserved code range: 4001 - 4099.
+
+<h3>Technicolor Processes</h3>
+
+Production of technicolor particles and modifications of QCD processes
+by technicolor interactions. Does not exist yet.
+<br/>Reserved code range: 4101 - 4199.
+
+<h3><aloc href="ExtraDimensionalProcesses">Extra-Dimensional
+Processes</aloc></h3>
+
+A vast area, here represented by the production of a Randall-Sundrum
+excited graviton state.
+<br/>Reserved code range: 5001 - 5099.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Program Files">
+
+<h2>Program Files</h2>
+
+The code is subdivided into a set of files, mainly by physics
+task. Each file typically contains one main class, but often
+with a few related helper classes that are not used elsewhere in
+the program. Normally the files come in pairs.
+<ul>
+<li>A header file, <code>.h</code> in the <code>include</code>
+subdirectory, where the public interface of the class is declared,
+and inline methods are defined.</li>
+<li>A source code file, <code>.cc</code> in the <code>src</code>
+subdirectory, where most of the methods are implemented.</li>
+</ul>
+During compilation, related dependency files, <code>.d</code>, and
+compiled code, <code>.o</code> are created in the <code>tmp</code>
+subdirectory.
+
+<p/>
+In part the <code>.xml</code> documentation files in the
+<code>xmldoc</code> subdirectory have matching names, but the match
+is broken by the desire to group topics more by user interaction than
+internal operation. On these pages the function of the different code
+files is summarized. Currently, each <code>.xml</code> file is also
+translated into an <code>.html</code> one in the
+<code>htmldoc</code> subdirectory, to allow easy viewing of the
+contents in a web browser, and an <code>.php</code> one in
+<code>phpdoc</code>, for more sophisticated interactivity
+if that subdirectory is installed on a web server.
+
+<p/>
+Here is the current list of files, ordered alphabetically, with a brief
+description of contents.
+
+<file name="Analysis">
+contains routines to analyze events. Currently it can do sphericity,
+thrust, Lund/Jade/Durham jet clustering, and cone-jet finding.
+</file>
+
+<file name="Basics">
+contains some basic facilities of general use: a random number
+generator <code>Rndm</code>, a four-vector class <code>Vec4</code>, and a
+histogram class <code>Hist</code>.
+</file>
+
+<file name="BeamParticle">
+contains information on all partons extracted from one of the two
+beams. Defines modified parton distributions accordingly during the
+showering and multiple interactions processing, thereby extending on
+the one-particle-inclusive distributions defined by the previous class.
+Finds the internal structure for a beam remnant.
+</file>
+
+<file name="BeamRemnants">
+adds primordial <ei>kT</ei> to the set of hard subsystems,
+and combines these subsystems with the two beam remnants to provide
+the overall energy-momentum picture. Also ties together all the
+colour lines into consistent singlets.
+</file>
+
+<file name="BoseEinstein">
+provides a simple method to impose Bose-Einstein correlations on
+pairs of identical mesons.
+</file>
+
+<file name="Event">
+contains the event record, which basically is a vector of particles.
+This file also contains the <code>Particle</code> class, used by
+<code>Event</code>. <code>Pythia</code> uses two <code>Event</code>
+objects, one for the process-level record (<code>process</code>) and
+one for the complete event (<code>event</code>).
+</file>
+
+<file name="FragmentationFlavZpT">
+contains the classes for describing the fragmentation steps in
+flavour and in longitudinal and transverse momentum.
+</file>
+
+<file name="FragmentationSystems">
+defines some containers of parton systems, for use in
+the fragmentation routines.
+</file>
+
+<file name="HadronLevel">
+turns the parton-level event above into a set of outgoing particles,
+by applying string fragmentation (with special treatment for low-mass
+systems) and secondary decays, and optionally Bose-Einstein corrections.
+</file>
+
+<file name="HepMCInterface">
+contains an interface to convert the PYTHIA 8 event record into the
+HepMC format. The <code>HepMCInterface.cc</code> file is located in
+the subdirectory <code>hepmcinterface</code> and is used to build a
+separate <code>libhepmcinterface</code> library.
+</file>
+
+<file name="Info">
+is a simple container that gives access to some information on the
+nature of the current process, such as Mandelstam variables.
+Also contains a small database for errors and warnings encountered
+during program execution.
+</file>
+
+<file name="LesHouches">
+gives the possibility to feed in parton configurations for the
+subsequent event generation. One base class is defined, with containers
+for initialization and event information, that can be read from
+<code>Pythia</code>. Derived classes allow for a few different cases.
+</file>
+
+<file name="LHAFortran">
+is a header file only, for a class derived from the above LesHouches
+one, to be used for runtime interfacing to Fortran programs, such as
+PYTHIA 6.
+</file>
+
+<file name="LHAPDFInterface">
+is a header file only, with interfaces to the key LHAPDF routines,
+as needed for a runtime interface. There is a file
+<code>lhapdfdummy/LHAPDFdummy.cc</code> with matching dummy
+implementations, however. This file is used to build a separate
+<code>liblhapdfdummy</code> library, to be linked when the LHAPDF
+library is not used, so as to avoid problems with undefined references.
+</file>
+
+<file name="MiniStringFragmentation">
+performs string fragmentation in cases where the colour singlet
+subsystem mass is so small that one or at most two primary hadrons
+should be produced from it.
+</file>
+
+<file name="MultipleInteractions">
+performs multiple parton-parton interactions.
+</file>
+
+<file name="ParticleData">
+contains a database of all necessary particle data (masses, names, ..)
+and decay channels.
+</file>
+
+<file name="ParticleDecays">
+performs the decays of all normal unstable hadrons and leptons, i.e.
+in mass up to and including <ei>b bbar</ei> systems. It is not
+intended for decays of electroweak resonances, like <ei>Z^0</ei>.
+</file>
+
+<file name="PartonDistributions">
+contains parton distribution functions for the proton and electron.
+Currently very simple, with only two <ei>p</ei> parametrizations
+and one <ei>e</ei> ditto available, but it is possible to link in
+external sets.
+</file>
+
+<file name="PartonLevel">
+turns the (hard) process above into a complete set of partons, by
+adding initial- and final-state radiation, multiple parton--parton
+interactions, and beam remnants.
+</file>
+
+<file name="PhaseSpace">
+selects a point in phase space for the hard-process generation,
+optimized separately for each process to give improved Monte Carlo
+efficiency.
+</file>
+
+<file name="ProcessContainer">
+packages the information on a given subprocess, combining the
+phase-space selection and cross-section evaluation machineries
+with some statistics information. Also sets up the list of processes
+to be studied in a run.
+</file>
+
+<file name="ProcessLevel">
+handles the generation of the (hard) process that sets the character
+of the event. This involves either using internally implemented
+processes or linking to Les Houches information. The latter can
+be by runtime interfaces or by reading in a file. This step also
+includes resonance decays.
+</file>
+
+<file name="Pythia">
+is the main class, that administrates the whole event generation
+process by making use of all the others classes. Objects of most
+other classes reside (directly or indirectly) inside <code>Pythia</code>,
+so only a <code>Pythia</code> object needs to be explicitly instantiated
+and addressed by the user.
+</file>
+
+<file name="Pythia6Interface">
+is a header file only, with interfaces to the key PYTHIA 6 routines,
+as needed for a runtime Les Houches interface to this program.
+</file>
+
+<file name="PythiaComplex">
+is only a <code>.h</code> file, containing a <code>typedef</code> for
+double precision complex numbers.
+</file>
+
+<file name="PythiaStdlib">
+is only a <code>.h</code> file, containing most of the <code>Stdlib</code>
+headers used in PYTHIA 8, with <code>using</code> directives. It defines
+<code>M_PI</code> if this is not already done. Also a few simple inline
+methods: <code>pow2(x)</code>, <code>pow3(x)</code>, <code>pow4(x)</code>
+and <code>pow5(x)</code> for small integer powers, and
+<code>sqrtpos(x)</code> where a <code>max(0., x)</code> ensures that one
+does not take the square root of a negative number.
+</file>
+
+<file name="ResonanceDecays">
+decays resonances as part of the hard-process stage, in many cases
+(but not all) including angular correlations between the decay products.
+</file>
+
+<file name="ResonanceWidths">
+encodes some properties of resonances, in particular the dynamic
+calculation of widths.
+</file>
+
+<file name="Settings">
+contains a database of all flags, modes, parameters and words that
+determine the performance of the generator. Initial values are obtained
+from the contents of the <code>.xml</code> files, but these values can
+then be changed by the user.
+</file>
+
+<file name="SigmaCompositeness">
+contains the cross sections and matrix elements for production of
+some particles in compositeness scenarios, specifically excited
+fermions.
+</file>
+
+<file name="SigmaEW">
+contains the cross sections and matrix elements for electroweak
+processes involving photons, <ei>Z^0</ei>'s and <ei>W^+-</ei>'s.
+</file>
+
+<file name="SigmaExtraDim">
+contains the cross sections and matrix elements for processes in
+scenarios involving extra dimensions.
+</file>
+
+<file name="SigmaHiggs">
+contains the cross sections and matrix elements for Higgs production.
+</file>
+
+<file name="SigmaLeftRightSym">
+contains the cross sections and matrix elements for particle production
+in left-right-symmetry scenarios, specifically righthanded <ei>Z</ei>
+and <ei>W</ei> bosons and doubly-charged Higgs bosons.
+</file>
+
+<file name="SigmaLeptoquark">
+contains the cross sections and matrix elements for leptoquark production.
+</file>
+
+<file name="SigmaNewGaugeBosons">
+contains the cross sections and matrix elements for a <ei>Z'^0</ei>,
+a <ei>W^+-</ei> and a horizontal gauge boson <ei>R^0</ei>.
+</file>
+
+<file name="SigmaOnia">
+contains the cross sections and matrix elements for charmonium and
+bottomonium production.
+</file>
+
+<file name="SigmaProcess">
+contains the base class and derived classes for the evaluation of
+different matrix elements. Also keeps track of allowed incoming
+parton configurations and their cross sections, including parton
+densities. In order to keep this file from becoming too big, actual
+cross sections are found in several separate files of derived classes:
+<code>SigmaQCD</code>, <code>SigmaEW</code>, <code>SigmaOnia</code>,
+<code>SigmaHiggs</code>, <code>SigmaSUSY</code>,
+<code>SigmaNewGaugeBosons</code>, <code>SigmaLeftRightSym</code>,
+<code>SigmaLeptoquark</code>, <code>SigmaCompositeness</code> and
+<code>SigmaExtraDim</code>.
+</file>
+
+<file name="SigmaQCD">
+contains the cross sections and matrix elements for soft and hard
+QCD processes.
+</file>
+
+<file name="SigmaSUSY">
+contains the cross sections and matrix elements for Supersymmetric
+processes.
+</file>
+
+<file name="SigmaTotal">
+contains parametrizations of total, elastic and diffractive hadronic
+cross sections.
+</file>
+
+<file name="SpaceShower">
+performs spacelike initial-state transverse-momentum-ordered
+shower evolution.
+</file>
+
+<file name="StandardModel">
+contains the running <ei>alpha_strong</ei>, with <ei>Lambda</ei>
+matching at flavour thresholds, the running <ei>alpha_em</ei>,
+CKM mixing matrices, and a few other parameters such as
+<ei>sin^2(theta_W)</ei>.
+</file>
+
+<file name="StringFragmentation">
+performs string fragmentation of a given set of partons.
+</file>
+
+<file name="SusyLesHouches">
+contains information on SUSY parameters and particle data as specified
+by the SUSY Les Houches Accord.
+</file>
+
+<file name="TimeShower">
+performs timelike final-state transverse-momentum-ordered
+shower evolution.
+</file>
+
+<file name="UserHooks">
+Provides a way for a user to study the event at a few intermediate
+stages of evolution, to reject the event as a whole or to modify
+its cross-section weight.
+</file>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Program Flow">
+
+<h2>Program Flow</h2>
+
+Recall that, to first order, the event generation process can be
+subdivided into three stages:
+<ol>
+<li>Initialization.</li>
+<li>The event loop.</li>
+<li>Finishing.</li>
+</ol>
+This is reflected in how the top-level <code>Pythia</code> class should
+be used in the user-supplied main program, further outlined in the
+following. Since the nature of the run is defined at the initialization
+stage, this is where most of the PYTHIA user code has to be written.
+So as not to confuse the reader unduly, the description of initialization
+options has been subdivided into what would normally be used and what is
+intended for more special applications.
+
+<h3>Initialization - normal usage</h3>
+
+<ol>
+
+<li>
+Already at the top of the main program file, you need to include the proper
+header file
+<pre>
+ #include "Pythia.h"
+</pre>
+To simplify typing, it also makes sense to declare
+<pre>
+ using namespace Pythia8;
+</pre>
+</li>
+
+<p/>
+<li>
+The first step is to create a generator object,
+e.g. with
+<pre>
+ Pythia pythia;
+</pre>
+It is this object that we will use from now on. Normally a run
+will only contain one <code>Pythia</code> object. (Hypothetically
+you could use several <code>Pythia</code> objects sequentially,
+but if done in parallel the <code>static</code> character of some
+program elements is likely not to give the desired behaviour.)<br/>
+By default all output from <code>Pythia</code> will be on the
+<code>cout</code> stream, but the <code>list</code> methods below do
+allow output to alternative streams or files (by an optional
+last argument, a reference to an <code>ostream</code>, usually not
+explicitly written out here).
+</li>
+
+<p/>
+<li>
+You next want to set up the character of the run.
+The pages under the "Setup Run Tasks" heading in the index
+describe all the options available (with some very few exceptions,
+found on the other pages).
+The default values and your modifications are stored in two databases,
+one for <aloc href="SettingsScheme">generic settings</aloc>
+and one for <aloc href="ParticleDataScheme">particle data</aloc>.
+Both of these are static classes, and are
+initialized with their default values by the <code>Pythia</code>
+constructor. The default values can then be changed, primarily
+by one of the two ways below, or by a combination of them.<br/>
+
+<p/>
+a) You can use the dedicated methods of each class to change the
+database default values to fit the needs of your current run. However,
+the
+<pre>
+ pythia.readString(string);
+</pre>
+method provides a covenient uniform interface to all of them.
+The information in the string is case-insensitive, but upper- and
+lowercase can be combined for clarity. The rules are that<br/>
+(i) if the first nonblank character of the string is a letter
+it is assumed to contain a setting, and is sent on to
+<code>pythia.settings.readString(string)</code>;<br/>
+(ii) if instead the string begins with a digit it is assumed to
+contain particle data updates, and so sent on to
+<code>pythia.particleData.readString(string)</code>;<br/>
+(iii) if none of the above, the string is assumed to be a comment,
+i.e. nothing will be done.<br/>
+In the former two cases, a warning is issued whenever a string
+cannot be recognized (maybe because of a spelling mistake),
+unless an optional second argument <code>false</code> is used to
+switch off warnings.<br/>
+Some examples would be
+<pre>
+ pythia.readString("TimeShower:pTmin = 1.0");
+ pythia.readString("111:mayDecay = false");
+</pre>
+The <code>readString(string)</code> method is intended primarily for
+a few changes. It can also be useful if you want to construct a
+parser of input files that contain commands to several different
+libraries.<br/>
+
+<p/>
+b) You can read in a file containing a list of those variables
+you want to see changed, with a
+<pre>
+ pythia.readFile(fileName);
+</pre>
+Each line in this file with be processes by the
+<code>readString(string)</code> method introduced above. You can thus
+freely mix comment lines and lines handed on to <code>Settings</code>
+or to <code>ParticleDataTable</code>.
+Again, an optional second argument <code>false</code> allows
+you to switch off warning messages for unknown variables.<br/>
+This approach is better suited for more extensive changes than a direct
+usage of <code>readString(string)</code>, and can also avoid having to
+recompile and relink your main program between runs.
+</li>
+
+<p/>
+<li>
+Next comes the initialization stage, where all
+remaining details of the generation are to be specified. The
+<code>init(...)</code> method allows a few different input formats,
+so you can pick the one convenient for you:
+
+<p/>
+a) <code>pythia.init( idA, idB, eCM);</code><br/>
+lets you specify the identities and the CM energy of the two incoming
+beam particles, with A (B) assumed moving in the <ei>+z (-z)</ei>
+direction.
+
+<p/>
+b) <code>pythia.init( idA, idB, eA, eB);</code><br/>
+is similar, but the two beam energies can be different, so the
+collisions do not occur in the CM frame. If one of the beam energies
+is below the particle mass you obtain a fixed-target topology.
+
+<p/>
+c) <code>pythia.init( idA, idB, pxA, pyA, pzA, pxB, pyB, pzB);</code><br/>
+is similar, but here you provide the three-momenta
+<ei>(p_x, p_y, p_z)</ei> of the two incoming particles,
+to allow for arbitrary beam directions.
+
+<p/>
+d) <code>pythia.init(fileName);</code> <br/>
+assumes a file in the <aloc href="LesHouchesAccord">Les Houches
+Event File</aloc> format <ref>Alw06</ref> is provided.
+
+<p/>
+e) <code>pythia.init();</code><br/>
+with no arguments will read the beam parameters from the
+<aloc href="MainProgramSettings"><code>Main</code></aloc>
+group of variables, which provides you with the same possibilities as
+the above options a, b, c and d. If you don't change any of those you will
+default to proton-proton collisions at 14 TeV, i.e. the nominal LHC
+values.
+
+<p/>
+f) <code>pythia.init( LHAup*);</code> <br/>
+assumes <aloc href="LesHouchesAccord">Les Houches Accord</aloc>
+<ref>Boo01</ref> initialization and event information is available
+in an <code>LHAup</code> class object, and that a pointer to this object
+is handed in.
+
+<p/>
+<li>
+If you want to have a list of the generator and particle data used,
+either only what has been changed or everything, you can use
+<pre>
+ pythia.settings.listChanged();
+ pythia.settings.listAll();
+ pythia.particleData.listChanged();
+ pythia.particleData.listAll();
+</pre>
+</li>
+
+</ol>
+
+<h3>The event loop</h3>
+
+<ol>
+
+<li>
+Inside the event generation loop you generate the
+next event using the <code>next()</code> method,
+<pre>
+ pythia.next();
+</pre>
+This method takes no arguments; everything has already been specified.
+It does return a bool value, however, <code>false</code> when the
+generation failed. This can be a "programmed death" when the
+supply of input parton-level configurations on file is exhausted,
+but also caused by a failure of <code>Pythia</code> to generate an event,
+or that an event was generated but something strange was detected
+in it. It makes sense to allow a few <code>false</code>
+values before a run is aborted, so long as the related faulty
+events are skipped.
+</li>
+
+<p/>
+<li>
+The generated event is now stored in the <code>event</code>
+object, of type <aloc href="EventRecord"><code>Event</code></aloc>,
+which is a public member of <code>pythia</code>. You therefore have
+access to all the tools described on the pages under the "Study Output"
+header in the index. For instance, an event can be listed with
+<code>pythia.event.list()</code>, the identity of the <ei>i</ei>'th
+<aloc href="ParticleProperties">particle</aloc> is given by
+<code>pythia.event[i].id()</code>, and so on.<br/>
+The hard process - roughly the information normally stored in the
+Les Houches Accord event record - is available as a second object,
+<code>process</code>, also of type <code>Event</code>.<br/>
+A third public object is
+<aloc href="EventInformation"><code>info</code></aloc>, which offers
+a set of one-of-a kind pieces of information about the most recent
+event.
+</li>
+
+</ol>
+
+<h3>Finishing</h3>
+
+<ol>
+
+<li>At the end of the generation process, you can call
+<pre>
+ pythia.statistics();
+</pre>
+to get some run statistics, on cross sections and the number of errors
+and warnings encountered. With optional argument <code>true</code>
+also further statistics is printed. Currently this means the number of
+different subprocesses generated in the multiple-interactions
+framework.
+</li>
+
+</ol>
+
+<h3>Advanced usage, mainly for initialization</h3>
+
+A) Necessary data are automatically loaded when you use the
+default PYTHIA installation directory structure and run the main
+programs in the <code>examples</code> subdirectory. However, in the
+general case, you must provide the path to the <code>.xml</code> files,
+originally stored in the <code>xmldoc</code> directory, where default
+settings and particle data are found. This can be done in two ways.
+
+<ol>
+
+<li>
+You can set the environment variable <code>PYTHIA8DATA</code> to
+contain the location of the <code>xmldoc</code> directory. In the
+<code>csh</code> and <code>tcsh</code> shells this could e.g. be
+<pre>
+ setenv PYTHIA8DATA /home/myname/pythia81xx/xmldoc
+</pre>
+while in other shells it could be
+<pre>
+ export PYTHIA8DATA=/home/myname/pythia81xx/xmldoc
+</pre>
+where xx is the subversion number.<br/>
+Recall that environment variables set locally are only defined in the
+current instance of the shell. The above lines should go into your
+<code>.cshrc</code> and <code>.bashrc</code> files, respectively,
+if you want a more permanant assignment.
+</li>
+
+<p/>
+<li>
+You can provide the path as argument to the <code>Pythia</code>
+constructor, e.g.
+<pre>
+ Pythia pythia("/home/myname/pythia81xx/xmldoc");
+</pre>
+</li>
+</ol>
+where again xx is the subversion number.<br/>
+When <code>PYTHIA8DATA</code> is set it takes precedence, else
+the path in the constructor is used, else one defaults to the
+<code>../xmldoc</code> directory.
+
+<p/>
+B) You can override the default behaviour of PYTHIA not only by the
+settings and particle data, but also by replacing some of the
+PYTHIA standard routines by ones of your own. Of course, this is only
+possible if your routines fit into the general PYTHIA framework.
+Therefore they must be coded according to the the rules relevant
+in each case, as a derived class of a PYTHIA base class, and a pointer
+to such an object must be handed in by one of the methods below.
+These calls must be made before the <code>pythia.init(...)</code> call.
+
+<ol>
+
+<li>
+If you are not satisfied with the list of parton density functions that
+are implemented internally or available via the LHAPDF interface
+(see the <aloc href="PDFSelection">PDF Selection</aloc> page), you
+can suppy your own by a call to the <code>setPDFPtr(...)</code> method
+<pre>
+ pythia.setPDFptr( pdfAPtr, pdfBPtr);
+</pre>
+where <code>pdfAPtr</code> and <code>pdfBPtr</code> are pointers to
+two <code>Pythia</code> <aloc href="PartonDistributions">PDF
+objects</aloc>. Note that <code>pdfAPtr</code> and <code>pdfBPtr</code>
+cannot point to the same object; even if the PDF set is the same,
+two copies are needed to keep track of two separate sets of <ei>x</ei>
+and density values.<br/>
+If you further wish to use separate PDF's for the hard process of an
+event than the ones being used for everything else, the extended form
+<pre>
+ pythia.setPDFptr( pdfAPtr, pdfBPtr, pdfHardAPtr, pdfHardBPtr);
+</pre>
+allows you to specify those separately, and then the first two sets
+would only be used for the showers and for multiple interactions.
+</li>
+
+<p/>
+<li>
+If you want to perform some particle decays with an
+external generator, you can call the <code>setDecayPtr(...)</code>
+method
+<pre>
+ pythia.setDecayPtr( decayHandlePtr, particles);
+</pre>
+where the <code>decayHandlePtr</code> derives from the
+<aloc href="ExternalDecays"><code>DecayHandler</code></aloc> base
+class and <code>particles</code> is a vector of particle codes to be
+handled.
+</li>
+
+<p/>
+<li>
+If you want to use an external random number generator,
+you can call the <code>setRndmEnginePtr(...)</code> method
+<pre>
+ pythia.setRndmEnginePtr( rndmEnginePtr);
+</pre>
+where <code>rndmEnginePtr</code> derives from the
+<aloc href="RandomNumbers"><code>RndmEngine</code></aloc> base class.
+The <code>Pythia</code> default random number generator is perfectly
+good, so this is only intended for consistency in bigger frameworks.
+</li>
+
+<p/>
+<li>
+If you want to interrupt the evolution at various stages,
+to interrogate the event and possibly veto it, or you want to
+reweight the cross section, you can use
+<pre>
+ pythia.setUserHooksPtr( userHooksPtr);
+</pre>
+where <code>userHooksPtr</code> derives from the
+<aloc href="UserHooks"><code>UserHooks</code></aloc> base class.
+</li>
+
+<p/>
+<li>
+If you want to use your own parametrization of beam momentum spread and
+interaction vertex, rather than the provided simple Gaussian
+parametrization (off by default), you can call
+<pre>
+ pythia.setBeamShapePtr( beamShapePtr);
+</pre>
+where <code>beamShapePtr</code> derives from the
+<aloc href="BeamShape"><code>BeamShape</code></aloc> base class.
+</li>
+
+<p/>
+<li>
+If you want to implement a cross section of your own, but still make use
+of the built-in phase space selection machinery, you can use
+<pre>
+ pythia.setSigmaPtr( sigmaPtr);
+</pre>
+where <code>sigmaPtr</code> of type <code>SigmaProcess*</code> is an
+instance of a class derived from one of the <code>Sigma1Process</code>,
+<code>Sigma2Process</code> and <code>Sigma3Process</code> base classes
+in their turn derived from
+<aloc href="SemiInternalProcesses"><code>SigmaProcess</code></aloc>.
+This call can be used repeatedly to hand in several different processes.
+</li>
+
+<p/>
+<li>
+If your cross section contains the production of a new resonance
+with known analytical expression for all the relevant partial widths,
+you can make this resonance available to the program with
+<pre>
+ pythia.setResonancePtr( resonancePtr);
+</pre>
+where <code>resonancePtr</code> of type <code>ResonanceWidths*</code>
+is an instance of a class derived from the
+<aloc href="SemiInternalResonances"><code>ResonanceWidths</code></aloc>
+base class. In addition you need to add the particle to the normal
+<aloc href="ParticleDataScheme">particle and decay database</aloc>.
+This procedure can be used repeatedly to hand in several different
+resonances.
+</li>
+
+<p/>
+<li>
+If you are a real expert and want to replace the PYTHIA initial- and
+final-state showers, you can use
+<pre>
+ pythia.setShowerPtr( timesDecPtr, timesPtr, spacePtr);
+</pre>
+where <code>timesDecPtr</code> and <code>timesPtr</code>
+derive from the <code>TimeShower</code> base class, and
+<code>spacePtr</code> from <code>SpaceShower</code>
+(<aloc href="ImplementNewShowers">further instructions</aloc>).
+</li>
+
+</ol>
+
+<p/>
+C) Some comments on collecting several tasks in the same run.
+<ol>
+
+<li>
+PYTHIA has not been written for threadsafe execution. As a rule, you
+should not have more than one <code>Pythia</code> object in an executable
+at any time. For multicore processors, if you want to use all cores,
+the most efficient way presumably is to start correspondingly many jobs,
+with different random number seeds, and add the statistics at the end.
+
+<p/>
+In some cases it is possible to use more than one <code>Pythia</code>
+object. The key example would be the simultaneous generation of signal
+and pileup events, see <code>main19.cc</code>. Here all signal processes
+must be switched on before the first initialization, and then switched
+off and replaced by the background ones before the second initialization.
+Also most other settings can be changed consistently in between the two
+initializations, but in a few cases the last value will be used. Particle
+data is always based on the latest information. As a rule, however, it is
+safer to use two separate runs to store events on disk, in two separate
+files, and mix afterwards.
+</li>
+
+<p/>
+<li>
+When time is not an issue, it may be that you want to perform several
+separate subruns sequentially inside a run, e.g. to combine results for
+several kinematical regions or to compare results for some different
+tunes of the underlying event. One way to go is to create and destroy a
+<code>pythia</code> object once for each subrun, in which case they are
+completely separate. You can also use the same <code>pythia</code> object,
+only doing a new <code>init(...)</code> call for each subrun. In that
+case, the settings and particle databases remain as they were in the
+previous subrun, only affected by the specific changes you introduced in
+the meantime. You can put those changes in the main program, with
+<code>pythia.readString(string)</code>, using your own logic to decide
+which ones to execute in which subrun. A corresponding possibility
+exists with <code>pythia.readFile(fileName, subrun)</code>, which
+as second argument can take a non-negative subrun number. (Or,
+alternatively use the longer form
+<code>pythia.readFile(fileName, warn, subrun)</code>.) Then only those
+sections of the file before any <code>Main:subrun = ...</code> line
+or with matching <code>subrun</code> number will be read. That is, the
+file could have a structure like
+<pre>
+ ( lines always read, i.e. "default values" always (re)set )
+ Main:subrun = 1
+ ( lines only read with readFile(fileName, 1) )
+ Main:subrun = 2
+ ( lines only read with readFile(fileName, 2) )
+</pre>
+Both of these possibilities are illustrated in <code>main08.cc</code>.
+</li>
+
+<p/>
+<li>
+When working with Les Houches Event Files, it may well be that your
+intended input event sample is spread over several files, that you all
+want to turn into complete events in one and the same run. There is no
+problem with looping over several subruns, where each new subrun
+is initialized with a new file. However, in that case you will do
+a complete re-initialization each time around. If you want to avoid
+this, note that there is an optional second argument for LHEF
+initialization: <code>pythia.init(fileName, skipInit)</code>.
+Alternatively, the tag <code>Main:LHEFskipInit</code> can be put
+in a file of commands to obtain the same effect.
+Here <code>skipInit</code> defaults to <code>false</code>,
+but if set <code>true</code> then the new file will be simulated
+with the same initialization data as already set in a previous
+<code>pythia.init(...)</code> call. The burden rests on you to ensure
+that this is indeed correct, e.g. that the two event samples have not
+been generated for different beam energies.
+</li>
+
+</ol>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="QCD Processes">
+
+<h2>QCD Processes</h2>
+
+This section is subdivided into soft and hard QCD processes, with
+open charm and bottom production set aside as a special part of the
+latter.
+
+<h3>Soft QCD processes</h3>
+
+As a rule, the processes in this class should not be mixed with
+the simulation of other processes. All by themselves, they are
+intended to represent the total cross section of hadron collisions,
+with the exception of the "rare processes" that one wishes to study
+separately. In particular, jet physics at all scales occurs as part
+of the minimum-bias description.
+
+<p/>
+We here use the "minimum bias" expression as a shorthand for
+inelastic, nondiffractive events. Strictly speaking, "minimum bias"
+represents an experimental procedure of accepting "everything", with
+some non-universal cuts to exclude elastic and diffractive topologies.
+In practice, the experimental mimimum-bias sample may then contain
+some contamination of what is in PYTHIA classified as diffractive,
+especially (high-mass) double diffractive.
+
+<p/>
+Some options to modify these cross sections, and especially to include
+Coulomb corrections to the elastic cross section, are found on the
+<aloc href="TotalCrossSections">Total Cross Sections</aloc> page.
+
+<flag name="SoftQCD:all" default="off">
+Common switch for the group of all soft QCD processes,
+as listed separately in the following.
+</flag>
+
+<flag name="SoftQCD:minBias" default="off">
+Minimum-bias events, based on an eikonalized description of all the
+hard QCD processes, so includes them in combinationation with
+low-<ei>pT</ei> events. Code 101.<br/>
+Since the current description is handled by the multiple-interactions
+machinery as part of the parton-level processing, no hard process at
+all is defined at the process-level part of the event generation.
+Fortunately, in this case a special
+<aloc href="EventInformation"><code>codeSub()</code></aloc>
+method provides information on the first, i.e. hardest, subprocess
+selected by the multiple-interactions machinery.
+
+</flag>
+
+<flag name="SoftQCD:elastic" default="off">
+Elastic scattering <ei>A B -> A B</ei>.
+Code 102.
+</flag>
+
+<flag name="SoftQCD:singleDiffractive" default="off">
+Single diffractive scattering <ei>A B -> X B</ei> and
+<ei>A B -> A X</ei>.
+Codes 103 and 104.
+</flag>
+
+<flag name="SoftQCD:doubleDiffractive" default="off">
+Double diffractive scattering <ei>A B -> X_1 X_2</ei>.
+Code 105.
+</flag>
+
+<h3>Hard QCD processes</h3>
+
+This group contains the processes for QCD jet production above
+some minimum <ei>pT</ei> threshold. The <ei>pT_min</ei> cut cannot be put
+too low, or else unreasonably large jet cross sections will be obtained.
+An eikonalized description, intended to be valid at all <ei>pT</ei>,
+is included as part of the multiple-interactions framework, e.g. in
+<code>SoftQCD:minBias</code> above.
+
+<flag name="HardQCD:all" default="off">
+Common switch for the group of all hard QCD processes,
+as listed separately in the following.
+</flag>
+
+<flag name="HardQCD:gg2gg" default="off">
+Scatterings <ei>g g -> g g</ei>.
+Code 111.
+</flag>
+
+<flag name="HardQCD:gg2qqbar" default="off">
+Scatterings <ei>g g -> q qbar</ei>, where <ei>q</ei> by default
+is a light quark (<ei>u, d, s</ei>) (see below).
+Code 112.
+</flag>
+
+<flag name="HardQCD:qg2qg" default="off">
+Scatterings <ei>q g -> q g</ei> and <ei>qbar g -> qbar g</ei>.
+Code 113.
+</flag>
+
+<flag name="HardQCD:qq2qq" default="off">
+Scatterings <ei>q q' -> q q'</ei>, <ei>q qbar' -> q qbar'</ei>,
+<ei>qbar qbar' -> qbar qbar'</ei>, where <ei>q'</ei> and <ei>q</ei>
+may agree, but the outgoing flavours equals the incoming ones
+Code 114.
+</flag>
+
+<flag name="HardQCD:qqbar2gg" default="off">
+Scatterings <ei>q qbar -> g g</ei>.
+Code 115.
+</flag>
+
+<flag name="HardQCD:qqbar2qqbarNew" default="off">
+Scatterings <ei>q qbar -> q' qbar'</ei>, where <ei>q'</ei>
+by default is a light quark (<ei>u, d, s</ei>) (see below).
+Code 116.
+</flag>
+
+<modeopen name="HardQCD:nQuarkNew" default="3" min="0" max="5">
+Number of allowed outgoing new quark flavours in the above
+<ei>g g -> q qbar</ei> and <ei>q qbar -> q' qbar'</ei> processes,
+where quarks are treated as massless in the matrix-element expressions
+(but correctly in the phase space). It is thus assumed that <ei>c cbar</ei>
+and <ei>b bbar</ei> are added separately with masses taken into account,
+using the processes below. A change to 4 would also include <ei>c cbar</ei>
+in the massless approximation, etc. In order to avoid doublecounting
+the processes below should then not be used simultaneously.
+</modeopen>
+
+<h3>Hard QCD processes: heavy-flavour subset</h3>
+
+These processes form a natural part of the above class, but can
+also be generated separately. Formally the heavy-quark mass makes
+these matrix elements finite in the <ei>pT -> 0</ei> limit, but at
+high energies one may still question the validity of the expressions
+at low <ei>pT</ei> values, like for the other hard-QCD processes.
+Also as above, an eikonalized description, intended to be valid at all
+<ei>pT</ei>, is included as part of the multiple-interactions framework.
+<br/>Note that the processes below only represent the "tip of the iceberg"
+of charm and bottom production at high energies, where flavour excitation
+and shower branchings provide major additional sources. All these sources
+come together in the descriptions offered by <code>SoftQCD:minBias</code>
+and <code>HardQCD:all</code>.
+
+<flag name="HardQCD:gg2ccbar" default="off">
+Scatterings <ei>g g -> c cbar</ei>.
+Code 121.
+</flag>
+
+<flag name="HardQCD:qqbar2ccbar" default="off">
+Scatterings <ei>q qbar -> c cbar</ei>.
+Code 122.
+</flag>
+
+<flag name="HardQCD:gg2bbbar" default="off">
+Scatterings <ei>g g -> b bbar</ei>.
+Code 123.
+</flag>
+
+<flag name="HardQCD:qqbar2bbbar" default="off">
+Scatterings <ei>q qbar -> b bbar</ei>.
+Code 124.
+</flag>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Random-Number Seed">
+
+<h2>Random-Number Seed</h2>
+
+The seed of the random number generator can be set as follows:
+
+<flag name="Random:setSeed" default="off">
+Indicates whether a user-set seed should be used every time the
+<code>Pythia::init</code> routine is called. If off, the random number
+generator is initialized with its default seed at the beginning
+of the run, and never again. If on, each new <code>Pythia::init</code>
+call (should several be made in the same run) results in the random
+number being re-initialized, thereby possibly starting over with the
+same sequence, if you do not watch out.
+</flag>
+
+<modeopen name="Random:seed" default="-1" max="900000000">
+The seed to be used, if <code>setSeed</code> is on.<br/>
+A negative value gives the default seed,<br/>
+a value 0 gives a random seed based on the time, and<br/>
+a value between 1 and 900,000,000 a unique different random number
+sequence.
+</modeopen>
+
+<p/>
+For more on random numbers see <aloc href="RandomNumbers">here</aloc>.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Random Numbers">
+
+<h2>Random Numbers</h2>
+
+This page describes the random-number generator in PYTHIA and
+how it can be replaced by an external one.
+
+<h3>Internal random numbers</h3>
+
+The <code>Rndm</code> class generates random numbers, using the
+Marsaglia-Zaman-Tsang algorithm <ref>Mar90</ref>. It is purely static,
+i.e. only exists in one copy, so that one cannot run several copies,
+each with the same random number sequence, by mistake.
+
+<p/>
+Random numbers <code>R</code> uniformly distributed in
+<code>0 < R < 1</code> are obtained with
+<pre>
+ Rndm::flat();
+</pre>
+There are also methods to generate according to an exponential, to
+<ei>x * exp(-x)</ei>, to a Gaussian, or picked among a set of
+possibilites, which make use of <code>flat()</code>.
+
+<p/>
+If the random number generator is not initialized before, it will be
+so the first time it is asked to generate a random number, and then
+with the default seed, 19780503. You can initialize, or reinitialize,
+with your own choice of seed with a
+<pre>
+ Rndm::init(seed);
+</pre>
+Here values <code>0 < seed < 900 000 000</code> gives so many
+different random number sequences, while <code>seed = 0</code> will call
+the <code>Stdlib time(0)</code> function to provide a "random"
+<code>seed</code>, and <code>seed < 0</code> will revert back to
+the default <code>seed</code>.
+
+<p/>
+The <code>Pythia</code> class defines <aloc href="RandomNumberSeed">a
+flag and a mode</aloc>, that allows the <code>seed</code> to be set in
+the <code>Pythia::init</code> call. That would be the standard way for a
+user to pick the random number sequence in a run.
+
+<h3>External random numbers</h3>
+
+<code>RndmEngine</code> is a base class for the external handling of
+random-number generation. The user-written derived class is called
+if a pointer to it has been handed in with the
+<code>pythia.rndmEnginePtr()</code> method. Since the default
+Marsaglia-Zaman-Tsang algorithm is quite good, chances are that any
+replacement would be a step down, but this may still be required by
+consistency with other program elements in big experimental frameworks.
+
+<p/>
+There is only one pure virtual method in <code>RndmEngine</code>, to
+generate one random number flat in the range between 0 and 1:
+<pre>
+ virtual double flat() = 0;
+</pre>
+Note that methods for initialization are not provided in the base
+class, in part since input parameters may be specific to the generator
+used, in part since initialization can as well be taken care of
+externally to the <code>Pythia</code> code.
+
+<p/>
+An example illustrating how to run with an external random number
+generator is provided in <code>main24.cc</code>.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Random-Number Seed">
+
+<h2>Random-Numbers Seed</h2>
+
+The seed of the random number generator can be set as follows:
+
+<flag name="Random:setSeed" default="off">
+Indicates whether a user-set seed should be used every time the
+<code>Pythia::init</code> routine is called. If off, the random number
+generator is initialized with its default seed at the beginning
+of the run, and never again. If on, each new <code>Pythia::init</code>
+call (should several be made in the same run) results in the random
+number being re-initialized, thereby possibly starting over with the
+same sequence, if you do not watch out.
+</flag>
+
+<modeopen name="Random:seed" default="-1" max="900000000">
+The seed to be used, if <code>setSeed</code> is on.<br/>
+A negative value gives the default seed,<br/>
+a value 0 gives a random seed based on the time, and<br/>
+a value between 1 and 900,000,000 a unique different random number
+sequence.
+</modeopen>
+
+<p/>
+See further <aloc href="RandomNumbers">here</aloc>.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Resonance Decays">
+
+<h2>Resonance Decays</h2>
+
+The <code>ResonanceDecays</code> class performs the sequential decays of
+all resonances formed in the hard process. Note the important distinction
+between "resonances" and other "particles" made in PYTHIA.
+<ul>
+<li>
+The list of resonances contains <ei>gamma^*/Z^0</ei>, <ei>W^+-</ei>, top,
+the Higgs, and essentially all new particles of Beyond-the-Standard-Model
+physics: further Higgses, sfermions, gauginos, techniparticles, and so on.
+The partial widths to different decay channels are perturbatively
+calculable, given the parameters of the respective model, and branching
+ratios may be allowed to vary across a (reasonably broad) resonance peak.
+Usually resonances are short-lived, and therefore it makes sense to consider
+their decays immediately after the primary hard process has been set up.
+Furthermore, in several cases the decay angular distributions are encoded
+as part of the specific process, e.g. the <ei>W</ei> decays differently in
+<ei>f fbar -> W^+-</ei>, <ei>f fbar -> W^+ W^-</ei> and
+<ei>h^0 -> W^+ W^- </ei>. All of these particles are (in PYTHIA) only
+produced as part of the hard process itself, i.e. they are not produced
+in showers or hadronization processes. Therefore the restriction to
+specific decay channels can be consistently taken into account as a
+corresponding reduction in the cross section of a process. Finally, note
+that all of these resonances have an on-shell mass above 20 GeV, with the
+exception of some hypothetical weakly interacting and stable particles
+such as the gravitino.
+</li>
+<li>
+The other particles include normal hadrons and the Standard-Model leptons,
+including the <ei>tau^+-</ei>. These can be produced in the normal
+hadronization and decay description, which involve unknown nonperturbative
+parameters and multistep chains that cannot be predicted beforehand:
+a hard process like <ei>g g -> g g</ei> can develop a shower with a
+<ei>g -> b bbar</ei> branching, where the <ei>b</ei> hadronizes to a
+<ei>B^0bar</ei> that oscillates to a <ei>B^0</ei> that decays to a
+<ei>tau^+</ei>. Therefore any change of branching ratios - most of which
+are determined from data rather than from first principles anyway -
+will not be taken into account in the cross section of a process.
+Exceptions exist, but most particles in this class are made to decay
+isotropically. Finally, note that all of these particles have a mass
+below 20 GeV.
+</li>
+</ul>
+
+There is one ambiguous case in this classification, namely the photon.
+The <ei>gamma^*/Z^0</ei> combination contains a low-mass peak when
+produced in a hard process. On the other hand, photons can participate
+in shower evolution, and therefore a photon originally assumed
+massless can be assigned an arbitrarily high mass when it is allowed
+to branch into a fermion pair. In some cases this could lead to
+doublecounting, e.g. between processes such as
+<ei>f fbar -> (gamma^*/Z^0) (gamma^*/Z^0)</ei>,
+<ei>f fbar -> (gamma^*/Z^0) gamma</ei> and
+<ei>f fbar -> gamma gamma</ei>. Here it make sense to limit the
+lower mass allowed for the <ei>gamma^*/Z^0</ei> combination,
+in <code>23:mMin</code>, to be the same as the upper limit allowed
+for an off-shell photon in the shower evolution, in
+<code>TimeShower:mMaxGamma</code>. By default this matching is done
+at 10 GeV.
+
+<p/>
+In spite of the above-mentioned differences, the resonances and the
+other particles are all stored in one common
+<aloc href="ParticleData">particle data table</aloc>, so as to offer a
+uniform interface to <aloc href="ParticleDataScheme">setting and
+getting</aloc> properties such as name, mass, charge and decay modes,
+also for the <aloc href="ParticleProperties">particle properties</aloc>
+in the event record. Some methods are specific to resonances, however,
+in particular for the calculation of partial widths and thereby of
+branching ratio. For resonances these can be calculated dynamically,
+set up at initialization for the nominal mass and then updated to the
+current mass when these are picked according to a Breit-Wigner resonance
+shape.
+
+<h3>Resonance Decays and Cross Sections</h3>
+
+As already hinted above, you have the possibility to set the allowed
+decay channels of resonances, see
+<aloc href="ParticleDataScheme">Particle Data Scheme</aloc> description.
+For instance, if you study the process <ei>q qbar -> H^0 Z^0</ei>
+you could specify that the <ei>Z^0</ei> should decay only to
+lepton pairs, the <ei>H^0</ei> only to <ei>W^+ W^-</ei>, the
+<ei>W^+</ei> only to a muon and a neutrino, while the <ei>W^-</ei>
+can decay to anything. Unfortunately there are limits to the
+flexibility: you cannot set a resonance to have different properties
+in different places of a process, e.g. if instead
+<ei>H^0 -> Z^0 Z^0</ei> in the above process then the three
+<ei>Z^0</ei>'s would all obey the same rules.
+
+<p/>
+The restrictions on the allowed final states of a process is directly
+reflected in the cross section of it. That is, if some final states
+are excluded then the cross section is reduced accordingly. Such
+restrictions are built up recursively in cases of sequential decay
+chains. The restrictions are also reflected in the compositions of
+those events that actually do get to be generated. For instance,
+the relative rates of <ei>H^0 -> W^+ W^-</ei> and
+<ei>H^0 -> Z^0 Z^0</ei> are shifted when the allowed sets of
+<ei>W^+-</ei> and <ei>Z^0</ei> decay channels are changed.
+
+<p/>
+We remind that only those particles that Pythia treat as resonances
+enjoy this property, and only those that are considered as part of the
+hard process and its assocaited resonance decays.
+
+<p/>
+There is one key restriction on resonances:
+<parm name="ResonanceWidths:minWidth" default="1e-20" min="1e-30">
+Minimal allowed width of a resonance, in GeV. If the width falls below
+this number the resonance is considered stable and will not be allowed
+to decay. This is mainly intended as a technical parameter, to avoid
+disasters in cases where no open decay channels exists at all. It could
+be used for real-life decisions as well, however, but then typically
+would have to be much bigger than the default value. Special caution
+would be needed if coloured resonance particles were made stable, since
+the program would not necessarily know how to hadronize them, and
+therefore fail at that stage.
+</parm>
+
+<h3>Special properties and methods for resonances</h3>
+
+The method <code>ParticleDataTable::isResonance(id)</code> allows you to
+query whether a given particle species is considered a resonance or not.
+You can also change the default value of this flag in the normal way,
+e.g. <code>pythia.readString("id:isResonance = true")</code>.
+
+<p/>
+An option with a forced width can be set with the
+<code>id:doForceWidth</code> flag as above, and queried with
+<code>ParticleDataTable::doForceWidth(id)</code>. It is by default
+<code>off</code>, and should normally so remain. If switched
+<code>on</code> then the width stored in <code>id:mWidth</code> is
+strictly used to describe the Breit-Wigner of the resonance. This is
+unlike the normal behaviour of standard resonances such as the
+<ei>Z^0</ei>, <ei>W^+-</ei>, <ei>t</ei> or <ei>h^0</ei>, which have
+explicit decay-widths formulae encoded, in classes derived from the
+<aloc href="SemiInternalResonances"><code>ResonanceWidths</code></aloc>
+base class. These formulae are used, e.g., to derive all the Higgs partial
+widths as a function of the Higgs mass you choose, and at initialization
+overwrites the existing total width value. The reason for forcing the
+width to another value specified by you would normally more have to do
+with experimental issues than with physics ones, e.g. how sensitive your
+detector would be to changes in the Higgs width by a factor of two.
+A warning is that such a rescaling could modify the cross section of
+a process correspondingly for some processes, while leaving it
+(essentially) unchanged for others (as would seem most logical),
+depending on how these were encoded. A further warning is that,
+if you use this facility for <ei>Z^0</ei> or <ei>Z'^0</ei> with
+<ei>gamma^*/Z^0</ei> or <ei>gamma^*/Z^0/Z'^0</ei> interference on,
+then also the handling of this interference is questionable.
+So, if you need to use the width-rescaling option, be extremely cautios.
+
+<p/>
+If a resonance does not have a class of its own, with hardcoded equations
+for all relevant partial widths, then a simpler object will be created
+at initialization. This object will take the total width and branching
+ratios as is (with the optional variations explained in the next section),
+and thus the rescaling approach brings no further freedom.
+
+<p/>
+Mainly for internal usage, the <code>ParticleDataTable</code> contain
+some special methods that are only meaningful for resonances:
+<ul>
+<li><code>resInit(...)</code> to initialize a resonance, possibly
+including a recalculation of the nominal width to match the nominal
+mass;</li>
+<li><code>resWidth(...)</code> to calculate the partial and total widths
+at the currently selected mass;</li>
+<li><code>resWidthOpen(...)</code> to calculate the partial and total
+widths of those channels left open by user switches, at the currently
+selected mass;</li>
+<li><code>resWidthStore(...)</code> to calculate the partial and total
+widths of those channels left open by user switches, at the currently
+selected mass, and store those as input for a subsequent selection of
+decay channel;</li>
+<li><code>resOpenFrac(...)</code> to return the fraction of the total
+width that is open by the decay channel selection made by users (based on
+the choice of <aloc href="ParticleDataScheme"><code>onMode</code></aloc>
+for the various decay channels, recursively calculated for sequential
+decays);</li>
+<li><code>resWidthRescaleFactor(...)</code> returns the factor by which
+the internally calculated PYTHIA width has to be rescaled to give the
+user-enforced width;</li>
+<li><code>resWidthChan(...)</code> to return the width for one particular
+channel (currently only used for Higgs decays, to obtain instate coupling
+from outstate width).</li>
+</ul>
+These methods actually provide an interface to the classes derived from
+the <code>ResonanceWidths</code> base class, to describe various
+resonances.
+
+<h3>Modes for Matrix Element Processing</h3>
+
+The <code>meMode()</code> value for a decay mode is used to specify
+<aloc href="ParticleDecays">nonisotropic decays or the conversion of
+a parton list into a set of hadrons</aloc> in some channels of normal
+particles. For resonances it can also take a third function, namely
+to describe how the branching ratios and widths of a resonance should
+be rescaled as a function of the current mass of the decaying resonance.
+The rules are especially useful when new channels are added to an
+existing particle, or a completely new resonance added.
+
+<ul>
+<li>0 : channels for which hardcoded partial-width expressions are
+expected to exist in the derived class of the respective resonance.
+Should no such code exist then the partial width defaults to zero.
+</li>
+<li>1 - 99 : same as 0, but normally not used for resonances.</li>
+<li>100 : calculate the partial width of the channel from its stored
+branching ratio times the stored total width. This value remains unchanged
+when the resonance fluctuates in mass. Specifically there are no
+threshold corrections. That is, if the resonance fluctuates down in
+mass, to below the nominal threshold, it is assumed that one of the
+daughters could also fluctuate down to keep the channel open. (If not,
+there may be problems later on.)
+</li>
+<li>101 : calculate the partial width of the channel from its stored
+branching ratio times the stored total width. Multiply by a step threshold,
+i.e. the channel is switched off when the sum of the daughter on-shell
+masses is above the current mother mass.</li>
+<li>102 : calculate the partial width of the channel from its stored
+branching ratio times the stored total width. Multiply by a smooth
+threshold factor
+<ei>beta = sqrt( (1 - m_1^2/m_2 - m_2^2/m^2)^2 - 4 m_1^2 m_2^2/m^4)</ei>
+for two-body decays and <ei>sqrt(1 - Sum_i m_i / m)</ei> for multibody
+ones. The former correctly encodes the size of the phase space but
+misses out on any nontrivial matrix-element behaviour, while the latter
+obviously is a very crude simplification of the correct phase-space
+expression. Specifically, it is thereby assumed that the stored branching
+ratio and total width did not take into account such a factor.</li>
+<li>103 : use the same kind of behaviour and threshold factor as for
+102 above, but assume that such a threshold factor has been used when
+the default branching ratio and total width were calculated, so that one
+should additionally divide by the on-shell threshold factor. Specifically,
+this will give back the stored branching ratios for on-shell mass,
+unlike the 102 option. To avoid division by zero, or in general
+unreasonably big rescaling factors, a lower limit
+<code>minThreshold</code> (see below) on the value of the on-shell
+threshold factor is imposed. (In cases where a big rescaling is
+intentional, code 102 would be more appropriate.) </li>
+</ul>
+
+<parm name="ResonanceWidths:minThreshold" default="0.1" min="0.01">
+Used uniquely for <code>meMode = 103</code> to set the minimal value
+assumed for the threshold factor,
+<ei>sqrt( (1 - m_1^2/m_2 - m_2^2/m^2)^2 - 4 m_1^2 m_2^2/m^4)</ei>
+for two-body decays and <ei>sqrt(1 - Sum_i m_i / m)</ei> for multibody
+ones. Thus the inverse of this number sets an upper limit for how
+much the partial width of a channel can increase from the on-shell
+value to the value for asymptotically large resonance masses. Is mainly
+intended as a safety measure, to avoid unintentionally large rescalings.
+</parm>
+
+<p/>
+All of these <code>meMode</code>'s may coexist for the same resonance.
+This would be the case e.g. if you want to add a few new channels to an
+already existing resonance, where the old partial widths come hardcoded
+while the new ones are read in from an external file. The typical example
+would be an MSSM Higgs sector, where partial widths to SM particles are
+already encoded, <code>meMode = 0</code>, while decay rates to sparticles
+are read in from some external calculation and maybe would be best
+approximated by using <code>meMode = 103</code>. Indeed the default
+particle table in PYTHIA uses 103 for all channels that are expected
+to be provided by external input.
+
+<p/>
+Some further clarification may be useful. At initialization the existing
+total width and on-shell branching ratios will be updated. For channels
+with <code>meMode < 100</code> the originally stored branching ratios
+are irrelevant, since the existing code will anyway be used to calculate
+the partial widths from scratch. For channels with <code>meMode = 100</code>
+or bigger, instead the stored branching ratio is used together with the
+originally stored total width to define the correct on-shell partial width.
+The sum of partial widths then gives the new total width, and from there
+new branching ratios are defined.
+
+<p/>
+In these operations the original sum of branching ratios need not be
+normalized to unity. For instance, you may at input have a stored total
+width of 1 GeV and a sum of branching ratios of 2. After initialization
+the width will then have been changed to 2 GeV and the sum of branching
+ratios rescaled to unity. This might happen e.g. if you add a few channels
+to an existing resonance, without changing the branching ratios of the
+existing channels or the total width of the resonance.
+
+<p/>
+In order to simulate the Breit-Wigner shape correctly, it is important
+that all channels that contribute to the total width are included in the
+above operations. This must be kept separate from the issue of which
+channels you want to have switched on for a particular study, to be
+considered next.
+
+<p/>
+
+In the event-generation process, when an off-shell resonance mass has been
+selected, the width and branching ratios are re-evaluated for this new mass.
+At this stage also the effects of restrictions on allowed decay modes are
+taken into account, as set by the <code>onMode</code> switch for each
+separate decay channel. Thus a channel may be on or off, with different
+choices of open channels between the particle and its antiparticle.
+In addition, even when a channel is on, the decay may be into another
+resonance with its selection of allowed channels. It is these kinds of
+restrictions that lead to the <ei>Gamma_out</ei> possibly being
+smaller than <ei>Gamma_tot</ei>. As a reminder, the Breit-Wigner for
+decays behaves like <ei>Gamma_out / ((s - m^2)^2 + s * Gamma_tot^2)</ei>,
+where the width in the numerator is only to those channels being studied,
+but the one in the denominator to all channels of the particle. These
+ever-changing numbers are not directly visible to the user, but are only
+stored in a work area.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="SUSY Les Houches Accord">
+
+<h2>SUSY Les Houches Accord</h2>
+
+The PYTHIA 8 program does not contain an internal spectrum calculator
+(a.k.a. RGE package) to provide supersymmetric couplings, mixing angles,
+masses and branching ratios. Thus the SUSY Les Houches Accord (SLHA)
+<ref>Ska04</ref> is the only way of inputting SUSY models, and
+SUSY processes cannot be run unless such an input has taken place.
+
+<flag name="SUSY" default="off">
+Global switch for SUSY on or off. When on, the initialization step
+(<code>pythia.init</code>) will read in the file below and set up
+the information required for simulation of supersymmetric processes.
+</flag>
+
+<word name="SUSY:SusyLesHouchesFile" default="softsusy.spc">
+Name of a SUSY Les Houches Accord (SLHA) spectrum file containing the
+SUSY model definition, masses, and other parameters pertaining to
+the desired SUSY model. Note that SLHA files can still be used
+even if no supersymmetric processes are switched on, as an
+alternative way of inputting particle masses, decay tables, etc.
+</word>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
+
--- /dev/null
+<chapter name="SUSY Processes">
+
+<h2>SUSY Processes</h2>
+
+The implementation of SUSY processes is barely begun, so this page
+is more a placeholder than a repository of useful processes.
+
+<p/>
+Here is collected processes involving supersymmetric particle
+production, with the exception of the (extended) Higgs sector.
+Since the number of separate but closely related processes is so big,
+there will not be switches for each separate process but only for a
+reasonable set of subgroups.
+
+<br/><note>Important note:</note>
+In order to simulate SUSY processes it is required to read in the
+couplings and masses relevant for the scenario to be studied. This
+is done with the help of the SUSY Les Houches Accord (SLHA). The
+reading of a relevant SLHA file <b>must</b> be set up, as described
+on <aloc href="SUSYLesHouchesAccord">this page</aloc>.
+
+<flag name="SUSY:all" default="off">
+Common switch for production of supersymmetric particles, i.e.
+particles with R-parity -1.
+</flag>
+
+<flag name="SUSY:qqbar2chi0chi0" default="off">
+Pair production of neutralinos by quark-antiquark annihilation. With
+four neutralino species this gives ten separate processes, codes
+1201 - 1210. Neutralino decays have not yet been implemented.
+</flag>
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Sample Main Programs">
+
+<h2>Sample Main Programs</h2>
+
+To help exemplify what a main program could look like, a few simple
+examples are provided in the <code>examples</code> subdirectory,
+along with instructions how they should be run:
+<ul>
+
+<li><code>main01.cc</code> : a simple study of the charged multiplicity
+for jet events at the LHC. (Brief example given in talks.)</li>
+
+<li><code>main02.cc</code> : a simple study of the <ei>pT</ei> spectrum
+of Z bosons at the Tevatron. (Brief example given in talks.)</li>
+
+<li><code>main03.cc</code> : a simple single-particle analysis of jet
+events, where input is set by <code>main03.cmnd</code> "cards file".</li>
+
+<li><code>main04.cc</code> : a simple study of several different kinds
+of events, with the choice to be made in the <code>main04.cmnd</code>
+"cards file".</li>
+
+<li><code>main05.cc</code> : generation of QCD jet events at the LHC,
+with jet analysis using the <code>CellJet</code> cone-jet finder.</li>
+
+<li><code>main06.cc</code> : tests of cross sections for elastic and
+diffractive topologies, using <code>main06.cmnd</code> to pick process.</li>
+
+<li><code>main07.cc</code> : tests of cross sections for minimum-bias
+events, using <code>main07.cmnd</code> to pick options.</li>
+
+<li><code>main08.cc</code> : generation of the QCD jet cross section
+by splitting the run into subruns, each in its own <ei>pT</ei> bin,
+and adding the results properly reweighted. Two options, with limits
+set either in the main program or by subrun specification in the
+<code>main08.cmnd</code> file.</li>
+
+<li><code>main09.cc</code> : generation of LEP1 hadronic events, i.e.
+<ei>e^+e^- -> gamma*/Z^0 -> q qbar</ei>, with charged multiplicity,
+sphericity, thrust and jet analysis.</li>
+
+<li><code>main10.cc</code> : illustration how userHooks can be used
+interact directly with the event-generation process.</li>
+
+<li><code>main11.cc</code> : generation of two predetermined hard
+interactions in each event.</li>
+
+<li><code>main12.cc</code> : a study of top events, fed in from the
+Les Houches Event File <code>ttbar.lhe</code>, here generated by
+<code>main53.f</code>. This file currently only contains 100 events
+so as not to make the distributed PYTHIA package too big, and so serves
+mainly as a demonstration of the principles involved. </li>
+
+<li><code>main13.cc</code> : a more sophisticated variant of
+<code>main12.cc</code>, where two Les Houches Event Files
+(<code>ttbar.lhe</code> and <code>ttbar2.lhe</code>) successively
+are used as input. Also illustrating some other aspects, like the
+capability to mix in internally generated events.</li>
+
+<li><code>main14.cc</code> : a systematic comparison of several
+cross section values with their corresponding values in PYTHIA 6.4,
+the latter available as a table in the code.</li>
+
+<li><code>main15.cc</code> : loop over several tries, either to redo
+B decays only or to redo the complete hadronization chain of an event.
+Since much of the generation process is only made once this is a way
+to increase efficiency.</li>
+
+<li><code>main16.cc</code> : put all user analysis code into a class
+of its own, separate from the main program; provide the "cards file"
+name as a command-line argument.</li>
+
+<li><code>main17.cc</code> : collect the Pythia calls in a wrapper class,
+thereby simplifying the main program; provide the "cards file" name
+as a command-line argument.</li>
+
+<li><code>main18.cc</code> : shows how to write an event filter class,
+where you keep a vector of pointers to the subset of particles you
+want to study further. The event record itself remains unchanged.</li>
+
+<li><code>main19.cc</code> : use several instances of Pythia, one for
+signal events and others for a variable number of pileup and "beam-gas"
+events, combined into one common event record.</li>
+
+<li><code>main20.cc</code> : shows how PYTHIA 8 can write a Les Houches
+Event File, using facilities potentially useful also for other programs
+to write an LHEF.</li>
+
+<li><code>main21.cc</code> : an example how parton-level configurations
+can be input directly for hadronization, without being tied to the
+full process-generation machinery, e.g. to study the hadronization of
+junction topologies.</li>
+
+<li><code>main22.cc</code> : tests of internally implemented cross sections
+for Supersymmetric particle production, with SYSY spectrum defined in
+<code>main22.spc</code> and settings in <code>main22.cmnd</code>.</li>
+
+<li><code>main23.cc</code> : shows how an external decay handler can
+be linked to handle the decays of some particles.</li>
+
+<li><code>main24.cc</code> : shows how an external random number
+generator can be linked to replace the internal one.</li>
+
+<li><code>main25.cc</code> : shows how an external process can be
+implemented as a new class derived from a PYTHIA base class, and then
+handed in for generation as with a normal internal process.</li>
+
+<li><code>main26.cc</code> : shows how an external resonance can be
+implemented as a new class derived from a PYTHIA base class, and be
+used in an external process, both of which are then handed in for
+generation as with a normal internal resonance and process.</li>
+
+<li><code>main27.cc</code> : shows how an external beam momentum spread
+and vertex location generator can be implemented as a new class derived
+from a PYTHIA base class, and then handed in for internal use.</li>
+
+<li><code>main31.cc</code> : similar to main01, except that the
+event record is output in the HepMC event record format. Requires
+that HepMC is properly linked.</li>
+
+<li><code>main32.cc</code> : a streamlined version for the generation
+of events that are then stored in HepMC format, without any event
+analysis. That is, all physics studies will have to be done afterwards.
+The name of the input "cards file" (e.g. <code>main32.cmnd</code>)
+and output HepMC event file are to be provided as command-line arguments.
+Requires that HepMC is properly linked.</li>
+
+<li><code>main41.cc</code> : a test of the shape of parton densities,
+as a check prior to using a given PDF set in a generator. Requires
+that LHAPDF is properly linked.</li>
+
+<li><code>main42.cc</code> : compares the charged multiplicity
+distribution, and a few other minimum-bias physics aspects, between
+default PYTHIA PDF and another one. Requires that LHAPDF is properly
+linked.</li>
+
+<li><code>main51.cc</code> : a simple example how the Les Houches
+Accord interface, plus a few more Fortran-to-C++ commands, allows
+hard processes to be generated by PYTHIA 6.4 and then processed
+further by PYTHIA 8. Requires that PYTHIA 6.4 is properly linked.</li>
+
+<li><code>main52.cc</code> : a fairly extensive study of
+event properties, with hard processes generated by PYTHIA 6.4.
+It reads in a <code>main52.fcmnd</code> file with commands specfically
+for the Fortran PYTHIA 6.4 program and another <code>main52.ccmnd</code>
+file illustrating several of the settings listed on these pages.
+Requires that PYTHIA 6.4 is properly linked.</li>
+
+<li><code>main53.f</code> : a Fortran program (!) showing how
+PYTHIA 6.4 can be used to generate a Les Houches Event File
+<code>ttbar.lhe</code> with top events (which is used as input by
+<code>main12.cc</code>). This program can easily be modified to
+generate other files, bigger and/or for other processes.
+Requires that PYTHIA 6.4 is properly linked.</li>
+
+<li><code>main54.cc</code> : a final example where PYTHIA 6.4 is used
+to generate hard processes, which are directly input to be generated
+in full by the internal machinery, using the settings in
+<code>main54.cmnd</code>, and the output consists of a file with
+HepMC event records for further analysis. Requires that PYTHIA 6.4
+and HepMC are properly linked.</li>
+
+</ul>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Save Settings">
+
+<h2>Save Settings</h2>
+
+The information on this webpage is only valid if you access the PHP
+dynamic webpages via a web browser, and does not apply to the static
+HTML equivalents. With PHP, all of the settings in the PYTHIA program
+are represented by radio buttons or fill-in boxes, that makes it easy
+for you to construct a file with your desired changes. This file can
+then be read into PYTHIA by your main program to steer the whole run.
+
+<h3>Basic instructions</h3>
+
+The functionality of the PHP option is described in the following.
+
+<p/>
+<table border="2" cellpadding="5"><td>
+<PHPFILECODE/>
+</td></table>
+
+<ul>
+
+<p/><li>
+To begin with, you must specify a <b>(temporary) file name</b> in the
+box above. If the filename already exists on the server, you will be
+requested to pick a new name.</li>
+
+<p/><li>
+Once you have <b>Submit</b>ted your filename, you can browse through the
+pages and make your selections. The values currently selected when you
+load the page are the default values.</li>
+
+<p/><li>
+When you have finished making your changes to a particular page,
+you <b>must</b> click on <b>Save Settings</b> at the <b>bottom</b> of
+the page. This will write the changes to your temporary file. If you make
+a mistake, just repeat the procedure for that category again.<br>
+
+<p/><li>
+When you have finished all the changes you need, return to this page
+and click <b>Finish File</b>.</li>
+
+<p/><li>
+You will then get up a link, that you are asked to <b>right-click</b>
+with your mouse (or equivalent).</li>
+
+<p/><li>
+In the menu that appears, pick the option <b>Save Link As</b>
+(or equivalent).</li>
+
+<p/><li>
+You will now get up a file browser, for you to pick and <b>Save</b>
+the location and file name (the latter by default the same as the
+temporary file name).</li>
+
+<p/><li>
+At any time, if you click the <b>RESET</b> button, your temporary
+file will be erased and you can start anew.</li>
+
+<p/><li>
+Before you use a file, be sure to <b>check it visually</b> to confirm
+that you saved what you intended to. Minor corrections are easily made
+in a text editor.
+</li>
+
+</ul>
+
+<p/>
+<h3>Supplementary notes</h3>
+
+
+The documentation files exist in three versions.
+<ol>
+
+<p/><li>
+As a set of <code>.xml</code> files, in the <code>xmldoc/</code>
+subdirectory. These are the master copies that no user ever should
+touch, but that are used to generate the variants below.</li>
+
+<p/><li>
+As a set of <code>.html</code> files, in the <code>htmldoc/</code>
+subdirectory. You can open your own locally installed copy of the
+<code>Welcome.html</code> file in your web browser and thereafter
+navigate among all the pages. You can learn which parameters are free
+to be changed, but not change anything, except by brute-force
+cut-and-paste to a file of your own.</li>
+
+<p/><li>
+As a set of <code>.php</code> files, in the <code>phpdoc/</code>
+subdirectory. For these files to provide the functionality described
+above they have to accessed via a webserver. The one where you have
+your homepage should work fine. Alternatively you can use pages already
+available on another server.</li>
+
+</ol>
+
+<p/>
+A few further comments about the operation of the PHP option:
+<ul>
+
+<p/><li>
+To set up the PHP files on your webserver, you have to install the whole
+<code>phpdoc/</code> subdirectory there. In addition to the
+<code>.php</code> code this includes a few more files, plus a
+subdirectory named <code>files</code> where the temporary files
+are stored. This subdirectory must have public write access to work
+(<code>chmod a+w files</code> if not).</li>
+
+<p/><li>
+The "temporary" files stored in <code>files</code> actually remain
+unless the RESET button is used. The good news is that this makes
+it possible to recover a file that otherwise might be lost. The bad
+news is that the <code>files</code> directory may need to be cleaned
+up from time to time. (But typically the files are pretty small, so
+this should not be a major problem.)</li>
+
+<p/><li>
+When you click the <b>Save Settings</b> button on the bottom of a page
+all changed settings are written on the temporary file in the format
+<pre>
+name-of-flag/mode/parameter/word = value
+</pre>
+with one variable per line. Thereafter all the settings on the page
+are restored to their default values.</li>
+
+<p/><li>
+You can return to a page to do some further changes and save those.
+If you change the same parameter twice, it is the last value that
+counts. (Both values are stored in the file, with the more recent
+lower down, and then PYTHIA does the changes sequentially.) However
+remember that unchanged values are not stored, so if you want to
+restore some default value it may be simpler to edit the file
+afterwards.</li>
+
+<p/><li>
+The changeable flags/modes/parameters/words are mainly in the
+"Setup Run Tasks" section of the index, but a few (less
+frequently used ones) can also be found lower down, in the
+"Study Output" and "Link to Other Programs" pages.
+
+<p/><li>
+It is not (yet) possible to modify particle data within the PHP-based
+setup approach. This is a more difficult task, since e.g. the
+modifications one may want to do in a decay table can be quite
+interrelated.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Semi-Internal Processes">
+
+<h2>Semi-Internal Processes</h2>
+
+Normally users are expected to implement new processes via the
+<aloc href="LesHouchesAccord">Les Houches Accord</aloc>. Then
+you do all flavour, colour and phase-space selection externally,
+before your process-level events are input for further processing
+by PYTHIA. However, it is also possible to implement a
+new process in exactly the same way as the internal PYTHIA
+ones, thus making use of the internal phase space selection machinery
+to sample an externally provided cross-section expression.
+This page gives a brief summary how to do that. If you additionally
+want to introduce a new resonance species, with its own internal
+width calculations, you will find further instructions
+<aloc href="SemiInternalResonances">here</aloc>.
+
+<p/>
+Should you actually go ahead, it is strongly recommended to shop around
+for a similar process that has already been implemented, and to use that
+existing code as a template. Look for processes with the same combinations
+of incoming flavours and colour flows, rather than the shape of the
+cross section itself. With a reasonable such match the task should be
+of medium difficulty, without it more demanding.
+
+<p/>
+PYTHIA is rather good at handling the phase space of
+<ei>2 -> 1</ei> and <ei>2 -> 2</ei> processes, is more primitive for
+<ei>2 -> 3</ei> ones and does not at all address higher multiplicities.
+This limits the set of processes that you can implement in this
+framework. The produced particles may be resonances, however, so it is
+possible to end up with bigger "final" multiplicities through sequential
+decays, and to include further matrix-element weighting in those decays.
+
+<p/>
+There are two steps involved in implementing a process:
+<br/>1) writing a new class, where the matrix elements are implemented,
+including information on incoming and outgoing flavours and colours, and
+<br/>2) making the process available.
+<br/>We consider these two aspects in turn. An example where it all comes
+together is found in <code>main25.cc</code>.
+
+<h3>The Cross Section Class</h3>
+
+The matrix-element information has to be encoded in a new class.
+The relevant code could either be put before the main program in the
+same file, or be stored separately, e.g. in a matched pair
+of <code>.h</code> and <code>.cc</code> files. The latter may be more
+convenient, in particular if the cross sections are lengthy, or if you
+intend to build up your own little process library, but of course
+requires that these additional files are correctly compiled and linked.
+
+<p/>
+The class has to be derived either from
+<code>Sigma1Process</code>, for <ei>2 -> 1</ei> processes, from
+<code>Sigma2Process</code>, for <ei>2 -> 2</ei> ones, or from
+<code>Sigma3Process</code>, for <ei>2 -> 3</ei> ones. (The
+<code>Sigma0Process</code> class is used for elastic, diffractive
+and minimum-bias events, and is not recommended for use beyond that.)
+These are in their turn derived from the <code>SigmaProcess</code>
+base class.
+
+<p/>
+The class can implement a number of methods. Some of these are
+compulsory, others strongly recommended, and the rest are to be
+used only when the need arises to override the default behaviour.
+The methods are:
+
+<p/>
+A <b>constructor</b> for the derived class obviously must be available.
+Here you are quite free to allow a list of arguments, to set
+the parameters of your model, or even to create a set of closely
+related but distinct processes. For instance, <ei>g g -> Q Qbar</ei>,
+<ei>Q = c</ei> or <ei>b</ei>, is only coded once, and then the
+constructor takes the quark code (4 or 5) as argument,
+to allow the proper amount of differentiation.
+
+<p/>
+A <b>destructor</b> is only needed if you plan to delete the process
+before the natural end of the run, and require some special behaviour
+at that point. If you call such a destructor you will leave a pointer
+dangling inside the <code>Pythia</code> object you gave it in to,
+if that still exists.
+
+<method name="void initProc()">
+is called once during initalization, and can then be used to set up
+parameters, such as masses and couplings, and perform calculations
+that need not be repeated for each new event, thereby saving time.
+This method needs not be implemented, since in principle all
+calculations can be done in <code>sigmaHat</code> below.
+
+<method name="void sigmaKin()">
+is called once a kinematical configuration has been determined, but
+before the two incoming flavours are known. This routine can therefore
+be used to perform calculations that otherwise might have to be repeated
+over and over again in <code>sigmaHat</code> below. For instance
+a flavour-independent cross section calculation for a <ei>q g</ei>
+initial state would be repeated 20 times in <code>sigmaHat</code>,
+five times for the five quark flavours allowed in the incoming beams,
+times twice to include antiquarks, times twice since the (anti)quark
+could be in either of the two beams. You could therefore calculate the
+result once only and store it as a private data member of the class.
+It is optional whether you want to use this method, however, or put
+everything in <code>sigmaHat</code>.
+
+<method name="double sigmaHat()">
+is the key method for cross section calculations and returns a cross section
+value, as further described below. It is called when also a preliminary set
+of incoming flavours has been picked, in addition to the kinematical ones
+already available for <code>sigmaKin</code>. Typically <code>sigmaHat</code>
+is called inside a loop over all allowed incoming flavour combinations,
+stored in <code>id1</code> and <code>id2</code>, with fixed kinematics,
+as already illustrated above. The sum over the different flavour combinations
+provides the total cross section, while their relative size is used to make
+a selection of a specific incomimg state.
+<br/>For a <ei>2 -> 1</ei> process, the returned value should be
+<ei>sigmaHat(sHat)</ei>, where <code>mH</code> (= <ei>mHat</ei>),
+<code>sH</code> (= <ei>sHat</ei>) and <code>sH2</code> (= <ei>sHat^2</ei>)
+are available to be used.
+<br/>For a <ei>2 -> 2</ei> process, instead
+<ei>d(sigmaHat)/d(tHat)</ei> should be returned, based on
+provided <code>mH, sH, sH2, tH, tH2, uH, uH2, m3, s3, m4, s4</code> and
+<code>pT2</code> values (<code>s3 = m3*m3</code> etc.).
+<br/>For a <ei>2 -> 3</ei> process, instead <ei>|M|^2</ei> should be
+returned, with normalization such that <ei>|M|^2 / (2 sHat)</ei> integrated
+over the three-body phase space gives the cross section. Here no standard
+set of variables exist. Instead the obvious ones,
+<code>mH, sH, m3, s3, m4, s4, m5, s5</code>, are complemented by the
+four-vectors <code>p3cm, p4cm, p5cm</code>, from which further invariants
+may be calculated. The four-vectors are defined in the cm frame of the
+subcollision, with incoming partons along the <ei>+-z</ei> axis.
+<br/>In either case, <ei>alpha_s</ei> and <ei>alpha_em</ei> have already
+been calculated, and are stored in <code>alpS</code> and <code>alpEM</code>.
+Also other standard variables may be used, like
+<code>CoupEW::sin2thetaW()</code>, and related flavour-dependent
+vector and axial couplings in <code>CoupEW</code> and CKM combinations
+in <code>VCKM</code>.
+<br/>In case some of the final-state particles are resonances, their
+squared masses have already been selected according to a Breit-Wigner
+with a linearly running width <ei>Gamma(m) = Gamma(m_0) * m / m_0</ei>.
+More precisely, the mass spectrum is weighted according to
+<ei>w_BW(m^2) d(m^2)</ei>, where
+<eq>
+w_BW(m^2) = (1/pi) * (m * Gamma(m)) / ( (m^2 - m_0^2)^2 + (m * Gamma(m))^2 ) .
+</eq>
+If you would like to have another expression, the above weights are stored
+in <code>runBW3</code>, <code>runBW4</code> and <code>runBW5</code>,
+respectively. If you divide out one of these factors, you just remain with
+a phase space selection <ei>d(m^2)</ei> for this particle,
+and can multiply on your desired shape factor instead. Unfortunately, the
+Monte Carlo efficiency will drop if your new mass distribution differs
+dramatically from the input one. Therefore it does make sense to adjust the
+database value of the width to be slightly (but not too much) broader
+than the distribution you have in mind. Also note that, already by default,
+the wings of the Breit-Wigner are oversampled (with a compensating lower
+internal weight) by partly sampling like <ei>(a + b/m^2 + c/m^4) d(m^2)</ei>,
+where the last term is only used for <ei>gamma^*/Z^0</ei>.
+
+<method name="void setIdColAcol()">
+is called only once an initial state and a kinematical configuration has
+been picked. This routine must set the complete flavour information and
+the colour flow of the process. This may involve further random choices,
+between different possible final-state flavours or between possible
+competing colour flows. Private data members of the class may be used to
+retain some information from the previous steps above.
+<br/>When this routine is called the two incoming flavours have already
+been selected and are available in <code>id1</code> and <code>id2</code>,
+whereas the one, two or three outgoing ones either are fixed for a given
+process or can be determined from the instate (e.g. whether a <ei>W^+</ei>
+or <ei>W^-</ei> was produced). There is also a standard method in
+<code>VCKM</code> to pick a final flavour from an initial one with CKM
+mixing. Once you have figured out the value of
+<code>id3</code> and, the case being, <code>id4</code> and
+<code>id5</code>, you store these values permanently by a call
+<code>setId( id1, id2, id3, id4, id5)</code>, where the last two may be
+omitted if irrelevant.
+<br/>Correspondingly, the colours are stored with
+<code>setColAcol( col1, acol1, col2, acol2, col3, acol3, col4, acol4,
+col5, acol5)</code>, where the final ones may be omitted if irrelevant.
+Les Houches style colour tags are used, but starting with number 1
+(and later shifted by the currently requested offset). The
+input is grouped particle by particle, with the colour index before the
+anticolour one. You may need to select colour flow dynamically, depending
+on the kinematics, when several distinct possibilities exist. Trivial
+operations, like swapping colours and anticolours, can be done with
+existing methods.
+<br/>When the <code>id3Mass()</code> and <code>id4Mass()</code>
+methods have been used, the order of the outgoing particles may be
+inconsistent with the way the <ei>tHat</ei> and <ei>uHat</ei>
+variables have been defined. A typical example would be a process like
+<ei>q g -> q' W</ei> with <ei>tHat</ei> defined between incoming and
+outgoing quark, but where <code>id3Mass() = 24</code> and so the
+process is to be stored as <ei>q g -> W q'</ei>. One should then put
+the variable <code>swapTU = true</code> in <code>setIdColAcol()</code>
+for each event where the <ei>tHat</ei> and <ei>uHat</ei> variables
+should be swapped before the event kinematics is reconstructed. This
+variable is automatically restored to <code>false</code> for each new
+event.
+
+<method name="double weightDecayFlav( Event& process)">
+is called to allow a reweighting of the simultaneous flavour choices of
+resonance decay products. Is currently only used for the
+<ei>q qbar -> gamma*/Z^0 gamma*/Z^0</ei> process, and will likely not
+be of interest for you.
+
+<method name="double weightDecay( Event& process, int iResBeg, int iResEnd)">
+is called when the basic process has one or several resonances, after each
+set of related resonances in <code>process[i]</code>,
+<code>iResBeg</code> <= <code>i </code> <= <code>iResEnd</code>,
+has been allowed to decay. The calculated weight, to be normalized
+to the range between 0 and 1, is used to decide whether to accept the
+decay(s) or try for a new decay configuration. The base-class version of
+this method returns unity, i.e. gives isotropic decays by default.
+This method may be called repeatedly for a single event. For instance, in
+<ei>q qbar -> H^0 Z^0</ei> with <ei>H^0 -> W^+ W^-</ei>, a first call
+would be made after the <ei>H^0</ei> and <ei>Z^0</ei> decays, and then
+depend only on the <ei>Z^0</ei> decay angles since the <ei>H^0</ei>
+decays isotropically. The second call would be after the <ei>W^+ W^-</ei>
+decays and then involve correlations between the four daughter fermions.
+
+<method name="string name()">
+returns the name of the process, as you want it to be shown in listings.
+
+<method name="int code()">
+returns an integer identifier of the process. This has no internal function,
+but is only intended as a service for the user to rapidly (and hopefully
+uniquely) identify which process occured in a given event. Numbers below
+10000 are reserved for internal PYTHIA use.
+
+<method name="string inFlux()">
+this string specifies the combinations of incoming partons that are
+allowed for the process under consideration, and thereby which incoming
+flavours <code>id1</code> and <code>id2</code> the <code>sigmaHat()</code>
+calls will be looped over. It is always possible to pick a wider flavour
+selection than strictly required and then put to zero cross sections in
+the superfluous channels, but of course this may cost some extra execution
+time. Currently allowed options are:
+<br/>* <code>gg</code>: two gluons.
+<br/>* <code>qg</code>: one (anti)quark and one gluon.
+<br/>* <code>qq</code>: any combination of two quarks, two antiquarks or
+a quark and an antiquark.
+<br/>* <code>qqbarSame</code>: a quark and its antiquark;
+this is a subset of the above <code>qq</code> option.
+<br/>* <code>ff</code>: any combination of two fermions, two antifermions
+or a fermion and an antifermion; is the same as <code>qq</code> for
+hadron beams but also allows processes to work with lepton beams.
+<br/>* <code>ffbarSame</code>: a fermion and its antifermion; is the
+same as <code>qqbarSame</code> for hadron beams but also allows processes
+to work with lepton beams.
+<br/>* <code>ffbarChg</code>: a fermion and an antifermion that combine
+to give charge +-1.
+<br/>* <code>fgm</code>: a fermion and a photon (gamma).
+<br/>* <code>ggm</code>: a gluon and a photon.
+<br/>* <code>gmgm</code>: two photons.
+
+<method name="bool convert2mb()">
+it is assumed that cross sections normally come in dimensions such that
+they, when integrated over the relevant phase space, obtain the dimension
+GeV^-2, and therefore need to be converted to mb. If the cross section
+is already encoded as mb then <code>convert2mb()</code> should be
+overloaded to instead return <code>false</code>.
+
+<method name="int id3Mass(), int id4Mass(), int id5Mass()">
+are the one, two or three final-state flavours, where masses are to be
+selected before the matrix elements are evaluated. Only the absolute value
+should be given. For massless particles, like gluons and photons, one need
+not give anything, i.e. one defaults to 0. The same goes for normal light
+quarks, where masses presumably are not implemented in the matrix elements.
+Later on, these quarks can still (automatically) obtain constituent masses,
+once a <ei>u</ei>, <ei>d</ei> or <ei>s</ei> flavour has been selected.
+
+<method name="int resonanceA(), int resonanceB()">
+are the codes of up to two <ei>s</ei>-channel resonances contributing to
+the matrix elements. These are used by the program to improve the phase-space
+selection efficiency, by partly sampling according to the relevant
+Breit-Wigners. Massless resonances (the gluon and photon) need not be
+specified.
+
+<method name="bool isSChannel()">
+normally the choice of renormalization and factorization scales in
+<ei>2 -> 2</ei> and <ei>2 -> 3</ei> processes is based on the assumption
+that <ei>t</ei>- and <ei>u</ei>-channel exchanges dominates the
+cross section. In cases such as <ei>f fbar -> gamma* -> f' fbar'</ei> a
+<ei>2 -> 2</ei> process actually ought to be given scales as a
+<ei>2 -> 1</ei> one, in the sense that it proceeds entirely through
+an <ei>s</ei>-channel resonance. This can be achieved if you override the
+default <code>false</code> to return <code>true</code>. See further the
+page on <aloc href="CouplingsAndScales">couplings and scales</aloc>.
+
+<method name="int idTchan1(), int idTchan2()">
+the <ei>2 -> 3</ei> phase space selection machinery is rather primitive,
+as already mentioned. The efficiency can be improved in processes that
+proceed though <ei>t</ei>-channel exchanges, such as
+<ei>q qbar' -> H^0 q qbar'</ei> via <ei>Z^0 Z^0</ei> fusion, if the identity
+of the <ei>t</ei>-channel-exchanged particles on the two side of the
+event are provided. Only the absolute value is of interest.
+
+<method name="double tChanFracPow1(), double tChanFracPow2()">
+in the above kind of <ei>2 -> 3</ei> phase-space selection, the
+sampling of <ei>pT^2</ei> is done with one part flat, one part weighted
+like <ei>1 / (pT^2 + m_R^2)</ei> and one part like
+<ei>1 / (pT^2 + m_R^2)^2</ei>. The above values provide the relative
+amount put in the latter two channels, respectively, with the first
+obtaining the rest. Thus the sum of <code>tChanFracPow1()</code> and
+<code>tChanFracPow2()</code> must be below unity. The final results
+should be independent of these numbers, but the Monte Carlo efficiency
+may be quite low for a bad choice. Here <ei>m_R</ei> is the mass of the
+exchanged resonance specified by <code>idTchan1()</code> or
+<code>idTchan2()</code>. Note that the order of the final-state
+listing is important in the above <ei>q qbar' -> H^0 q qbar'</ei> example,
+i.e. the <ei>H^0</ei> must be returned by <code>id3Mass()</code>,
+since it is actually the <ei>pT^2</ei> of the latter two that are
+selected independently, with the first <ei>pT</ei> then fixed
+by transverse-momentum conservation.
+
+<method name="useMirrorWeight()">
+in <ei>2 -> 3</ei> processes the phase space selection used here
+involves a twofold ambiguity basically corresponding to a flipping of
+the positions of last two outgoing particles. These are assumed equally
+likely by default, <code>false</code>, but for processes proceeding entirely
+through <ei>t</ei>-channel exchange the Monte Carlo efficiency can be
+improved by making a preselection based on the relative propagator
+weights, <code>true</code>.
+
+<method name="int gmZmode()">
+allows a possibility to override the global mode
+<aloc href="ElectroweakProcesses"><code>WeakZ0:gmZmode</code></aloc>
+for a specific process. The global mode normally is used to switch off
+parts of the <ei>gamma^*/Z^0</ei> propagator for test purposes. The
+above local mode is useful for processes where a <ei>Z^0</ei> really is
+that and nothing more, such as <ei>q qbar -> H^0 Z^0</ei>. The default
+value -1 returned by <code>gmZmode()</code> ensures that the global
+mode is used.
+
+<h3>Access to a process</h3>
+
+Once you have implemented a class, it is straightforward to make use of
+it in a run. Assume you have written a new class <code>MySigma</code>,
+which inherits from <code>Sigma1Process</code>, <code>Sigma2Process</code>
+or <code>Sigma3Process</code>, which in their turn inherit from
+<code>SigmaProcess</code>. You then create an instance of this class
+and hand it in to a <code>pythia</code> object with
+<pre>
+ SigmaProcess* mySigma = new MySigma();
+ pythia.setSigmaPtr( mySigma);
+</pre>
+If you have several processes you can repeat the procedure any number
+of times. When <code>pythia.init(...)</code> is called these processes
+are initialized along with any internal processes you may have switched on,
+and treated in exactly the same manner. The <code>pythia.next()</code>
+will therefore generate a mix of the different kinds of processes without
+distinction. See also the <aloc href="ProgramFlow">Program Flow</aloc>
+description.
+
+<p/>
+If the code should be of good quality and general usefulness, it would
+be simple to include it as a permanently available process in the
+standard program distribution. The final step of that integration ought to
+be left for the PYTHIA authors, but here is a description of what is
+required.
+
+<p/>
+A flag has to be defined, that allows the process to be switched on;
+by default it should always be off. The name of the flag should be
+chosen of the type <code>model:process</code>. Here the
+<code>model</code> would be related to the general scenario considered,
+e.g. <code>Compositeness</code>, while <code>process</code> would
+specify instate and outstate, separated by a 2 (= to), e.g.
+<code>ug2u*g</code>.
+When several processes are implemented and "belong together" it is
+also useful to define a <code>model:all</code> switch that affects
+all the separate processes.
+
+<p/>
+The flags should normally be stored in the <code>ProcessSelection.xml</code>
+file or one of its daughters for a specific kind of processes. This is to
+make them easily found by users. You could create and use your own
+<code>.xml</code> file, so long as you then add that name to the
+list of files in the <code>Index.xml</code> file. (If not,
+the flags would never be created and the program would not work.)
+
+<p/>
+In the <code>ProcessContainer.c</code> file, the
+<code>SetupContainers::init()</code> method needs to be expanded to
+create instances of the processes switched on. This code is fairly
+repetitive, and should be easy to copy and modify from the code
+already there. The basic structure is
+<br/>(i) check whether a process is requested by the user and, if so,
+<br/>(ii) create an instance of the matrix-element class,
+<br/>(iii)create a container for the matrix element and its associated
+phase-space handling, and
+<br>(iv) add the container to the existing process list.
+
+<p/>
+Two minor variations are possible. One is that a set of related
+processes are lumped inside the the same initial check, i.e. are
+switched on all together. The second is that the matrix-element
+constructor may take arguments, as specified by you (see above).
+If so, the same basic matrix element may be recycled for a set of
+related processes, e.g. one for a composite <ei>u</ei> and one for
+a composite <ei>d</ei>. Obviously these variations may be combined.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Semi-Internal Resonances">
+
+<h2>Semi-Internal Resonances</h2>
+
+The introduction of a new <aloc href="SemiInternalProcesses">
+semi-internal process</aloc> may also involve a new particle,
+not currently implemented in PYTHIA. Often it is then enough to
+use the <aloc href="ParticleDataScheme">standard machinery</aloc>
+to introduce a new particle (<code>id:all = ...</code>) and new
+decay channels (<code>id:addChannel = ...</code>). By default this
+only allows you to define a fixed total width and fixed branching
+ratios. Using <aloc href="ResonanceDecays"><code>meMode</code></aloc>
+values 100 or bigger provides the possibility of a very
+simple threshold behaviour.
+
+<p/>
+If you want to have complete freedom, however, there are two
+ways to go. One is that you make the resonance decay part of the
+hard process itself, either using the
+<aloc href="LesHouchesAccord">Les Houches interface</aloc> or
+a semi-internal process. The other is for you to create a new
+<code>ResonanceWidths</code> object, where you write the code
+needed for a calculation of the partial width of a particular
+channel.
+
+<p/>
+Here we will explain what is involved in setting up a resonance.
+Should you actually go ahead with this, it is strongly recommended
+to use an existing resonance as a template, to get the correct
+structure. There also exists a sample main program,
+<code>main26.cc</code>, that illustrates how you could combine
+a new process and a new resonance.
+
+<p/>
+There are three steps involved in implementing a new resonance:
+<br/>1) providing the standard particle information, as already
+outlined above (<code>id:all = ...</code>,
+<code>id:addChannel = ...</code>), except that now branching
+ratios need not be specified, since they anyway will be overwritten
+by the dynamically calculated values.
+<br/>2) writing the class that calculates the partial widths.
+<br/>3) handing in a pointer to an instance of this class to PYTHIA.
+<br/>We consider the latter two aspects in turn.
+
+<h3>The ResonanceWidths Class</h3>
+
+The resonance-width calculation has to be encoded in a new class.
+The relevant code could either be put before the main program in the
+same file, or be stored separately, e.g. in a matched pair
+of <code>.h</code> and <code>.cc</code> files. The latter may be more
+convenient, in particular if the calculations are lengthy, or
+likely to be used in many different runs, but of course requires
+that these additional files are correctly compiled and linked.
+
+<p/>
+The class has to be derived from the <code>ResonanceWidths</code>
+base class. It can implement a number of methods. The constructor
+and the <code>calcWidth</code> ones are always needed, while others
+are for convenience. Much of the administrativ machinery is handled
+by methods in the base class.
+
+<p/>Thus, in particular, you must implement expressions for all
+possible final states, whether switched on in the current run or not,
+since all contribute to the total width needed in the denominator of
+the Breit-Wigner expression. Then the methods in the base class take
+care of selecting only allowed channels where that is required, and
+also of including effects of closed channels in secondary decays.
+These methods can be accessed indirectly via the
+<aloc href="ResonanceDecays"><code>res...</code></aloc>
+methods of the normal particle database.
+
+<p/>
+A <b>constructor</b> for the derived class obviously must be available.
+Here you are quite free to allow a list of arguments, to set
+the parameters of your model. The constructor must call the
+base-class <code>initBasic(idResIn)</code> method, where the argument
+<code>idResIn</code> is the PDG-style identity code you have chosen
+for the new resonance. When you create several related resonances
+as instances of the same class you would naturally make
+<code>idResIn</code> an argument of the constructor; for the
+PYTHIA classes this convention is used also in cases when it is
+not needed.
+<br/>The <code>initBasic(...)</code> method will
+hook up the <code>ResonanceWidths</code> object with the corresponding
+entry in the generic particle database, i.e. with the normal particle
+information you set up in point 1) above. It will store, in base-class
+member variables, a number of quantities that you later may find useful:
+<br/><code>idRes</code> : the identity code you provide;
+<br/><code>hasAntiRes</code> : whether there is an antiparticle;
+<br/><code>mRes</code> : resonance mass;
+<br/><code>GammaRes</code> resonance width;
+<br/><code>m2Res</code> : the squared mass;
+<br/><code>GamMRat</code> : the ratio of width to mass.
+
+<p/>
+A <b>destructor</b> is only needed if you plan to delete the resonance
+before the natural end of the run, and require some special behaviour
+at that point. If you call such a destructor you will leave a pointer
+dangling inside the <code>Pythia</code> object you gave it in to,
+if that still exists.
+
+<method name="void initConstants()">
+is called once during initialization, and can then be used to set up
+further parameters specific to this particle species, such as couplings,
+and perform calculations that need not be repeated for each new event,
+thereby saving time. This method needs not be implemented.
+
+<method name="void calcPreFac(bool calledFromInit = false)">
+is called once a mass has been chosen for the resonance, but before
+a specific final state is considered. This routine can therefore
+be used to perform calculations that otherwise might have to be repeated
+over and over again in <code>calcWidth</code> below. It is optional
+whether you want to use this method, however, or put
+everything in <code>calcWidth()</code>.
+<br/>The optional argument will have the value <code>true</code> when
+the resonance is initialized, and then be <code>false</code> throughout
+the event generation, should you wish to make a distinction.
+In PYTHIA such a distinction is made for <ei>gamma^*/Z^0</ei> and
+<ei>gamma^*/Z^0/Z'^0</ei>, owing to the necessity of a special
+description of interference effects, but not for other resonances.
+<br/>In addition to the base-class member variables already described
+above, <code>mHat</code> contains the current mass of the resonance.
+At initialization this agrees with the nominal mass <code>mRes</code>,
+but during the run it will not (in general).
+
+<method name="void calcWidth(bool calledFromInit = false)">
+is the key method for width calculations and returns a partial width
+value, as further described below. It is called for a specific
+final state, typically in a loop over all allowed final states,
+subsequent to the <code>calcPreFac(...)</code> call above.
+Information on the final state is stored in a number of base-class
+variables, for you to use in your calculations:
+<br/><code>iChannel</code> : the channel number in the list of
+possible decay channels;
+<br/><code>mult</code> : the number of decay products;
+<br/><code>id1, id2, id3</code> : the identity code of up to the first
+three decay products, arranged in descending order of the absolute value
+of the identity code;
+<br/><code>id1Abs, id2Abs, id3Abs</code> : the absolute value of the
+above three identity codes;
+<br/><code>mHat</code> : the current resonance mass, which is the same
+as in the latest <code>calcPreFac(...)</code> call;
+<br/><code>mf1, mf2, mf3</code> : masses of the above decay products;
+<br/><code>mr1, mr2, mr3</code> : squared ratio of the product masses
+to the resonance mass;
+<br/><code>ps</code> : is only meaningful for two-body decays, where it
+gives the phase-space factor
+<ei>ps = sqrt( (1. - mr1 - mr2)^2 - 4. * mr1 * mr2 )</ei>;
+<br/>In two-body decays the third slot is zero for the above properties.
+Should there be more than three particles in the decay, you would have
+to take care of the subsequent products yourself, e.g. using
+<br/><code>particlePtr->decay[iChannel].product(j);</code>
+<br/>to extract the <code>j</code>'th decay products (with
+<code>j = 0</code> for the first, etc.). Currently we are not aware
+of any such examples.
+<br/>The base class also contains methods for <ei>alpha_em</ei> and
+<ei>alpha_strong</ei> evaluation, and can access many standard-model
+couplings; see the existing code for examples.
+<br/>The result of your calculation should be stored in
+<br/><code>widNow</code> : the partial width of the current channel,
+expressed in GeV.
+
+<method name="double widthChan( mHat, idAbs1, idAbs2)">
+is not normally used. In PYTHIA the only exception is Higgs decays,
+where it is used to define the width (except for colour factors)
+associated with a specific incoming state. It allows the results of
+some loop expressions to be pretabulated.
+
+
+<h3>Access to resonance widths</h3>
+
+Once you have implemented a class, it is straightforward to
+make use of it in a run. Assume you have written a new class
+<code>MyResonance</code>, which inherits from
+<code>ResonanceWidths</code>. You then create an instance of
+this class and hand it in to a <code>pythia</code> object with
+<pre>
+ ResonanceWidths* myResonance = new MyResonance();
+ pythia.setResonancePtr( myResonance);
+</pre>
+If you have several resonances you can repeat the procedure any number
+of times. When <code>pythia.init(...)</code> is called these resonances
+are initialized along with all the internal resonances, and treated in
+exactly the same manner. See also the <aloc href="ProgramFlow">Program
+Flow</aloc>
+description.
+
+<p/>
+If the code should be of good quality and general usefulness,
+it would be simple to include it as a permanently available process
+in the standard program distribution. The final step of that integration
+ought to be left for the PYTHIA authors, but basically all that is
+needed is to add one line in
+<code>ParticleDataTable::initResonances</code>, where one creates an
+instance of the resonance in the same way as for the resonances already
+there. In addition, the particle data and decay table for the new
+resonance has to be added to the permanent
+<aloc href="ParticleData">particle database</aloc>, and the code itself
+to <code>include/ResonanceWidths.h</code> and
+<code>src/ResonanceWidths.cc</code>.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="The Settings Scheme">
+
+<h2>The Settings Scheme</h2>
+
+The <code>Settings</code> class keeps track of all the flags, modes,
+parameters and words in the program. As such, it serves the other program
+elements from one central repository. Accessing it allows the user to
+modify the behaviour of the program. The <code>Settings</code> class is
+purely static, i.e. you can interact with it directly by
+<code>Settings::command(argument)</code>.
+However, a <code>settings</code> object of the <code>Settings</code> class
+is a public member of the <code>Pythia</code> class, so an alternative
+notation would be <code>pythia.settings.command(argument)</code>,
+assuming that <code>pythia</code> is an instance of the <code>Pythia</code>
+class. Further, for the most frequent user tasks, <code>Pythia</code>
+methods have been defined, so that <code>pythia.command(argument)</code>
+would work, see further below.
+
+<h3>Concepts</h3>
+
+We distinguish four kinds of user-modifiable variables, by the way
+they have to be stored:
+<ol>
+<li>Flags are on/off switches, and are stored as <code>bool</code>.</li>
+<li>Modes corresponds to a finite enumeration of separate options,
+ and are stored as <code>int</code>.</li>
+<li>Parameters take a continuum of values, and are stored as
+<code>double</code>. The shorthand notation parm is used in the C++
+code and XML tags, so that all four kinds are represented by
+four-letter type names.</li>
+<li>Words are simple character strings and are stored as
+<code>string</code>. No blanks or double quotation marks (") may
+appear inside a word, the former to simplify parsing of an input file
+and the latter not to cause conflicts with XML attribute delimiters.
+Currently the main application is to store file names.</li>
+</ol>
+
+<p/>
+In general, each variable stored in <code>Settings</code> is associated
+with four kinds of information:
+<ul>
+<li>The variable name, of the form <code>class:name</code>
+(or <code>file:name</code>, usually these agree), e.g.
+<code>TimeShower:pTmin</code>. The class/file part usually identifies
+the <code>.xml</code> file where the variable is defined, and the part of
+the program where it is used, but such a connection cannot be strictly
+upheld, since e.g. the same variable may be used in a few different
+cases (even if most of them are not).</li>
+<li>The default value, set in the original declaration, and intended
+to represent a reasonable choice.</li>
+<li>The current value, which differs from the default when the user so
+requests.</li>
+<li>An allowed range of values, represented by meaningful
+minimum and maximum values. This has no sense for a <code>flag</code>
+or a <code>word</code> (and is not used there), is usually rather
+well-defined for a <code>mode</code>, but less so for a <code>parm</code>.
+Often the allowed range exaggerates the degree of our current knowledge,
+so as not to restrict too much what the user can do. One may choose
+not to set the lower or upper limit, in which case the range is
+open-ended.</li>
+</ul>
+
+<p/>
+Technically, the <code>Settings</code> class is implemented with the
+help of four separate maps, one for each kind of variable, with the
+variable <code>name</code> used as key.
+
+<h3>Operation</h3>
+
+The normal flow of setting values is:
+
+<ol>
+
+<p/> <li>
+When a <code>Pythia</code> object <code>pythia </code>is created,
+the member <code>pythia.settings</code> is asked to scan the files
+listed in the <code>Index.xml</code> file in the <code>xmldoc</code>
+subdirectory.
+
+<p/>
+In all of the files scanned, lines beginning with
+<code><flag</code>, <code><mode</code>, <code><parm</code>
+or <code><word</code> are identified, and the information on
+such a line is used to define a new flag, mode, parameter or word.
+To exemplify, consider a line
+<pre>
+<parm name="TimeShower:pTmin" default="0.5" min="0.1" max="2.0">
+</pre>
+which appears in the <code>TimeShower.xml</code> file, and there
+defines a parameter <code>TimeShower:pTmin</code> with default value
+0.5 GeV and allowed variation in the range 0.1 - 2.0 GeV. The min
+and max values are optional.
+<note>Important:</note> the values in the <code>.xml</code> files should
+not be changed, except by the PYTHIA authors. Any changes should be
+done with the help of the methods described below.
+</li>
+
+<p/> <li>
+Between the creation of the <code>Pythia</code> object and the
+<code>init</code> call for it, you may use several alternative
+methods to modify some of the default values.
+
+<p/>
+a) Inside your main program you can directly set values with
+<pre>
+ pythia.readString(string)
+</pre>
+where both the variable name and the value are contained inside
+the character string, separated by blanks and/or a =, e.g.
+<pre>
+ pythia.readString("TimeShower:pTmin = 1.0");
+</pre>
+The match of the name to the database is case-insensitive. Names
+that do not match an existing variable are ignored. A warning is
+printed, however, unless an optional second argument <code>false</code>
+is used. Strings beginning with a non-alphanumeric character, like
+# or !, are assumed to be comments and are not processed at all.
+Values below the minimum or above the maximum are set at
+the respective border. For <code>bool</code> values, the following
+notation may be used interchangeably:
+<code>true = on = yes = ok = 1</code>, while everything else gives
+<code>false</code> (including but not limited to
+<code>false</code>, <code>off</code>, <code>no</code> and 0).<br/>
+
+<p/>
+b) The <code>Pythia</code> <code>readString(string)</code> method
+actually does not do changes itself, but sends on the string either
+to the <code>Settings</code> class or to <code>ParticleData</code>.
+If desired, it is possible to communicate
+directly with the corresponding <code>Settings</code> method:
+<pre>
+ pythia.settings.readString("TimeShower:pTmin = 1.0");
+</pre>
+In this case, changes intended for <code>ParticleData</code>
+would not be understood.
+
+<p/>
+c) Underlying the <code>settings.readString(string)</code> method are
+the settings-type-sensitive commands in the <code>Settings</code>, that
+are split by names containing <code>flag</code>, <code>mode</code>,
+<code>parm</code> or <code>word</code>. Thus, the example now reads
+<pre>
+ pythia.settings.parm("TimeShower:pTmin", 1.0);
+</pre>
+Boolean values should here be given as <code>true</code> or
+<code>false</code> i.e. there is less flexibility in the lower-level
+methods.
+
+<p/>
+At the same level, there are several different methods available.
+We here show the ones for <code>mode</code>, but corresponding methods
+exist for <code>flag</code>, <code>parm</code> and <code>word</code>,
+with obvious restrictions where <code>min</code> and <code>max</code>
+are not defined. Again name comparisons are case-insensitive.
+<method name="mode( name)">
+gives the current value,
+</method>
+<method name="mode( name, value)">
+sets the current value,
+</method>
+<method name="isMode( name)">
+tells whether a mode has been defined or not,
+</method>
+<method name="addMode( name, default, min, max)">
+defines a new mode,
+</method>
+<method name="forceMode( name, value)">
+sets the value, also when outside the recommended bounds (and it is
+completely up to you to face the consequences),
+</method>
+<method name="resetMode( name)">
+resets the current value to the default one.
+</method>
+
+<p/>
+Normally the user should have no need for these methods. The
+main exception is when some of the variables defined on the
+<aloc href="MainProgramSettings">Main-Program Settings</aloc>
+page are used to set run-specific information
+(like the CM energy or the number of events to generate) in an external
+file (see 2d below) and these variables are to be read into the main
+program. Then the <code>flag(name)</code>, <code>mode(name)</code>
+<code>parm(name)</code> and <code>word(name)</code> methods are to
+be used, see e.g. the main programs in the <code>examples</code>
+subdirectory to find out how it works.
+
+<p/>
+d) A simpler and more useful way is to collect all your changes
+in a separate file, with one line per change, e.g.
+<pre>
+ TimeShower:pTmin = 1.0
+</pre>
+Each line is read in as a string and processed with the methods already
+introduced.
+
+The file can be read by the
+<pre>
+ pythia.readFile(fileName);
+</pre>
+method. The file can freely mix commands to the <code>Settings</code>
+and <code>ParticleData</code> classes, and so is preferable. Lines with
+settings are handled by calls to the
+<code>pythia.settings.readString(string)</code> method. Again, an optional
+second argument <code>false</code> allows you to switch off warning
+messages for unknown variables.
+</li>
+
+<p/> <li>
+In the <code>Pythia init</code> call, many of the various other program
+elements are initialized, making use of the current values in the database.
+Once initialized, the common <code>Settings</code> database is likely not
+consulted again by these routines. It is therefore not productive to do
+further changes in mid-run: at best nothing changes, at worst you may
+set up inconsistencies.
+
+<p/>
+A routine <code>reInit(fileName)</code> is provided, and can be used to
+zero all the maps and reinitialize from scratch. Such a call might be
+required if several <code>Pythia</code> objects are created in the same run,
+and requested to have different values - by default the <code>init()</code>
+call is only made the first time. However, a more economical solution
+is then offered by <code>resetAll()</code>, which sets all variables to
+their default values.
+</li>
+
+<p/> <li>
+You may at any time obtain a listing of all variables in the
+database by calling
+<pre>
+ pythia.settings.listAll();
+</pre>
+The listing is strictly alphabetical, which at least means that names
+from the same file are kept together, but otherwise may not be so
+well-structured: important and unimportant ones will appear mixed.
+A more relevant alternative is
+<pre>
+ pythia.settings.listChanged();
+</pre>
+where you will only get those variables that differ from their
+defaults. Or you can use
+<pre>
+ pythia.settings.list("string");
+</pre>
+where only those variables with names that contain the string
+(case-insensitive match) are listed. Thus, with a string
+<code>shower</code>, the shower-related variables would be shown.
+</li>
+
+<p/> <li>
+The above listings are in a tabular form that cannot be read
+back in. Assuming you want to save all changed settings (maybe because
+you read in changes from several files), you can do that by calling
+<pre>
+ pythia.settings.writeFile(fileName);
+</pre>
+This file could then directly be read in by
+<code>readFile(fileName)</code> in a subsequent (identical) run.
+A second argument <code>true</code> would print all settings, not
+only the changed ones. Further, the first argument can be replaced by
+(a reference to) an <code>ostream</code>, by default <code>cout</code>.
+</li>
+</ol>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Spacelike Showers">
+
+<h2>Spacelike Showers</h2>
+
+The PYTHIA algorithm for spacelike initial-state showers is
+based on the recent article <ref>Sjo05</ref>, where a
+transverse-momentum-ordered backwards evolution scheme is introduced.
+This algorithm is a further development of the virtuality-ordered one
+presented in <ref>Sj085</ref>, with matching to first-order matrix
+element for <ei>Z^0</ei>, <ei>W^+-</ei> and Higgs (in the
+<ei>m_t -> infinity</ei> limit) production as introduced in
+<ref>Miu99</ref>.
+
+<p/>
+The normal user is not expected to call <code>SpaceShower</code>
+directly, but only have it called from <code>Pythia</code>,
+via <code>PartonLevel</code>. Some of the parameters below,
+in particular <code>SpaceShower:alphaSvalue</code>,
+would be of interest for a tuning exercise, however.
+
+<h3>Main variables</h3>
+
+The maximum <ei>pT</ei> to be allowed in the shower evolution is
+related to the nature of the hard process itself. It involves a
+delicate balance between not doublecounting and not leaving any
+gaps in the coverage. The best procedure may depend on information
+only the user has: how the events were generated and mixed (e.g. with
+Les Houches Accord external input), and how they are intended to be
+used. Therefore a few options are available, with a sensible default
+behaviour.
+
+<modepick name="SpaceShower:pTmaxMatch" default="0" min="0" max="2">
+Way in which the maximum shower evolution scale is set to match the
+scale of the hard process itself.
+<option value="0"><b>(i)</b> if the final state of the hard process
+(not counting subsequent resonance decays) contains at least one quark
+(<ei>u, d, s, c ,b</ei>), gluon or photon then <ei>pT_max</ei>
+is chosen to be the factorization scale for internal processes
+and the <code>scale</code> value for Les Houches input;
+<b>(ii)</b> if not, emissions are allowed to go all the way up to
+the kinematical limit.
+The reasoning is that in the former set of processes the ISR
+emission of yet another quark, gluon or photon could lead to
+doublecounting, while no such danger exists in the latter case.
+</option>
+<option value="1">always use the factorization scale for an internal
+process and the <code>scale</code> value for Les Houches input,
+i.e. the lower value. This should avoid doublecounting, but
+may leave out some emissions that ought to have been simulated.
+</option>
+<option value="2">always allow emissions up to the kinematical limit.
+This will simulate all possible event topologies, but may lead to
+doublecounting.
+</option>
+<note>Note 1:</note> These options only apply to the hard interaction.
+Emissions off subsequent multiple interactions are always constrainted
+to be below the factorization scale of the process itself.
+<note>Note 2:</note> Some processes contain matrix-element matching
+to the first emission; this is the case notably for single
+<ei>gamma^*/Z^0, W^+-</ei> and <ei>H^0</ei> production. Then default
+and option 2 give the correct result, while option 1 should never
+be used.
+</modepick>
+
+<parm name="SpaceShower:pTmaxFudge" default="1.0" min="0.5" max="2.0">
+In cases where the above <code>pTmaxMatch</code> rules would imply
+that <ei>pT_max = pT_factorization</ei>, <code>pTmaxFudge</code>
+introduced a multiplicative factor <ei>f</ei> such that instead
+<ei>pT_max = f * pT_factorization</ei>. Only applies to the hardest
+interaction in an event. It is strongly suggested that <ei>f = 1</ei>,
+but variations around this default can be useful to test this assumption.
+</parm>
+
+<modepick name="SpaceShower:pTdampMatch" default="0" min="0" max="2">
+These options only take effect when a process is allowed to radiate up
+to the kinematical limit by the above <code>pTmaxMatch</code> choice,
+and no matrix-element corrections are available. Then, in many processes,
+the fall-off in <ei>pT</ei> will be too slow by one factor of <ei>pT^2</ei>.
+That is, while showers have an approximate <ei>dpT^2/pT^2</ei> shape, often
+it should become more like <ei>dpT^2/pT^4</ei> at <ei>pT</ei> values above
+the scale of the hard process. Whether this actually is the case
+depends on the particular process studied, e.g. if <ei>t</ei>-channel
+gluon exchange is likely to dominate. If so, the options below could
+provide a reasonable high-<ei>pT</ei> behaviour without requiring
+higher-order calculations.
+<option value="0">emissions go up to the kinematical limit,
+with no special dampening.
+</option>
+<option value="1">emissions go up to the kinematical limit,
+but dampened by a factor <ei>k^2 Q^2_fac/(pT^2 + k^2 Q^2_fac)</ei>,
+where <ei>Q_fac</ei> is the factorization scale and <ei>k</ei> is a
+multiplicative fudge factor stored in <code>pTdampFudge</code> below.
+</option>
+<option value="2">emissions go up to the kinematical limit,
+but dampened by a factor <ei>k^2 Q^2_ren/(pT^2 + k^2 Q^2_ren)</ei>,
+where <ei>Q_ren</ei> is the renormalization scale and <ei>k</ei> is a
+multiplicative fudge factor stored in <code>pTdampFudge</code> below.
+</option>
+<note>Note:</note> These options only apply to the hard interaction.
+Emissions off subsequent multiple interactions are always constrainted
+to be below the factorization scale of the process itself.
+</modepick>
+
+<parm name="SpaceShower:pTdampFudge" default="1.0" min="0.25" max="4.0">
+In cases 1 and 2 above, where a dampening is imposed at around the
+factorization or renormalization scale, respectively, this allows the
+<ei>pT</ei> scale of dampening of radiation by a half to be shifted
+by this factor relative to the default <ei>Q_fac</ei> or <ei>Q_ren</ei>.
+This number ought to be in the neighbourhood of unity, but variations
+away from this value could do better in some processes.
+</parm>
+
+<p/>
+The amount of QCD radiation in the shower is determined by
+<parm name="SpaceShower:alphaSvalue" default="0.127" min="0.06" max="0.25">
+The <ei>alpha_strong</ei> value at scale <code>M_Z^2</code>.
+Default value is picked equal to the one used in CTEQ 5L.
+</parm>
+
+<p/>
+The actual value is then regulated by the running to the scale
+<ei>pT^2</ei>, at which it is evaluated
+<modepick name="SpaceShower:alphaSorder" default="1" min="0" max="2">
+Order at which <ei>alpha_strong</ei> runs,
+<option value="0">zeroth order, i.e. <ei>alpha_strong</ei> is kept
+fixed.</option>
+<option value="1">first order, which is the normal value.</option>
+<option value="2">second order. Since other parts of the code do
+not go to second order there is no strong reason to use this option,
+but there is also nothing wrong with it.</option>
+</modepick>
+
+<p/>
+QED radiation is regulated by the <ei>alpha_electromagnetic</ei>
+value at the <ei>pT^2</ei> scale of a branching.
+
+<modepick name="SpaceShower:alphaEMorder" default="1" min="-1" max="1">
+The running of <ei>alpha_em</ei>.
+<option value="1">first-order running, constrained to agree with
+<code>StandardModel:alphaEMmZ</code> at the <ei>Z^0</ei> mass.
+</option>
+<option value="0">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed at its value at vanishing momentum transfer.</option>
+<option value="-1">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed, but at <code>StandardModel:alphaEMmZ</code>, i.e. its value
+at the <ei>Z^0</ei> mass.
+</option>
+</modepick>
+
+<p/>
+There are two complementary ways of regularizing the small-<ei>pT</ei>
+divergence, a sharp cutoff and a smooth dampening. These can be
+combined as desired but it makes sense to coordinate with how the
+same issue is handled in multiple interactions.
+
+<flag name="SpaceShower:samePTasMI" default="on">
+Regularize the <ei>pT -> 0</ei> divergence using the same sharp cutoff
+and smooth dampening parameters as used to describe multiple interactions.
+That is, the <code>MultipleInteractions:pT0Ref</code>,
+<code>MultipleInteractions:ecmRef</code>,
+<code>MultipleInteractions:ecmPow</code> and
+<code>MultipleInteractions:pTmin</code> parameters are used to regularize
+all ISR QCD radiation, rather than the corresponding parameters below.
+This is a sensible physics ansatz, based on the assumption that colour
+screening effects influence both MI and ISR in the same way. Photon
+radiation is regularized separately in either case.
+<note>Warning:</note> if a large <code>pT0</code> is picked for multiple
+interactions, such that the integrated interaction cross section is
+below the nondiffractive inelastic one, this <code>pT0</code> will
+automatically be scaled down to cope. Information on such a rescaling
+does NOT propagate to <code>SpaceShower</code>, however.
+</flag>
+
+<p/>
+The actual <code>pT0</code> parameter used at a given cm energy scale,
+<ei>ecmNow</ei>, is obtained as
+<eq>
+ pT0 = pT0(ecmNow) = pT0Ref * (ecmNow / ecmRef)^ecmPow
+</eq>
+where <ei>pT0Ref</ei>, <ei>ecmRef</ei> and <ei>ecmPow</ei> are the
+three parameters below.
+
+<parm name="SpaceShower:pT0Ref" default="2.2"
+min="0.5" max="10.0">
+Regularization of the divergence of the QCD emission probability for
+<ei>pT -> 0</ei> is obtained by a factor <ei>pT^2 / (pT0^2 + pT^2)</ei>,
+and by using an <ei>alpha_s(pT0^2 + pT^2)</ei>. An energy dependence
+of the <ei>pT0</ei> choice is introduced by the next two parameters,
+so that <ei>pT0Ref</ei> is the <ei>pT0</ei> value for the reference
+cm energy, <ei>pT0Ref = pT0(ecmRef)</ei>.
+</parm>
+
+<parm name="SpaceShower:ecmRef" default="1800.0" min="1.">
+The <ei>ecmRef</ei> reference energy scale introduced above.
+</parm>
+
+<parm name="SpaceShower:ecmPow" default="0.16" min="0." max="0.5">
+The <ei>ecmPow</ei> energy rescaling pace introduced above.
+</parm>
+
+<parm name="SpaceShower:pTmin" default="0.2"
+min="0.1" max="10.0">
+Lower cutoff in <ei>pT</ei>, below which no further ISR branchings
+are allowed. Normally the <ei>pT0</ei> above would be used to
+provide the main regularization of the branching rate for
+<ei>pT -> 0</ei>, in which case <ei>pTmin</ei> is used mainly for
+technical reasons. It is possible, however, to set <ei>pT0Ref = 0</ei>
+and use <ei>pTmin</ei> to provide a step-function regularization,
+or to combine them in intermediate approaches. Currently <ei>pTmin</ei>
+is taken to be energy-independent.
+</parm>
+
+<parm name="SpaceShower:pTminChgQ" default="0.5" min="0.01">
+Parton shower cut-off <ei>pT</ei> for photon coupling to a coloured
+particle.
+</parm>
+
+<parm name="SpaceShower:pTminChgL" default="0.0005" min="0.0001">
+Parton shower cut-off mass for pure QED branchings.
+Assumed smaller than (or equal to) <ei>pTminChgQ</ei>.
+</parm>
+
+<flag name="SpaceShower:rapidityOrder" default="off">
+Force emissions, after the first, to be ordered in rapidity,
+i.e. in terms of decreasing angles in a backwards-evolution sense.
+Could be used to probe sensitivity to unordered emissions.
+Only affects QCD emissions.
+</flag>
+
+<h3>Further variables</h3>
+
+These should normally not be touched. Their only function is for
+cross-checks.
+
+<p/>
+There are three flags you can use to switch on or off selected
+branchings in the shower:
+
+<flag name="SpaceShower:QCDshower" default="on">
+Allow a QCD shower; on/off = true/false.
+</flag>
+
+<flag name="SpaceShower:QEDshowerByQ" default="on">
+Allow quarks to radiate photons; on/off = true/false.
+</flag>
+
+<flag name="SpaceShower:QEDshowerByL" default="on">
+Allow leptons to radiate photons; on/off = true/false.
+</flag>
+
+<p/>
+There are three further possibilities to simplify the shower:
+
+<flag name="SpaceShower:MEcorrections" default="on">
+Use of matrix element corrections; on/off = true/false.
+</flag>
+
+<flag name="SpaceShower:phiPolAsym" default="on">
+Azimuthal asymmetry induced by gluon polarization; on/off = true/false.
+Not yet implemented.
+</flag>
+
+<modeopen name="SpaceShower:nQuarkIn" default="5" min="0" max="5">
+Number of allowed quark flavours in <ei>g -> q qbar</ei> branchings,
+when kinematically allowed, and thereby also in incoming beams.
+Changing it to 4 would forbid <ei>g -> b bbar</ei>, etc.
+</modeopen>
+
+<h3>Technical notes</h3>
+
+Almost everything is equivalent to the algorithm in [1]. Minor changes
+are as follows.
+<ul>
+<li>
+It is now possible to have a second-order running <ei>alpha_s</ei>,
+in addition to fixed or first-order running.
+</li>
+<li>
+The description of heavy flavour production in the threshold region
+has been modified, so as to be more forgiving about mismatches
+between the <ei>c/b</ei> masses used in Pythia relative to those
+used in a respective PDF parametrization. The basic idea is that,
+in the threshold region of a heavy quark <ei>Q</ei>, <ei>Q = c/b</ei>,
+the effect of subsequent <ei>Q -> Q g</ei> branchings is negligible.
+If so, then
+<eq>
+ f_Q(x, pT2) = integral_mQ2^pT2 dpT'2/pT'2 * alpha_s(pT'2)/2pi
+ * integral P(z) g(x', pT'2) delta(x - z x')
+</eq>
+so use this to select the <ei>pT2</ei> of the <ei>g -> Q Qbar</ei>
+branching. In the old formalism the same kind of behaviour should
+be obtained, but by a cancellation of a <ei>1/f_Q</ei> that diverges
+at the theshold and a Sudakov that vanishes.
+<br/>
+The strategy therefore is that, once <ei>pT2 < f * mQ2</ei>, with
+<ei>f</ei> a parameter of the order of 2, a <ei>pT2</ei> is chosen
+like <ei>dpT2/pT2</ei> between <ei>mQ2</ei> and <ei>f * mQ2</ei>, a
+nd a <ei>z</ei> flat in the allowed range. Thereafter acceptance
+is based on the product of three factors, representing the running
+of <ei>alpha_strong</ei>, the splitting kernel (including the mass term)
+and the gluon density weight. At failure, a new <ei>pT2</ei> is chosen
+in the same range, i.e. is not required to be lower since no Sudakov
+is involved.
+</li>
+</ul>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Standard-Model Parameters">
+
+<h2>Standard-Model Parameters</h2>
+
+<h3>The strong coupling</h3>
+
+The <code>AlphaStrong</code> class is used to provide a first- or
+second-order running <ei>alpha_strong</ei> (or, trivially, a
+zeroth-order fixed one). Formulae are the standard ones found in
+<ref>Yao06</ref>. The second-order expression used, eq. (9.5),
+may be somewhat different in other approaches (with differences
+formally of higher order), so do not necessarily expect perfect
+agreement, especially not at small <ei>Q^2</ei> scales. The starting
+<ei>alpha_strong</ei> value is defined at the <ei>M_Z</ei> mass scale.
+The <ei>Lambda</ei> values are matched at the <ei>b</ei> and <ei>c</ei>
+flavour thresholds, such that <ei>alpha_strong</ei> is continuous.
+For second-order matching an approximate iterative method is used.
+
+<p/>
+Since we allow <ei>alpha_strong</ei> to vary separately for
+hard processes, timelike showers, spacelike showers and multiple
+interactions, the relevant values can be set in each of these classes.
+The default behaviour is everywhere first-order running.
+
+<p/>
+The <ei>alpha_strong</ei> calculation is initialized by
+<code>init( value, order)</code>, where <code>value</code>
+is the <ei>alpha_strong</ei> value at <ei>M_Z</ei> and <code>order</code>
+is the order of the running, 0, 1 or 2. Thereafter the value can be
+calculated by <code>alphaS(scale2)</code>, where
+<code>scale2</code> is the <ei>Q^2</ei> scale in GeV^2.
+
+<p/>
+For applications inside shower programs, a second-order <code>alpha_s</code>
+value can be obtained as the product of the two functions
+<code>alphaS1Ord(scale2)</code> and <code>alphaS2OrdCorr(scale2)</code>,
+where the first gives a simple first-order running (but with the
+second-order <ei>Lambda</ei>) and the second the correction factor,
+below unity, for the second-order terms. This allows a compact handling
+of evolution equations.
+
+<h3>The electromagnetic coupling</h3>
+
+<p/>
+The <code>AlphaEM</code> class is used to generate a running
+<ei>alpha_em</ei>. The input <code>StandardModel:alphaEMmZ</code>
+value at the <ei>M_Z</ei> mass is matched to a low-energy behaviour
+with running starting at the electron mass threshold. The matching
+is done by fitting an effective running coefficient in the region
+betweeen the light-quark treshold and the charm/tau threshold. This
+procedure is approximate, but good enough for our purposes.
+
+<p/>
+Since we allow <ei>alpha_em</ei> to vary separately for
+hard processes, timelike showers, spacelike showers and multiple
+interactions, the choice between using a fixed or a running
+<ei>alpha_em</ei> can be made in each of these classes.
+The default behaviour is everywhere first-order running.
+The actual values assumed at zero momentum transfer and
+at <ei>M_Z</ei> are only set here, however.
+
+<parm name="StandardModel:alphaEM0" default="0.00729735"
+min="0.0072973" max="0.0072974">
+The <ei>alpha_em</ei> value at vanishing momentum transfer
+(and also below <ei>m_e</ei>).
+</parm>
+
+<parm name="StandardModel:alphaEMmZ" default="0.00781751"
+min="0.00780" max="0.00783">
+The <ei>alpha_em</ei> value at the <ei>M_Z</ei> mass scale.
+Default is taken from <ref>Yao06</ref>.
+</parm>
+
+<p/>
+The <ei>alpha_em</ei> calculation is initialized by
+<code>init(order)</code>, where <code>order</code> is the order of
+the running, 0 or 1, with -1 a special option to use the fix value
+provided at <ei>M_Z</ei>. Thereafter the value can be
+calculated by <code>alphaEM(scale2)</code>, where
+<code>scale2</code> is the <ei>Q^2</ei> scale in GeV^2.
+
+<h3>The electroweak couplings</h3>
+
+There are two degrees of freedom that can be set, related to the
+electroweak mixing angle:
+
+<parm name="StandardModel:sin2thetaW" default="0.2312"
+min="0.225" max="0.240">
+The weak mixing angle, as used in all <ei>Z^0</ei> and <ei>W^+-</ei>
+masses and couplings, except for the vector couplings of fermions
+to the <ei>Z^0</ei>, see below. Default is the MSbar value from
+<ref>Yao06</ref>.
+</parm>
+
+<parm name="StandardModel:sin2thetaWbar" default="0.2315" min="0.225" max="0.240">
+The weak mixing angle, as used to derive the vector couplings of fermions
+to the <ei>Z^0</ei>, in the relation
+<ei>v_f = a_f - 4 e_f sin^2(theta_W)bar</ei>. Default is the
+effective-angle value from <ref>Yao06</ref>.
+</parm>
+
+<p/>
+These and various couplings can be read out from the static
+<code>CoupEW</code> class:<br/>
+<code>CoupEW::sin2thetaW()</code> gives the weak mixing angle set above.<br/>
+<code>CoupEW::cos2thetaW()</code> gives 1 minus it.<br/>
+<code>CoupEW::sin2thetaWbar()</code> gives the weak mixing angle as used
+in fermion couplings.<br/>
+<code>CoupEW::ef(idAbs)</code> gives the electrical charge. Note that this
+and subsequent routines should be called with a positive
+<code>idAbs</code>.<br/>
+<code>CoupEW::vf(idAbs)</code> gives the vector coupling to
+<ei>Z^0</ei>.<br/>
+<code>CoupEW::af(idAbs)</code> gives the axial vector coupling.<br/>
+<code>CoupEW::t3f(idAbs)</code> gives the weak isospin of lefthanded quarks,
+i.e. <ei>a_f/2</ei>.<br/>
+<code>CoupEW::lf(idAbs)</code> gives the lefthanded coupling, i.e.
+<ei>(v_f + a_f/2)/2</ei> (other definitions may differ by a factor
+of 2).<br/>
+<code>CoupEW::rf(idAbs)</code> gives the righthanded coupling, i.e.
+<ei>(v_f - a_f/2)/2</ei> (with comment as above).<br/>
+<code>CoupEW::ef2(idAbs)</code> gives <ei>e_f^2</ei>.<br/>
+<code>CoupEW::vf2(idAbs)</code> gives <ei>v_f^2</ei>.<br/>
+<code>CoupEW::af2(idAbs)</code> gives <ei>a_f^2</ei>.
+
+<h3>The quark weak-mixing matrix</h3>
+
+The absolute values of the Cabibbo-Kobayashi-Maskawa matrix elements are
+set by the following nine real values taken from <ref>Yao06</ref> -
+currently the CP-violating phase is not taken into account in this
+parametrization. It is up to the user to pick a consistent unitary
+set of new values whenever changes are made.
+
+<parm name="StandardModel:Vud" default="0.97383" min="0.973" max="0.975">
+The <ei>V_ud</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vus" default="0.2272" min="0.224" max="0.230">
+The <ei>V_us</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vub" default="0.00396" min="0.0037" max="0.0042">
+The <ei>V_ub</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vcd" default="0.2271" min="0.224" max="0.230">
+The <ei>V_cd</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vcs" default="0.97296" min="0.972" max="0.974">
+The <ei>V_cs</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vcb" default="0.04221" min="0.0418" max="0.0426">
+The <ei>V_cb</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vtd" default="0.00814" min="0.006" max="0.010">
+The <ei>V_td</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vts" default="0.04161" min="0.039" max="0.043">
+The <ei>V_ts</ei> CKM matrix element.
+</parm>
+
+<parm name="StandardModel:Vtb" default="0.9991" min="0.99907" max="0.9992">
+The <ei>V_tb</ei> CKM matrix element.
+</parm>
+
+<p/>
+These couplings can be read back out in a few alternative forms:<br/>
+<code>VCKM::Vgen(genU, genD)</code> gives the CKM mixing element for
+up-type generation index <code>genU</code> (1, 2 or 3) and
+down-type generation index <code>genD</code>.<br/>
+<code>VCKM::V2gen(genU, genD)</code> gives the square of the above.<br/>
+<code>VCKM::Vid(id1, id2)</code> gives the CKM mixing element between
+two quark flavours <code>id1</code> and <code>id2</code>. The sign of
+the flavours is irrelevant, since the process may be either of the type
+<ei>q qbar' -> W</ei> or <ei>q g -> W q'</ei>. Flavour combinations
+with no CKM mixing (e.g. <ei>u u</ei>) are given a vanishing value.<br/>
+<code>VCKM::V2id(id1, id2)</code> gives the square of the above.<br/>
+<code>VCKM::V2sum(id)</code> gives the sum of squares that a given
+flavour can couple to, excluding the top quark. Is close to unity
+for the first two generations.<br/>
+<code>VCKM::V2pick(id)</code> picks a CKM partner quark (with the same
+sign as <code>id</code>) according to the respective squared elements,
+again excluding the top quark from the list of possibilities.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Timelike Showers">
+
+<h2>Timelike Showers</h2>
+
+The PYTHIA algorithm for timelike final-state showers is based on
+the recent article <ref>Sjo05</ref>, where a transverse-momentum-ordered
+evolution scheme is introduced. This algorithm is influenced by
+the previous mass-ordered algorithm in PYTHIA <ref>Ben87</ref> and by
+the dipole-emission formulation in Ariadne <ref>Gus86</ref>. From the
+mass-ordered algorithm it inherits a merging procedure for first-order
+gluon-emission matrix elements in essentially all two-body decays
+in the standard model and its minimal supersymmetric extension
+<ref>Nor01</ref>.
+
+<p/>
+The normal user is not expected to call <code>TimeShower</code> directly,
+but only have it called from <code>Pythia</code>. Some of the parameters
+below, in particular <code>TimeShower:alphaSvalue</code>, would be of
+interest for a tuning exercise, however.
+
+<h3>Main variables</h3>
+
+Often the maximum scale of the FSR shower evolution is understood from the
+context. For instance, in a resonace decay half the resonance mass sets an
+absolute upper limit. For a hard process in a hadronic collision the choice
+is not as unique. Here the factorization scale has been chosen as the
+maximum evolution scale. This would be the <ei>pT</ei> for a
+<ei>2 -> 2</ei> process, supplemented by mass terms for massive outgoing
+particles. Some small amount of freedom is offered by
+<parm name="TimeShower:pTmaxFudge" default="1.0" min="0.5" max="2.0">
+While the above rules would imply that <ei>pT_max = pT_factorization</ei>,
+<code>pTmaxFudge</code> introduced a multiplicative factor <ei>f</ei> such
+that instead <ei>pT_max = f * pT_factorization</ei>. Only applies to the
+hardest interaction in an event. It is strongly suggested that
+<ei>f = 1</ei>, but variations around this default can be useful to test
+this assumption.
+</parm>
+
+<p/>
+The amount of QCD radiation in the shower is determined by
+<parm name="TimeShower:alphaSvalue" default="0.137"
+min="0.06" max="0.25">
+The <ei>alpha_strong</ei> value at scale <ei>M_Z^2</ei>. The default
+value corresponds to a crude tuning to LEP data, to be improved.
+</parm>
+
+<p/>
+The actual value is then regulated by the running to the scale
+<ei>pT^2</ei>, at which the shower evaluates <ei>alpha_strong</ei>
+
+<modepick name="TimeShower:alphaSorder" default="1" min="0" max="2">
+Order at which <ei>alpha_strong</ei> runs,
+<option value="0">zeroth order, i.e. <ei>alpha_strong</ei> is kept
+fixed.</option>
+<option value="1">first order, which is the normal value.</option>
+<option value="2">second order. Since other parts of the code do
+not go to second order there is no strong reason to use this option,
+but there is also nothing wrong with it.</option>
+</modepick>
+
+<p/>
+QED radiation is regulated by the <ei>alpha_electromagnetic</ei>
+value at the <ei>pT^2</ei> scale of a branching.
+
+<modepick name="TimeShower:alphaEMorder" default="1" min="-1" max="1">
+The running of <ei>alpha_em</ei>.
+<option value="1">first-order running, constrained to agree with
+<code>StandardModel:alphaEMmZ</code> at the <ei>Z^0</ei> mass.
+</option>
+<option value="0">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed at its value at vanishing momentum transfer.</option>
+<option value="-1">zeroth order, i.e. <ei>alpha_em</ei> is kept
+fixed, but at <code>StandardModel:alphaEMmZ</code>, i.e. its value
+at the <ei>Z^0</ei> mass.
+</option>
+</modepick>
+
+<p/>
+The rate of radiation if divergent in the <ei>pT -> 0</ei> limit. Here,
+however, perturbation theory is expected to break down. Therefore an
+effective <ei>pT_min</ei> cutoff parameter is introduced, below which
+no emissions are allowed. The cutoff may be different for QCD and QED
+radiation off quarks, and is mainly a technical parameter for QED
+radiation off leptons.
+
+<parm name="TimeShower:pTmin" default="0.5" min="0.1" max="2.0">
+Parton shower cut-off <ei>pT</ei> for QCD emissions.
+</parm>
+
+<parm name="TimeShower:pTminChgQ" default="0.5" min="0.1" max="2.0">
+Parton shower cut-off <ei>pT</ei> for photon coupling to coloured particle.
+</parm>
+
+<parm name="TimeShower:pTminChgL" default="0.0005" min="0.0001" max="2.0">
+Parton shower cut-off <ei>pT</ei> for pure QED branchings.
+Assumed smaller than (or equal to) <code>pTminChgQ</code>.
+</parm>
+
+<p/>
+Shower branchings <ei>gamma -> f fbar</ei>, where <ei>f</ei> is a
+quark or lepton, in part compete with the hard processes involving
+<ei>gamma^*/Z^0</ei> production. In order to avoid overlap it makes
+sense to correlate the maximum <ei>gamma</ei> mass allowed in showers
+with the minumum <ei>gamma^*/Z^0</ei> mass allowed in hard processes.
+In addition, the shower contribution only contains the pure
+<ei>gamma^*</ei> contribution, i.e. not the <ei>Z^0</ei> part, so
+the mass spectrum above 50 GeV or so would not be well described.
+
+<parm name="TimeShower:mMaxGamma" default="10.0" min="0.001"
+max="50.0">
+Maximum invariant mass allowed for the created fermion pair in a
+<ei>gamma -> f fbar</ei> branching in the shower.
+</parm>
+
+<h3>Interleaved evolution</h3>
+
+Multiple interactions (MI) and initial-state showers (ISR) are
+always interleaved, as follows. Starting from the hard interaction,
+the complete event is constructed by a set of steps. In each step
+the <ei>pT</ei> scale of the previous step is used as starting scale
+for a downwards evolution. The MI and ISR components each make
+their respective Monte Carlo choices for the next lower <ei>pT</ei>
+value. The one with larger <ei>pT</ei> is allowed to carry out its
+proposed action, thereby modifying the conditions for the next steps.
+This is relevant since the two components compete for the energy
+contained in the beam remnants: both an interaction and an emission
+take avay some of the energy, leaving less for the future. The end
+result is a combined chain of decreasing <ei>pT</ei> values, where
+ones associated with new interactions and ones with new emissions
+are interleaved.
+
+<p/>
+There is no corresponding requirement for final-state radiation (FSR)
+to be interleaved. Such an FSR emission does not compete directly for
+beam energy (but see below), and also can be viewed as occuring after
+the other two components in some kind of time sense. Interleaving is
+allowed, however, since it can be argued that a high-<ei>pT</ei> FSR
+occurs on shorter time scales than a low-<ei>pT</ei> MI, say.
+Backwards evolution of ISR is also an example that physical time
+is not the only possible ordering principle, but that one can work
+with conditional probabilities: given the partonic picture at a
+specific <ei>pT</ei> resolution scale, what possibilities are open
+for a modified picture at a slightly lower <ei>pT</ei> scale, either
+by MI, ISR or FSR? Complete interleaving of the three components also
+offers advantages if one aims at matching to higher-order matrix
+elements above some given scale.
+
+<flag name="TimeShower:interleave" default="on">
+If on, final-state emissions are interleaved in the same
+decreasing-<ei>pT</ei> chain as multiple interactions and initial-state
+emissions. If off, final-state emissions are only addressed after the
+multiple interactions and initial-state radiation have been considered.
+</flag>
+
+<p/>
+As an aside, it should be noted that such interleaving does not affect
+showering in resonance decays, such as a <ei>Z^0</ei>. These decays are
+only introduced after the production process has been considered in full,
+and the subsequent FSR is carried out inside the resonance, with
+preserved resonance mass.
+
+<p/>
+One aspect of FSR for a hard process in hadron collisions is that often
+colour diples are formed between a scattered parton and a beam remnant,
+or rather the hole left behind by an incoming partons. If such holes
+are allowed as dipole ends and take the recoil when the scattered parton
+undergoes a branching then this translates into the need to take some
+amount of remnant energy also in the case of FSR, i.e. the roles of
+ISR and FSR are not completely decoupled. The energy taken away is
+bokkept by increasing the <ei>x</ei> value assigned to the incoming
+scattering parton, and a reweighting factor
+<ei>x_new f(x_new, pT^2) / x_old f(x_old, pT^2)</ei>
+in the emission probability ensures that not unphysically large
+<ei>x_new</ei> values are reached. Usually such <ei>x</ei> changes are
+small, and they can be viewed as a higher-order effect beyond the
+accuracy of the leading-log initial-state showers.
+
+<p/>
+This choice is not unique, however. As an alternative, if nothing else
+useful for cross-checks, one could imagine that the FSR is completely
+decoupled from the ISR and beam remnants.
+
+<flag name="TimeShower:allowBeamRecoil" default="on">
+If on, the final-state shower is allowed to borrow energy from
+the beam remnants as described above, thereby changing the mass of the
+scattering subsystem. If off, the partons in the scattering subsystem
+are constrained to borrow energy from each other, such that the total
+four-momentum of the system is preserved. This flag has no effect
+on resonance decays, where the shower always preserves the resonance
+mass, cf. the comment above about showers for resonances never being
+interleaved.
+</flag>
+
+
+<h3>Radiation off octet onium states</h3>
+
+In the current implementation, charmonium and bottomonium production
+can proceed either through colour singlet or colour octet mechanisms,
+both of them implemented in terms of <ei>2 -> 2</ei> hard processes
+such as <ei>g g -> (onium) g</ei>.
+In the former case the state does not radiate and the onium therefore
+is produced in isolation, up to normal underlying-event activity. In
+the latter case the situation is not so clear, but it is sensible to
+assume that a shower can evolve. (Assuming, of course, that the
+transverse momentum of the onium state is sufficiently high that
+radiation is of relevance.)
+
+<p/>
+There could be two parts to such a shower. Firstly a gluon (or even a
+quark, though less likely) produced in a hard <ei>2 -> 2</ei> process
+can undergo showering into many gluons, whereof one branches into the
+heavy-quark pair. Secondly, once the pair has been produced, each quark
+can radiate further gluons. This latter kind of emission could easily
+break up a semibound quark pair, but might also create a new semibound
+state where before an unbound pair existed, and to some approximation
+these two effects should balance in the onium production rate.
+The showering "off an onium state" as implemented here therefore should
+not be viewed as an accurate description of the emission history
+step by step, but rather as an effective approach to ensure that the
+octet onium produced "in the hard process" is embedded in a realistic
+amount of jet activity.
+Of course both the isolated singlet and embedded octet are likely to
+be extremes, but hopefully the mix of the two will strike a reasonable
+balance. However, it is possible that some part of the octet production
+occurs in channels where it should not be accompanied by (hard) radiation.
+Therefore reducing the fraction of octet onium states allowed to radiate
+is a valid variation to explore uncertainties.
+
+<p/>
+If an octet onium state is chosen to radiate, the simulation of branchings
+is based on the assumption that the full radiation is provided by an
+incoherent sum of radiation off the quark and off the antiquark of the
+onium state. Thus the splitting kernel is taken to be the normal
+<ei>q -> q g</ei> one, multiplied by a factor of two. Obviously this is
+a simplification of a more complex picture, averaging over factors pulling
+in different directions. Firstly, radiation off a gluon ought
+to be enhanced by a factor 9/4 relative to a quark rather than the 2
+now used, but this is a minor difference. Secondly, our use of the
+<ei>q -> q g</ei> branching kernel is roughly equivalent to always
+following the harder gluon in a <ei>g -> g g</ei> branching. This could
+give us a bias towards producing too hard onia. A soft gluon would have
+little phase space to branch into a heavy-quark pair however, so the
+bias may not be as big as it would seem at first glance. Thirdly,
+once the gluon has branched into a quark pair, each quark carries roughly
+only half of the onium energy. The maximum energy per emitted gluon should
+then be roughly half the onium energy rather than the full, as it is now.
+Thereby the energy of radiated gluons is exaggerated, i.e. onia become too
+soft. So the second and the third points tend to cancel each other.
+
+<p/>
+Finally, note that the lower cutoff scale of the shower evolution depends
+on the onium mass rather than on the quark mass, as it should be. Gluons
+below the octet-onium scale should only be part of the octet-to-singlet
+transition.
+
+<parm name="TimeShower:octetOniumFraction" default="1." min="0." max="1." >
+Allow colour-octet charmonium and bottomonium states to radiate gluons.
+0 means that no octet-onium states radiate, 1 that all do, with possibility
+to interpolate between these two extremes.
+</parm>
+
+<parm name="TimeShower:octetOniumColFac" default="2." min="0." max="4." >
+The colour factor used used in the splitting kernel for those octet onium
+states that are allowed to radiate, normalized to the <ei>q -> q g</ei>
+splitting kernel. Thus the default corresponds to twice the radiation
+off a quark. The physically preferred range would be between 1 and 9/4.
+</parm>
+
+<h3>Further variables</h3>
+
+There are several possibilities you can use to switch on or off selected
+branching types in the shower, or in other respects simplify the shower.
+These should normally not be touched. Their main function is for
+cross-checks.
+
+<flag name="TimeShower:QCDshower" default="on">
+Allow a QCD shower, i.e. branchings <ei>q -> q g</ei>, <ei>g -> g g</ei>
+and <ei>g -> q qbar</ei>; on/off = true/false.
+</flag>
+
+<modeopen name="TimeShower:nGluonToQuark" default="5" min="0" max="5">
+Number of allowed quark flavours in <ei>g -> q qbar</ei> branchings
+(phase space permitting). A change to 4 would exclude
+<ei>g -> b bbar</ei>, etc.
+</modeopen>
+
+<flag name="TimeShower:QEDshowerByQ" default="on">
+Allow quarks to radiate photons, i.e. branchings <ei>q -> q gamma</ei>;
+on/off = true/false.
+</flag>
+
+<flag name="TimeShower:QEDshowerByL" default="on">
+Allow leptons to radiate photons, i.e. branchings <ei>l -> l gamma</ei>;
+on/off = true/false.
+</flag>
+
+<flag name="TimeShower:QEDshowerByGamma" default="on">
+Allow photons to branch into lepton or quark pairs, i.e. branchings
+<ei>gamma -> l+ l-</ei> and <ei>gamma -> q qbar</ei>;
+on/off = true/false.
+</flag>
+
+<modeopen name="TimeShower:nGammaToQuark" default="5" min="0" max="5">
+Number of allowed quark flavours in <ei>gamma -> q qbar</ei> branchings
+(phase space permitting). A change to 4 would exclude
+<ei>g -> b bbar</ei>, etc.
+</modeopen>
+
+<modeopen name="TimeShower:nGammaToLepton" default="3" min="0" max="3">
+Number of allowed lepton flavours in <ei>gamma -> l+ l-</ei> branchings
+(phase space permitting). A change to 2 would exclude
+<ei>gamma -> tau+ tau-</ei>, and a change to 1 also
+<ei>gamma -> mu+ mu-</ei>.
+</modeopen>
+
+<flag name="TimeShower:MEcorrections" default="on">
+Use of matrix element corrections where available; on/off = true/false.
+</flag>
+
+<flag name="TimeShower:phiPolAsym" default="on">
+Azimuthal asymmetry induced by gluon polarization; on/off = true/false.
+</flag>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Top Processes">
+
+<h2>Top Processes</h2>
+
+Different ways to produce top quarks, singly or in pairs.
+
+<flag name="Top:all" default="off">
+Common switch for the group of top production.
+</flag>
+
+<flag name="Top:gg2ttbar" default="off">
+Scatterings <ei>g g -> t tbar</ei>.
+Code 601.
+</flag>
+
+<flag name="Top:qqbar2ttbar" default="off">
+Scatterings <ei>q qbar -> t tbar</ei> by gluon exchange.
+Code 602.
+</flag>
+
+<flag name="Top:qq2tq(t:W)" default="off">
+Scatterings <ei>q q' -> t q''</ei> by <ei>t</ei>-channel exchange
+of a <ei>W^+-</ei> boson.
+Code 603.
+</flag>
+
+<flag name="Top:ffbar2ttbar(s:gmZ)" default="off">
+Scatterings <ei>f fbar -> t tbar</ei> by <ei>s</ei>-channel exchange
+of a <ei>gamma^*/Z^0</ei> boson.
+Code 604.
+</flag>
+
+<flag name="Top:ffbar2tqbar(s:W)" default="off">
+Scatterings <ei>f fbar' -> t q''</ei> by <ei>s</ei>-channel exchange
+of a <ei>W^+-</ei> boson.
+Code 605.
+</flag>
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
+
--- /dev/null
+<chapter name="Total Cross Sections">
+
+<h2>Total Cross Sections</h2>
+
+The <code>SigmaTotal</code> class returns the total, elastic, diffractive
+and nondiffractive cross sections in hadronic collisions, and also the
+slopes of the <ei>d(sigma)/dt</ei> distributions. The parametrizations
+used are from <ref>Sch97</ref> which borrows some of the total cross
+sections from <ref>Don92</ref>.
+
+<p/>
+The allowed combinations of incoming particles are <ei>p + p</ei>,
+<ei>pbar + p</ei>, <ei>pi+ + p</ei>, <ei>pi- + p</ei>,
+<ei>pi0/rho0 + p</ei>, <ei>phi + p</ei>, <ei>J/psi + p</ei>,
+<ei>rho + rho</ei>, <ei>rho + phi</ei>, <ei>rho + J/psi</ei>,
+<ei>phi + phi</ei>, <ei>phi + J/psi</ei>, <ei>J/psi + J/psi</ei>.
+The strong emphasis on vector mesons is related to the description
+of <ei>gamma + p</ei> and <ei>gamma + gamma</ei> interactions in a
+Vector Dominance Model framework (which will not be available for some
+time to come, so this is a bit of overkill).
+
+<h3>Variables</h3>
+
+If the internally implemented cross section parametrizations are not
+satisfactory, it is possible to override the cross section values
+with
+
+<flag name="SigmaTotal:setOwn" default="no">
+Allow a user to set own cross sections by hand; yes/no = true/false.
+</flag>
+
+<p/>
+When <code>SigmaTotal:setOwn = yes</code>, the user is expected to set
+values for the corresponding cross sections:
+
+<parm name="SigmaTotal:sigmaTot" default="80." min="0.">
+Total cross section in mb.
+</parm>
+
+<parm name="SigmaTotal:sigmaEl" default="20." min="0.">
+Elastic cross section in mb.
+</parm>
+
+<parm name="SigmaTotal:sigmaXB" default="8." min="0.">
+Single Diffractive cross section <ei>A + B -> X + B</ei> in mb.
+</parm>
+
+<parm name="SigmaTotal:sigmaAX" default="8." min="0.">
+Single Diffractive cross section <ei>A + B -> A + X</ei> in mb.
+</parm>
+
+<parm name="SigmaTotal:sigmaXX" default="4." min="0.">
+Double Diffractive cross section <ei>A + B -> X_1 + X_2</ei> in mb.
+</parm>
+
+<p/>
+Note that the total cross section subtracted by the elastic and various
+diffractive ones gives the inelastic nondiffractive cross section,
+which therefore is not set separately. If this cross section evaluates
+to be negative the internal parametrizations are used instead of the
+ones here. However, since the nondiffractive inelastic cross section
+is what makes up the minimum-bias event class, and plays a major role
+in the description of multiple interactions, it is important that a
+consistent set is used.
+
+<p/>
+In the above option the <ei>t</ei> slopes are based on the internal
+parametrizations. In addition there is no Coulomb-term contribution
+to the elastic (or total) cross section, which of course becomes
+infinite if this contribution is included. If you have switched on
+<code>SigmaTotal:setOwn</code> you can further switch on a machinery
+to include the Coulomb term, including interference with the conventional
+strong-interaction Pomeron one <ref>Ber87</ref>. Then the elastic cross
+section is no longer taken from <code>SigmaTotal:sigmaEl</code> but
+derived from the parameters below and <code>SigmaTotal:sigmaTot</code>,
+using the optical theorem. The machinery is only intended to be used for
+<ei>p p</ei> and <ei>pbar p</ei> collisions. The description of
+diffractive events, and especially their slopes, remains unchanged.
+
+<flag name="SigmaElastic:setOwn" default="no">
+Allow a user to set parameters for the normalization and shape of the
+elastic cross section the by hand; yes/no = true/false.
+</flag>
+
+<parm name="SigmaElastic:bSlope" default="18." min="0.">
+the slope <ei>b</ei> of the strong-interaction term <ei>exp(bt)</ei>,
+in units of GeV^-2.
+</parm>
+
+<parm name="SigmaElastic:rho" default="0.13" min="-1." max="1.">
+the ratio of the real to the imaginary parts of the nuclear scattering
+amplitude.
+</parm>
+
+<parm name="SigmaElastic:lambda" default="0.71" min="0.1" max="2.">
+the main parameter of the electric form factor
+<ei>G(t) = lambda^2 / (lambda + |t|)^2</ei>, in units of GeV^2.
+</parm>
+
+<parm name="SigmaElastic:tAbsMin" default="5e-5" min="1e-10">
+since the Coulomb contribution is infinite a lower limit on
+<ei>|t|</ei> must be set to regularize the divergence,
+in units of GeV^2.
+</parm>
+
+<parm name="SigmaElastic:phaseConst" default="0.577">
+The Coulomb term is taken to contain a phase factor
+<ei>exp(+- i alpha phi(t))</ei>, with + for <ei>p p</ei> and - for
+<ei>pbar p</ei>, where <ei>phi(t) = - phaseConst - ln(-B t/2)</ei>.
+This constant is model dependent <ref>Cah82</ref>.
+</parm>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Tunes">
+
+<h2>Tunes</h2>
+
+Since some physics aspects cannot be derived from first principles,
+this program contains many parameters that represent a true
+uncertainty in our understanding of nature. Particularly afflicted
+are the areas of hadronization and multiple interactions, which both
+involve nonperturbative QCD physics.
+
+<p/>
+Technically, PYTHIA parameters can be varied independently of each
+other, but the physical requirement of a sensible description of a set
+of data leads to correlations and anticorrelations between the
+parameters. Hence the need to produce tunes, not of one parameter at
+a time, but simultaneously for a group of them. A well-known such
+example is parton densities, where combined tunes to a wide range of data
+have been produced, that can then be obtained prepackaged.
+
+<p/>
+Given the many PYTHIA parameters to be tuned, it is convenient to
+divide the task into subtasks. Firstly, if we assume jet universality,
+hadronization and final-state parton showers should be tuned to
+<ei>e^+e^-</ei> annihilation data, notably from LEP1, since this
+offers the cleanest environment. Secondly, with such parameters fixed,
+hadron collider data should be studied to pin down multiple interactions
+and other further aspects, such as initial-state radiation. (Thirdly
+would come anything else, such as physics with photon beams, which
+involve further parameters, but that is beyond the current scope.)
+
+<p/>
+Sadly PYTHIA 8 did not yet take many steps along this long road.
+While the default values in PYTHIA 8 have been chosen "sensibly",
+so far there has not been a complete, consistent tuning of the program.
+For hadronization we can partly benefit from the LEP experience with
+PYTHIA 6, since the basic hadronization scheme did not change.
+However, there never was a combined LEP tune, since each of the four
+LEP collaborations produced their own tunes to their own data. The
+situation is worse for multiple interactions, where PYTHIA 8 is more
+different from PYTHIA 6. Nevertheless, the PYTHIA 6 tunes to CDF data,
+performed by R.D. Field, have been used as a rough guide in picking
+reasonable default values.
+
+<p/>
+In the future we hope to see PYTHIA 8 tunes appear. Like with parton
+distributions, there is likely to be several tunes, because different
+sets of data will pull in different directions, by imperfections
+in the model or in the data, and by differences in the chosen
+tuning strategies. We therefore propose to collect some of these tunes
+here, in a prepackaged form. Of course, in all cases it is a matter
+of setting values for parameters already defined elsewhere, so the
+tunes offer no new functionality, only a more convenient setup.
+
+<p/>
+If you set either the <code>Tune:ee</code> and <code>Tune:pp</code>
+modes below non-zero then all parameters used in the respective tune
+will be set accordingly when <code>pythia.init(...)</code> is called.
+You can check this by calling <code>pythia.settings.listChanged()</code>
+before and after initialization; before only the tune modes are
+nondefault, afterwards all the non-default-valued parameters in the
+tune appear. Therefore, for better or worse, you cannot combine a tune
+option with your own choices for some of the parameters used in the tune,
+since the values you set before <code>pythia.init(...)</code> would be
+overwritten at that point.
+
+<modepick name="Tune:ee" default="0">
+Choice of tune to <ei>e^+e^-</ei> data, mainly for the hadronization
+and timelike-showering aspects of PYTHIA.
+<option value="0">no values are overwritten at initialization,
+so you can set the individual parameters as you wish.
+</option>
+<option value="101">a tune by Marc Montull to the LEP 1 particle
+composition, as published in the RPP. The default PYTHIA parameter
+values tend to produce more vector mesons than observed in data.
+When more pseudoscalars are produced directly this also leads to a
+reduced <ei>s/u</ei> ratio and diquark fraction. Also other parameters
+related to the particle composition obtain changed values. No related
+(re)tune to event shapes has been performed so far, however.
+</option>
+</modepick>
+
+<modepick name="Tune:pp" default="0">
+Choice of tune to <ei>pp / ppbar</ei> data, mainly for the
+multiple-interactions and initial-state-radiation aspects of PYTHIA.
+<note>Note:</note> Currently this is only a placeholder, since no
+tunes alternative to the default values exist.
+<option value="0">no values are overwritten at initialization,
+so you can set the individual parameters as you wish.
+</option>
+
+</modepick>
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Update History">
+
+<h2>Update History</h2>
+
+These update notes describe major updates relative to the baseline
+PYTHIA 8.100 version. However, they are less extensive than the
+corresponding update notes for PYTHIA 6. There are three main
+reasons for this:
+<ul>
+<li>The manual contained on these html/php pages is kept up to date.
+ (However, the "Brief Introduction" may not always be.)
+</li>
+<li>8.1 is a quite new code, so there are many minor changes that,
+ if all were to be documented, would hide the key ones.
+</li>
+<li>8.1 is not yet used for "mission critical" applications,
+ so there is less need to trace changed behaviour.
+</li>
+</ul>
+
+<h3>Main news by version</h3>
+
+<ul>
+<li>8.101: 10 November 2007
+<ul>
+<li>New option to initialize with arbitrary beam directions<br/>
+<code>pythia.init( idA, idB, pxA, pyA, pzA, pxB, pyB, pzB)</code>
+</li>
+<li>The <code>LHAevnt</code> and <code>LHAinit</code> classes have been
+joined into a new <code>LHAup</code> one, with new options that allow
+the writing of a Les Houches Event File.
+</li>
+</ul>
+</li>
+
+<li>8.102: 6 December 2007
+<ul>
+<li>Limited capability to use two different <code>Pythia</code> instances
+for signal + pileup event generation, see <code>main19.cc</code> for an
+example.
+</li>
+<li>Added capability to set <aloc href="BeamParameters">beam energy spread
+and beam vertex</aloc>.
+<br/>
+<b>Warning:</b> as a consequence, some settings names have been changed,
+see below.
+</li>
+</ul>
+</li>
+
+<li>8.103: 22 January 2008
+<ul>
+<li>Updated HepMC conversion routine.
+</li>
+<li>In the <code>Event</code> class the <code>=</code> and
+<code>=+</code> methods have been overloaded to allow the copying
+or appending of event records. Illustrated in <code>main19.cc</code>.
+</li>
+</ul>
+</li>
+
+<li>8.104: 14 February 2008
+<ul>
+<li>Updated configure scripts.
+</li>
+<li>The <code>SusyLesHouches</code> class updated to handle
+SLHA version 2.
+</li>
+<li>The <code>forceHadronLevel()</code> method introduced for standalone
+hadronization.
+</li>
+<li><code>main15.cc</code> illustrated how either full hadronization or
+only decays of some particles can be looped over for the rest of the
+event retained.
+</li>
+<li>The html and php page formatting improved with
+cascading style sheets.
+</li>
+<li>The static <code>ErrorMsg</code> class has been removed and
+its functionality moved into the non-static <code>Info</code> class,
+in the renamed Info file.
+</li>
+</ul>
+</li>
+
+<li>8.105: 24 February 2008
+<ul>
+<li>Further reduction of the use of static, with related code changes.
+This should allow to have several almost independent <code>Pythia</code>
+instances. Some static classes still remain, however, notably for
+random number generation and particle properties.
+</li>
+<li>Several minor improvements and new options.
+</li>
+</ul>
+</li>
+
+<li>8.106: 11 March 2008
+<ul>
+<li>Improved handling of the Higgs width, relevant for massive and thereby
+broad resonance shapes.
+</li>
+</ul>
+</li>
+
+<li>8.107: 17 March 2008
+<ul>
+<li>Correction in the event record, so that the beam particles in line
+1 and 2 do not have any mother according to the <code>motherList</code>
+method. Previously the "system" entry in line 0 was counted as their
+mother, which gave rise to an unexpected extra vertex in the conversion
+to the HepMC format.
+</li>
+</ul>
+</li>
+
+<li>8.108: 1 May 2008
+<ul>
+<li>Support for HepMC version 1 is removed, to simplify the code and
+reflect the evolution of the field.
+</li>
+<li>Status codes are stored in HepMC only as 1 for existing and 2 for
+decayed or fragmented particles (whereas previously the original PYTHIA
+codes were used for the latter).
+</li>
+<li>Parton densities are stored in HepMC as <ei>xf(x,Q^2)</ei>
+rather than the <ei>f(x,Q^2)</ei> used in (some) previous versions.
+</li>
+<li>The SusyLesHouches class has ben updated so that reading is fully
+compatible with the SLHA2 standard.
+</li>
+<li>The matrix elements for neutralino pair production have now been
+completed and checked.
+</li>
+<li>A new compilation option <code>-Wshadow</code> is introduced and
+code is rewritten at all places where this option gave warnings.
+</li>
+<li>Minor library correction to allow compilation with gcc 4.3.0.</li>
+<li>Ensure that <ei>alpha_strong</ei> does not blow up, by introducing
+a minimal scale somewhat above <ei>Lambda_3</ei> (roughly where
+<ei>alpha_strong = 10</ei>).
+</li>
+<li>New methods <code>isValence1()</code> and <code>isValence2()</code>
+in the <code>Info</code> class.
+</li>
+</ul>
+</li>
+
+</ul>
+
+<h3>Changes among settings names</h3>
+
+New capabilities are still being added, meaning new settings names.
+It then may become preferable to rename existing settings to form
+new logical groups. Here is a list of thise changes that have been
+made since be 8.100 baseline version.
+<ul>
+<li>A '*' is used as wildcard.
+</li>
+<li>Names within brackets denotes also new/changed functionality.
+</li>
+</ul>
+
+<table cellspacing="5">
+<tr> <td>8.100 setting </td> <td>has been moved to </td> </tr>
+<tr> <td>Beams:* </td> <td>BeamRemnants:* </td> </tr>
+<tr> <td>Main:idA </td> <td>Beams:idA </td> </tr>
+<tr> <td>Main:idB </td> <td>Beams:idB </td> </tr>
+<tr> <td>Main:inCMframe </td> <td>(Beams:frameType) </td> </tr>
+<tr> <td>Main:eCM </td> <td>Beams:eCM </td> </tr>
+<tr> <td>Main:eA </td> <td>Beams:eA </td> </tr>
+<tr> <td>Main:eB </td> <td>Beams:eB </td> </tr>
+<tr> <td>Main:LHEF </td> <td>Beams:LHEF </td> </tr>
+</table>
+
+
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="User Hooks">
+
+<h2>User Hooks</h2>
+
+Sometimes it may be convenient to step in during the generation
+process: to modify the built-in cross sections, to veto undesirable
+events or simply to collect statistics at various stages of the
+evolution. There is a base class <code>UserHooks</code> that gives
+you this access at a few selected places. This class in itself does
+nothing; the idea is that you should write your own derived class
+for your task. A few very simple derived classes come with the
+program, mainly as illustration.
+
+<p/>
+For a derived class to be called during the execution, a pointer to
+an object of this class should be handed in with the
+<br/>
+<aloc href="ProgramFlow">
+<code>pythia.setUserHooksPtr( UserHooks*)</code></aloc> method.
+
+<p/>
+There are four distinct sets of routines. Ordered by increasing
+complexity, rather than by their appearance in the event-generation
+sequence, they are:
+<br/>(i) Ones that gives you access to the event record in between
+the process-level and parton-level steps, or in between the
+parton-level and hadron-level ones. You can study the event record
+and decide whether to veto this event.
+<br/>(ii) Ones that allow you to set a scale at with the combined
+parton-level MI+ISR+FSR downwards evolution in <ei>pT</ei> is
+temporarily interrupted, so the event can be studied and either
+vetoed or allowed to continue the evolution.
+<br/>(iii) Ones that allow you to to study the event after the first
+few ISR/FSR emissions, so the event can be vetoed or allowed to
+continue the evolution.
+<br/>(iv) Ones that gives you access to the properties of the trial
+hard process, so that you can modify the internal Pythia cross section
+by your own correction factors.
+<br/>They are described further in the following.
+
+<h3>Interrupt between the main generation levels</h3>
+
+If your derived class redefines the
+<br/><code>bool canVetoProcessLevel()</code>
+<br/>method to return <code>true</code>, then the method
+<br/><code>bool doVetoProcessLevel(const Event& process)</code>
+<br/>will be called immediately after a hard process has been selected and
+stored in the <code>process</code> event record. You can study, but not
+modify, this record. Based on that you can decide whether to veto the
+event or let it continue to evolve. If you veto, then this event is not
+counted among the accepted ones, and do not contribute to the estimated
+cross section. The <code>pytha.next()</code> method will begin a
+completely new event, so the vetoed event will not appear in the
+output of <code>pythia.next()</code>.
+
+<p/>
+Note that this is different from setting the flag
+<aloc href="MasterSwitches"><code>PartonLevel:all = off</code></aloc>.
+Also in this case the event
+generation will stop after the process level, but an event generated
+up to this point is considered perfectly acceptable, and cross sections
+are not affected. That is, this option is intended for simple studies of
+hard processes, where one can save time by not generating the rest of the
+story. By contrast, the <code>doVetoProcessLevel()</code> allows you to
+throw away uninteresting events at an early stage to save time that way,
+but those events that do survive the veto are allowed to develop into
+complete final states (unless flags have been set otherwise).
+
+<p/>
+The
+<br/><code>bool canVetoPartonLevel()</code>
+<br/>and
+<br/><code>bool doVetoPartonLevel(const Event& event)</code>
+<br/>are exact analogues to the above two methods, except that these
+ones are called after the parton level, i.e. when showers, multiple
+interactions and beam remnants have been set up, but hadronization and
+decays have not yet been performed. Information is now made available in
+the <code>event</code> event record. The difference relative to the
+<aloc href="MasterSwitches"><code>HadronLevel:all = off</code></aloc>
+flag setting follows the same pattern as above.
+
+<p/>
+The effect of the vetoes can be studied in the output of the
+<code>pythia.statistics()</code> method. The "Selected" column represents
+the number of events that were found acceptable by the internal Pythia
+machinery, whereas the "Accepted" one are the events that also survived
+the user cuts.
+
+<h3>Interrupt during the parton-level evolution, at a <ei>pT</ei> scale</h3>
+
+During the parton-level evolution, multiple interactions (MI),
+initial-state radiation (ISR) and final-state radiation (FSR)
+are normally evolved downwards in
+one interleaved evolution sequence of decreasing <ei>pT</ei> values.
+For some applications, e.g matrix-element-matching approaches, it
+may be convenient to stop the evolution temporarily when the "hard"
+emissions have been considered, but before continuing with the more
+time-consuming soft activity. Based on these hard partons one can make
+a decision whether the event at all falls in the intended event class,
+e.g. has the "right" number of parton-level jets. If yes then, as for
+the methods above, the evolution will continue all the way up to a
+complete event. Also as above, if no, then the event will not be
+considered in the final cross section.
+
+<p/>
+In this subsection we outline the possibility to interrupt at a given
+<ei>pT</ei> scale, in the next to interrupt after a given number of
+emissions.
+
+<p/>
+To use this possibility you need to redefine
+<br/><code>bool canVetoPT()</code>
+<br/>to return <code>true</code> and
+<br/><code>double scaleVetoPT()</code>
+<br/>to return the <ei>pT</ei> scale at which you want to study the event.
+
+<p/>
+The key routine, where you decide whether the event should be vetoed
+(return <code>true</code>) or not (<code>false</code>), is
+<br/><code>bool doVetoPT(int iPos, const Event& event)</code>
+<br/>Here
+<br/><code>iPos</code> is the position/status when the routine is
+called:
+<br/>= 0 when no MI, ISR or FSR occured above the veto scale;
+<br/>= 1 when inside the interleaved MI + ISR + FSR evolution,
+after an MI process;
+<br/>= 2 when inside the interleaved MI + ISR + FSR evolution,
+after an ISR emission;
+<br/>= 3 when inside the interleaved MI + ISR + FSR evolution,
+after an FSR emission;
+<br/>= 4 for the optional case where FSR is deferred from the interleaved
+evolution and only considered separately afterward (then alternative 3
+would never occur);
+<br/>= 5 is for subsequent resonance decays, and is called once
+for each decay in a chain such as <ei>t -> b W, W -> u dbar</ei>.
+
+<p/>
+The event record contains a list of all partons generated so far, also
+including intermediate ones not part of the "current final state",
+and also those from further multiple interactions. This may not be
+desirable for comparisons with matrix-element calculations. The method
+<br/><code>void subEvent(const Event& event, bool isHardest = true)</code>
+<br/> offers a simple recipe to extract a list of only the current
+partons from the hardest interaction, as relevant for <code>iPos</code>
+codes 0 - 4. With <code>isHardest = false</code> instead the latest
+"subprocess" is extracted, as relevant when <code>iPos</code> is 5,
+where it corresponds to the partons in the currently considered decay.
+
+<p/>
+The result is stored in the class member <code>Event workEvent</code>.
+The <code>daughter1()</code> and <code>daughter2()</code> both return
+the position in the original event record (<code>process</code> or
+<code>event</code>), so you can trace the full history, if of interest.
+The <code>workEvent</code> can e.g. be sent on to a
+<aloc href="EventAnalysis">jet clustering algorithm</aloc>.
+You are free to edit <code>workEvent</code> as you desire, e.g. boost
+to its rest frame before analysis, or remove particles that should
+not be analyzed.
+
+<h3>Interrupt during the parton-level evolution, after a step</h3>
+
+This option is closely related to the one above, so we do not repeat
+the introduction, nor the possibilities to study the event record,
+also by using <code>subEvent(...)</code>.
+What is different is that this method gives access to the event as
+it looks like after each of the first few steps in the downwards
+evolution, irrespectively of the <ei>pT</ei> scales of these branchings.
+Furthermore, it is here assumed that the focus is on the hardest
+subprocess, so that ISR/FSR emissions associated with additional MI's
+are not considered.
+
+<p/>
+To use the possibility to study the event after the first steps you need
+to redefine
+<br/><code>bool canVetoStep()</code>
+<br/>to return <code>true</code> and
+<br/><code>int numberVetoStep()</code>
+<br/>to return up to how many steps each of ISR and FSR (for the hardest
+interaction) that you want to be able to study. The number of steps
+defaults to the first one only.
+
+<p/>
+The key routine, where you decide whether the event should be vetoed
+(return <code>true</code>) or not (<code>false</code>), is
+<br/><code>bool doVetoStep( int iPos, int nISR, int nFSR,
+const Event& event)</code>
+<br/>Here
+<br/><code>iPos</code> is the position from where the routine has been
+called, options 2 - 5 of the <code>doVetoPT(...)</code> routine
+above, while options 0 and 1 are not relevant here;
+<br/><code>nISR</code> is the number of ISR emissions in the hardest
+process so far; and
+<br/><code>nFSR</code> is the number of FSR emissions in the hardest
+process so far.
+<br/>For resonance decays, <code>iPos = 5</code>, the <code>nISR</code>
+is set 0 and <code>nFSR</code> refers to the number of emissions in
+the currently studied system.
+
+<h3>Modify cross-sections</h3>
+
+If you want to modify a cross section you need to redefine
+<br/><code>bool canModifySigma()</code>
+<br/>to return <code>true</code> and
+<br/><code>double multiplySigmaBy(const SigmaProcess* sigmaProcessPtr,
+const PhaseSpace* phaseSpacePtr, bool inEvent)</code>
+<br/>to provide the factor by
+which you want to see the cross section modified. If you return unity
+then the normal cross section is obtained. Note that, unlike the
+methods above, these modifications do not lead to a difference between
+the number of "selected" events and the number of "accepted" ones,
+since the modifications occur already before the "selected" level.
+The integrated cross section of a process is modified, of course.
+
+<p/>
+What makes the <code>multiplySigmaBy(...)</code> routine somewhat
+tricky to write is that the hard-process event has not yet been
+constructed, so one is restricted to use the information available
+in the phase-space and cross-section objects currently being accessed.
+Which of their methods are applicable depends on the process,
+in particular the number of final-state particles. The
+<code>UserHooks</code> code contains explicit instructions about
+which methods provide meaningful information.
+
+<p/>
+The <code>inEvent</code> flag is <code>true</code> when this method is
+called from within the event-generation machinery and <code>false</code>
+when it is called at the initialization stage of the run, when the
+cross section is explored to find a maximum for later Monte Carlo usage.
+Cross-section modifications should be independent of this flag,
+for consistency, but if <code> multiplySigmaBy(...)</code> is used to
+collect statistics on the original kinematics distributions before cuts,
+then it is important to be able to exclude the initialization stage
+from comparisons.
+
+<p/>
+Note that the cross section is only modifiable for normal hard processes.
+It does not affect the cross section in further multiple interactions,
+nor in elastic/diffractive/minimum-bias events.
+
+<p/>
+One derived class is supplied as an example how this facility can be used
+to reweight cross sections in the same spirit as is done with QCD cross
+sections for the minimum-bias/underlying-event description:
+<class name="SuppressSmallPT( pT0timesMI, numberAlphaS, useSameAlphaSasMI)">
+suppress small-<ei>pT</ei> production for <ei>2 -> 2</ei> processes
+only, while leaving other processes unaffected. The basic suppression
+factor is <ei>pT^4 / ((k*pT0)^2 + pT^2)^2</ei>, where <ei>pT</ei>
+refers to the current hard subprocess and <ei>pT0</ei> is the same
+energy-dependent dampening scale as used for
+<aloc href="MultipleInteractions">multiple interactions</aloc>.
+The optional arguments provide further variability.
+<argument name="pT0timesMI">
+corresponds to the additional factor <ei>k</ei> in the above formula.
+It is by default equal to 1 but can be used to explore deviations from
+the expected value.
+</argument>
+<argument name="numberAlphaS">
+if this number <ei>n</ei> is bigger than the default 0, the
+corresponding number of <ei>alpha_strong</ei> factors is also
+reweighted from the normal renormalization scale to a modified one,
+i.e. a further suppression factor
+<ei>( alpha_s((k*pT0)^2 + Q^2_ren) / alpha_s(Q^2_ren) )^n</ei>
+is introduced.
+</argument>
+<argument name="useSameAlphaSasMI">
+regulates which kind of new <ei>alpha_strong</ei> value is evaluated
+for the numerator in the above expression. It is by default the same
+as set for multiple interactions (i.e. same starting value at
+<ei>M_Z</ei> and same order of running), but if <code>false</code>
+instead the one for hard subprocesses. The denominator
+<ei>alpha_s(Q^2_ren)</ei> is always the value used for the "original",
+unweighted cross section.
+</argument>
+</class>
+
+<h3>Final comments</h3>
+
+All the possibilities above can be combined freely and also be combined
+with the standard flags. An event would then survive only if it survived
+each of the possible veto methods. There are no hidden interdependencies
+in this game, but of course some combinations may not be particularly
+meaningful. For instance, if you set <code>PartonLevel:all = off</code>
+then the <code>doVetoPT(...)</code> and <code>doVetoPartonLevel(...)</code>
+locations in the code are not even reached, so they would never be called.
+
+<p/>
+An example how the above methods can be used for toy studies is found in
+<code>main10.cc</code>.
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Version">
+
+<h2>Version</h2>
+
+The settings on this page should not be changed by the ordinary user,
+but appear here for documentation purposes, and so that they can
+form part of the standard databases and be queried accordingly.
+
+<parmfix name="Pythia:versionNumber" default="8.108">
+Version and subversion number, with three significant decimals.
+</parmfix>
+
+<modefix name="Pythia:versionDate" default="20080501">
+Last date of change of current (sub)version, in format yyyymmdd.
+</modefix>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->
--- /dev/null
+<chapter name="Welcome">
+
+<frameset cols="260,*" framespacing="0" frameborder="0" border="0">
+<frame src="Index.xml" name="index" scrolling="auto" border="0"
+ marginwidth="20" marginheight="20" frameborder="0">
+</frame>
+<frame src="Frontpage.xml" name="page" scrolling="auto" border="0"
+ marginwidth="20" marginheight="20" frameborder="0">
+</frame>
+</frameset>
+
+</chapter>
+
+<!-- Copyright (C) 2008 Torbjorn Sjostrand -->