diff --git a/DipoleShower/Kinematics/DipoleSplittingKinematics.cc b/DipoleShower/Kinematics/DipoleSplittingKinematics.cc --- a/DipoleShower/Kinematics/DipoleSplittingKinematics.cc +++ b/DipoleShower/Kinematics/DipoleSplittingKinematics.cc @@ -1,238 +1,239 @@ // -*- C++ -*- // // DipoleSplittingKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2007 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the DipoleSplittingKinematics class. // #include "DipoleSplittingKinematics.h" #include "Herwig/DipoleShower/Base/DipoleSplittingInfo.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h" #include <limits> using namespace Herwig; DipoleSplittingKinematics::DipoleSplittingKinematics() : HandlerBase(), theIRCutoff(1.0*GeV), theXMin(1.e-5), theJacobian(0.0), theLastPt(0.0*GeV), theLastZ(0.0), theLastPhi(0.0), theLastEmitterZ(1.0), theLastSpectatorZ(1.0), theLastSplittingParameters() {} DipoleSplittingKinematics::~DipoleSplittingKinematics() {} void DipoleSplittingKinematics::persistentOutput(PersistentOStream & os) const { os << ounit(theIRCutoff,GeV) << theXMin << theMCCheck; } void DipoleSplittingKinematics::persistentInput(PersistentIStream & is, int) { is >> iunit(theIRCutoff,GeV) >> theXMin >> theMCCheck; } void DipoleSplittingKinematics::prepareSplitting(DipoleSplittingInfo& dInfo) { dInfo.splittingKinematics(this); if ( lastPt() > IRCutoff() ) dInfo.lastPt(lastPt()); else { dInfo.lastPt(0.0*GeV); dInfo.didStopEvolving(); } dInfo.lastZ(lastZ()); dInfo.lastPhi(lastPhi()); dInfo.lastEmitterZ(lastEmitterZ()); dInfo.lastSpectatorZ(lastSpectatorZ()); dInfo.splittingParameters().resize(lastSplittingParameters().size()); copy(lastSplittingParameters().begin(),lastSplittingParameters().end(), dInfo.splittingParameters().begin()); } Energy DipoleSplittingKinematics::generatePt(double r, Energy dScale, double emX, double specX, const DipoleIndex& dIndex, const DipoleSplittingKernel& split, double& weight) const { Energy maxPt = ptMax(dScale,emX,specX,dIndex,split); if ( maxPt <= IRCutoff() ) { weight = 0.0; return ZERO; } weight *= log(sqr(maxPt/IRCutoff())); return IRCutoff()*pow(maxPt/IRCutoff(),r); } double DipoleSplittingKinematics::ptToRandom(Energy pt, Energy dScale, double emX, double specX, const DipoleIndex& dIndex, const DipoleSplittingKernel& split) const { Energy maxPt = ptMax(dScale,emX,specX,dIndex,split); assert(pt >= IRCutoff() && pt <= maxPt); return log(pt/IRCutoff())/log(maxPt/IRCutoff()); } double DipoleSplittingKinematics::generateZ(double r, Energy pt, int sampling, const DipoleSplittingInfo& dInfo, const DipoleSplittingKernel& split, double& weight) const { pair<double,double> zLims = zBoundaries(pt,dInfo,split); using namespace RandomHelpers; if ( sampling == FlatZ ) { pair<double,double> kw = generate(flat(zLims.first,zLims.second),r); weight *= kw.second; return kw.first; } if ( sampling == OneOverZ ) { pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second),r); weight *= kw.second; return kw.first; } if ( sampling == OneOverOneMinusZ ) { pair<double,double> kw = generate(inverse(1.0,zLims.first,zLims.second),r); weight *= kw.second; return kw.first; } if ( sampling == OneOverZOneMinusZ ) { pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second) + inverse(1.0,zLims.first,zLims.second),r); weight *= kw.second; return kw.first; } weight = 0.0; return 0.0; } Lorentz5Momentum DipoleSplittingKinematics::getKt(const Lorentz5Momentum& p1, const Lorentz5Momentum& p2, Energy pt, double phi, bool spacelike) const { Lorentz5Momentum P; if ( !spacelike ) P = p1 + p2; else P = p1 - p2; Energy2 Q2 = abs(P.m2()); Lorentz5Momentum Q = !spacelike ? Lorentz5Momentum(ZERO,ZERO,ZERO,sqrt(Q2),sqrt(Q2)) : Lorentz5Momentum(ZERO,ZERO,sqrt(Q2),ZERO,-sqrt(Q2)); if ( spacelike && Q.z() < P.z() ) Q.setZ(-Q.z()); bool boost = abs((P-Q).vect().mag2()/GeV2) > 1e-10 || abs((P-Q).t()/GeV) > 1e-5; + boost &= (P*Q-Q.mass2())/GeV2 > 1e-8; Lorentz5Momentum inFrame1; if ( boost ) inFrame1 = p1 + ((P*p1-Q*p1)/(P*Q-Q.mass2()))*(P-Q); else inFrame1 = p1; Energy ptx = inFrame1.x(); Energy pty = inFrame1.y(); Energy q = 2.*inFrame1.z(); Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q)); Energy Qy = sqrt(4.*sqr(pty)+sqr(q)); double cPhi = cos(phi); double sPhi = sqrt(1.-sqr(cPhi)); if ( phi > Constants::pi ) sPhi = -sPhi; Lorentz5Momentum kt; if ( !spacelike ) { kt.setT(ZERO); kt.setX(pt*Qy*cPhi/Qp); kt.setY(-pt*(4*ptx*pty*cPhi/Qp+q*sPhi)/Qy); kt.setZ(2.*pt*(-ptx*q*cPhi/Qp + pty*sPhi)/Qy); } else { kt.setT(2.*pt*(ptx*q*cPhi+pty*Qp*sPhi)/(q*Qy)); kt.setX(pt*(Qp*q*cPhi+4.*ptx*pty*sPhi)/(q*Qy)); kt.setY(pt*Qy*sPhi/q); kt.setZ(ZERO); } if ( boost ) kt = kt + ((P*kt-Q*kt)/(P*Q-Q.mass2()))*(P-Q); kt.setMass(-pt); kt.rescaleRho(); return kt; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). AbstractClassDescription<DipoleSplittingKinematics> DipoleSplittingKinematics::initDipoleSplittingKinematics; // Definition of the static class description member. void DipoleSplittingKinematics::Init() { static ClassDocumentation<DipoleSplittingKinematics> documentation ("DipoleSplittingKinematics is the base class for dipole splittings " "as performed in the dipole shower."); static Parameter<DipoleSplittingKinematics,Energy> interfaceIRCutoff ("IRCutoff", "The IR cutoff to be used by this splitting kinematics.", &DipoleSplittingKinematics::theIRCutoff, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<DipoleSplittingKinematics,double> interfaceXMin ("XMin", "The minimum momentum fraction for incoming partons", &DipoleSplittingKinematics::theXMin, 1.0e-5, 0.0, 1.0, false, false, Interface::limited); static Reference<DipoleSplittingKinematics,DipoleMCCheck> interfaceMCCheck ("MCCheck", "[debug option] MCCheck", &DipoleSplittingKinematics::theMCCheck, false, false, true, true, false); interfaceMCCheck.rank(-1); } diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc --- a/MatrixElement/Matchbox/Base/MatchboxMEBase.cc +++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.cc @@ -1,1708 +1,1722 @@ // -*- C++ -*- // // MatchboxMEBase.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2012 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the MatchboxMEBase class. // #include "MatchboxMEBase.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/PDF/PDF.h" #include "ThePEG/PDT/PDT.h" #include "ThePEG/StandardModel/StandardModelBase.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Handlers/StdXCombGroup.h" #include "ThePEG/EventRecord/SubProcess.h" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" #include "Herwig/MatrixElement/Matchbox/Utility/DiagramDrawer.h" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h" #include "Herwig/Utilities/RunDirectories.h" #include "Herwig/MatrixElement/ProductionMatrixElement.h" #include "Herwig/MatrixElement/HardVertex.h" #include <boost/foreach.hpp> #include <cctype> #include <iterator> using std::ostream_iterator; using namespace Herwig; MatchboxMEBase::MatchboxMEBase() : MEBase(), theOneLoop(false), theOneLoopNoBorn(false), theOneLoopNoLoops(false), theNoCorrelations(false), theHavePDFs(false,false), checkedPDFs(false), theDiagramWeightVerboseDown(10000000000000.), theDiagramWeightVerboseUp(0.) {} MatchboxMEBase::~MatchboxMEBase() {} Ptr<MatchboxFactory>::tptr MatchboxMEBase::factory() const { return theFactory; } void MatchboxMEBase::factory(Ptr<MatchboxFactory>::tptr f) { theFactory = f; } Ptr<Tree2toNGenerator>::tptr MatchboxMEBase::diagramGenerator() const { return factory()->diagramGenerator(); } Ptr<ProcessData>::tptr MatchboxMEBase::processData() const { return factory()->processData(); } unsigned int MatchboxMEBase::getNLight() const { return factory()->nLight(); } vector<int> MatchboxMEBase::getNLightJetVec() const { return factory()->nLightJetVec(); } vector<int> MatchboxMEBase::getNHeavyJetVec() const { return factory()->nHeavyJetVec(); } vector<int> MatchboxMEBase::getNLightProtonVec() const { return factory()->nLightProtonVec(); } double MatchboxMEBase::factorizationScaleFactor() const { return factory()->factorizationScaleFactor(); } double MatchboxMEBase::renormalizationScaleFactor() const { return factory()->renormalizationScaleFactor(); } bool MatchboxMEBase::fixedCouplings() const { return factory()->fixedCouplings(); } bool MatchboxMEBase::fixedQEDCouplings() const { return factory()->fixedQEDCouplings(); } bool MatchboxMEBase::checkPoles() const { return factory()->checkPoles(); } bool MatchboxMEBase::verbose() const { return factory()->verbose(); } bool MatchboxMEBase::initVerbose() const { return factory()->initVerbose(); } void MatchboxMEBase::getDiagrams() const { if ( diagramGenerator() && processData() ) { vector<Ptr<Tree2toNDiagram>::ptr> diags; vector<Ptr<Tree2toNDiagram>::ptr>& res = processData()->diagramMap()[subProcess().legs]; if ( res.empty() ) { res = diagramGenerator()->generate(subProcess().legs,orderInAlphaS(),orderInAlphaEW()); } copy(res.begin(),res.end(),back_inserter(diags)); processData()->fillMassGenerators(subProcess().legs); if ( diags.empty() ) return; for ( vector<Ptr<Tree2toNDiagram>::ptr>::iterator d = diags.begin(); d != diags.end(); ++d ) { add(*d); } return; } throw Exception() << "MatchboxMEBase::getDiagrams() expects a Tree2toNGenerator and ProcessData object.\n" << "Please check your setup." << Exception::runerror; } Selector<MEBase::DiagramIndex> MatchboxMEBase::diagrams(const DiagramVector & diags) const { if ( phasespace() ) { return phasespace()->selectDiagrams(diags); } throw Exception() << "MatchboxMEBase::diagrams() expects a MatchboxPhasespace object.\n" << "Please check your setup." << Exception::runerror; return Selector<MEBase::DiagramIndex>(); } Selector<const ColourLines *> MatchboxMEBase::colourGeometries(tcDiagPtr diag) const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->haveColourFlows() ) { if ( matchboxAmplitude()->treeAmplitudes() ) matchboxAmplitude()->prepareAmplitudes(this); return matchboxAmplitude()->colourGeometries(diag); } } Ptr<Tree2toNDiagram>::tcptr tdiag = dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag); assert(diag && processData()); vector<ColourLines*>& flows = processData()->colourFlowMap()[tdiag]; if ( flows.empty() ) { list<list<list<pair<int,bool> > > > cflows = ColourBasis::colourFlows(tdiag); for ( list<list<list<pair<int,bool> > > >::const_iterator fit = cflows.begin(); fit != cflows.end(); ++fit ) { flows.push_back(new ColourLines(ColourBasis::cfstring(*fit))); } } Selector<const ColourLines *> res; for ( vector<ColourLines*>::const_iterator f = flows.begin(); f != flows.end(); ++f ) res.insert(1.0,*f); return res; } void MatchboxMEBase::constructVertex(tSubProPtr sub, const ColourLines* cl) { if ( !canFillRhoMatrix() || !factory()->spinCorrelations() ) return; assert(matchboxAmplitude()); assert(matchboxAmplitude()->colourBasis()); // get the colour structure for the selected colour flow size_t cStructure = matchboxAmplitude()->colourBasis()->tensorIdFromFlow(lastXComb().lastDiagram(),cl); // hard process for processing the spin info tPVector hard; hard.push_back(sub->incoming().first); hard.push_back(sub->incoming().second); vector<PDT::Spin> out; for ( size_t k = 0; k < sub->outgoing().size(); ++k ) { out.push_back(sub->outgoing()[k]->data().iSpin()); hard.push_back(sub->outgoing()[k]); } // calculate dummy wave functions to fill the spin info static vector<VectorWaveFunction> dummyPolarizations; static vector<SpinorWaveFunction> dummySpinors; static vector<SpinorBarWaveFunction> dummyBarSpinors; for ( size_t k = 0; k < hard.size(); ++k ) { if ( hard[k]->data().iSpin() == PDT::Spin1Half ) { if ( hard[k]->id() > 0 && k > 1 ) { SpinorBarWaveFunction(dummyBarSpinors,hard[k], outgoing, true); } else if ( hard[k]->id() < 0 && k > 1 ) { SpinorWaveFunction(dummySpinors,hard[k], outgoing, true); } else if ( hard[k]->id() > 0 && k < 2 ) { SpinorWaveFunction(dummySpinors,hard[k], incoming, false); } else if ( hard[k]->id() < 0 && k < 2 ) { SpinorBarWaveFunction(dummyBarSpinors,hard[k], incoming, false); } } else if ( hard[k]->data().iSpin() == PDT::Spin1 ) { VectorWaveFunction(dummyPolarizations,hard[k], k > 1 ? outgoing : incoming, k > 1 ? true : false, hard[k]->data().hardProcessMass() == ZERO); } else if (hard[k]->data().iSpin() == PDT::Spin0 ) { ScalarWaveFunction(hard[k],k > 1 ? outgoing : incoming, k > 1 ? true : false); } else assert(false); } // fill the production matrix element ProductionMatrixElement pMe(mePartonData()[0]->iSpin(), mePartonData()[1]->iSpin(), out); for ( map<vector<int>,CVector>::const_iterator lamp = lastLargeNAmplitudes().begin(); lamp != lastLargeNAmplitudes().end(); ++lamp ) { vector<unsigned int> pMeHelicities = matchboxAmplitude()->physicalHelicities(lamp->first); pMe(pMeHelicities) = lamp->second[cStructure]; } // set the spin information HardVertexPtr hardvertex = new_ptr(HardVertex()); hardvertex->ME(pMe); if ( sub->incoming().first->spinInfo() ) sub->incoming().first->spinInfo()->productionVertex(hardvertex); if ( sub->incoming().second->spinInfo() ) sub->incoming().second->spinInfo()->productionVertex(hardvertex); for ( ParticleVector::const_iterator p = sub->outgoing().begin(); p != sub->outgoing().end(); ++p ) { if ( (**p).spinInfo() ) (**p).spinInfo()->productionVertex(hardvertex); } } unsigned int MatchboxMEBase::orderInAlphaS() const { return subProcess().orderInAlphaS; } unsigned int MatchboxMEBase::orderInAlphaEW() const { return subProcess().orderInAlphaEW; } void MatchboxMEBase::setXComb(tStdXCombPtr xc) { MEBase::setXComb(xc); lastMatchboxXComb(xc); if ( phasespace() ) phasespace()->setXComb(xc); if ( scaleChoice() ) scaleChoice()->setXComb(xc); if ( matchboxAmplitude() ) matchboxAmplitude()->setXComb(xc); } double MatchboxMEBase::generateIncomingPartons(const double* r1, const double* r2) { // shamelessly stolen from PartonExtractor.cc Energy2 shmax = lastCuts().sHatMax(); Energy2 shmin = lastCuts().sHatMin(); Energy2 sh = shmin*pow(shmax/shmin, *r1); double ymax = lastCuts().yHatMax(); double ymin = lastCuts().yHatMin(); double km = log(shmax/shmin); ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/sh))); ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/sh))); double y = ymin + (*r2)*(ymax - ymin); double x1 = exp(-0.5*log(lastS()/sh) + y); double x2 = exp(-0.5*log(lastS()/sh) - y); Lorentz5Momentum P1 = lastParticles().first->momentum(); LorentzMomentum p1 = lightCone((P1.rho() + P1.e())*x1, Energy()); p1.rotateY(P1.theta()); p1.rotateZ(P1.phi()); meMomenta()[0] = p1; Lorentz5Momentum P2 = lastParticles().second->momentum(); LorentzMomentum p2 = lightCone((P2.rho() + P2.e())*x2, Energy()); p2.rotateY(P2.theta()); p2.rotateZ(P2.phi()); meMomenta()[1] = p2; lastXCombPtr()->lastX1X2(make_pair(x1,x2)); lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2()); return km*(ymax - ymin); } bool MatchboxMEBase::generateKinematics(const double * r) { if ( phasespace() ) { jacobian(phasespace()->generateKinematics(r,meMomenta())); if ( jacobian() == 0.0 ) return false; setScale(); logGenerateKinematics(r); assert(lastMatchboxXComb()); if ( nDimAmplitude() > 0 ) { amplitudeRandomNumbers().resize(nDimAmplitude()); copy(r + nDimPhasespace(), r + nDimPhasespace() + nDimAmplitude(), amplitudeRandomNumbers().begin()); } if ( nDimInsertions() > 0 ) { insertionRandomNumbers().resize(nDimInsertions()); copy(r + nDimPhasespace() + nDimAmplitude(), r + nDimPhasespace() + nDimAmplitude() + nDimInsertions(), insertionRandomNumbers().begin()); } return true; } throw Exception() << "MatchboxMEBase::generateKinematics() expects a MatchboxPhasespace object.\n" << "Please check your setup." << Exception::runerror; return false; } int MatchboxMEBase::nDim() const { if ( lastMatchboxXComb() ) return nDimPhasespace() + nDimAmplitude() + nDimInsertions(); int ampAdd = 0; if ( matchboxAmplitude() ) { ampAdd = matchboxAmplitude()->nDimAdditional(); } int insertionAdd = 0; for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { insertionAdd = max(insertionAdd,(**v).nDimAdditional()); } return nDimBorn() + ampAdd + insertionAdd; } int MatchboxMEBase::nDimBorn() const { if ( lastMatchboxXComb() ) return nDimPhasespace(); if ( phasespace() ) return phasespace()->nDim(diagrams().front()->partons()); throw Exception() << "MatchboxMEBase::nDim() expects a MatchboxPhasespace object.\n" << "Please check your setup." << Exception::runerror; return 0; } void MatchboxMEBase::setScale() const { if ( haveX1X2() ) { lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2()); } Energy2 fcscale = factorizationScale(); Energy2 fscale = fcscale*sqr(factorizationScaleFactor()); Energy2 rscale = renormalizationScale()*sqr(renormalizationScaleFactor()); Energy2 ewrscale = renormalizationScaleQED(); lastXCombPtr()->lastScale(fscale); lastXCombPtr()->lastCentralScale(fcscale); + lastXCombPtr()->lastShowerScale(showerScale()); lastMatchboxXComb()->lastRenormalizationScale(rscale); if ( !fixedCouplings() ) { if ( rscale > lastCuts().scaleMin() ) lastXCombPtr()->lastAlphaS(SM().alphaS(rscale)); else lastXCombPtr()->lastAlphaS(SM().alphaS(lastCuts().scaleMin())); } else { lastXCombPtr()->lastAlphaS(SM().alphaS()); } if ( !fixedQEDCouplings() ) { lastXCombPtr()->lastAlphaEM(SM().alphaEMME(ewrscale)); } else { lastXCombPtr()->lastAlphaEM(SM().alphaEMMZ()); } logSetScale(); } Energy2 MatchboxMEBase::factorizationScale() const { if ( scaleChoice() ) { return scaleChoice()->factorizationScale(); } throw Exception() << "MatchboxMEBase::factorizationScale() expects a MatchboxScaleChoice object.\n" << "Please check your setup." << Exception::runerror; return ZERO; } Energy2 MatchboxMEBase::renormalizationScale() const { if ( scaleChoice() ) { return scaleChoice()->renormalizationScale(); } throw Exception() << "MatchboxMEBase::renormalizationScale() expects a MatchboxScaleChoice object.\n" << "Please check your setup." << Exception::runerror; return ZERO; } Energy2 MatchboxMEBase::renormalizationScaleQED() const { if ( scaleChoice() ) { return scaleChoice()->renormalizationScaleQED(); } return renormalizationScale(); } +Energy2 MatchboxMEBase::showerScale() const { + if ( scaleChoice() ) { + return scaleChoice()->showerScale(); + } + + throw Exception() + << "MatchboxMEBase::showerScale() expects a MatchboxScaleChoice object.\n" + << "Please check your setup." << Exception::runerror; + + return ZERO; + +} + void MatchboxMEBase::setVetoScales(tSubProPtr) const {} bool MatchboxMEBase::havePDFWeight1() const { if ( checkedPDFs ) return theHavePDFs.first; theHavePDFs.first = factory()->isIncoming(mePartonData()[0]) && lastXCombPtr()->partonBins().first->pdf(); theHavePDFs.second = factory()->isIncoming(mePartonData()[1]) && lastXCombPtr()->partonBins().second->pdf(); checkedPDFs = true; return theHavePDFs.first; } bool MatchboxMEBase::havePDFWeight2() const { if ( checkedPDFs ) return theHavePDFs.second; theHavePDFs.first = factory()->isIncoming(mePartonData()[0]) && lastXCombPtr()->partonBins().first->pdf(); theHavePDFs.second = factory()->isIncoming(mePartonData()[1]) && lastXCombPtr()->partonBins().second->pdf(); checkedPDFs = true; return theHavePDFs.second; } void MatchboxMEBase::getPDFWeight(Energy2 factorizationScale) const { if ( !havePDFWeight1() && !havePDFWeight2() ) { lastMEPDFWeight(1.0); logPDFWeight(); return; } double w = 1.; if ( havePDFWeight1() ) w *= pdf1(factorizationScale); if ( havePDFWeight2() ) w *= pdf2(factorizationScale); lastMEPDFWeight(w); logPDFWeight(); } double MatchboxMEBase::pdf1(Energy2 fscale, double xEx, double xFactor) const { assert(lastXCombPtr()->partonBins().first->pdf()); if ( xEx < 1. && lastX1()*xFactor >= xEx ) { return ( ( 1. - lastX1()*xFactor ) / ( 1. - xEx ) ) * lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(), lastPartons().first->dataPtr(), fscale == ZERO ? lastScale() : fscale, xEx)/xEx; } return lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(), lastPartons().first->dataPtr(), fscale == ZERO ? lastScale() : fscale, lastX1()*xFactor)/lastX1()/xFactor; } double MatchboxMEBase::pdf2(Energy2 fscale, double xEx, double xFactor) const { assert(lastXCombPtr()->partonBins().second->pdf()); if ( xEx < 1. && lastX2()*xFactor >= xEx ) { return ( ( 1. - lastX2()*xFactor ) / ( 1. - xEx ) ) * lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(), lastPartons().second->dataPtr(), fscale == ZERO ? lastScale() : fscale, xEx)/xEx; } return lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(), lastPartons().second->dataPtr(), fscale == ZERO ? lastScale() : fscale, lastX2()*xFactor)/lastX2()/xFactor; } double MatchboxMEBase::me2() const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->treeAmplitudes() ) matchboxAmplitude()->prepareAmplitudes(this); double res = matchboxAmplitude()->me2()* me2Norm(); return res; } throw Exception() << "MatchboxMEBase::me2() expects a MatchboxAmplitude object.\n" << "Please check your setup." << Exception::runerror; return 0.; } double MatchboxMEBase::largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->treeAmplitudes() ) { largeNBasis->prepare(mePartonData(),false); matchboxAmplitude()->prepareAmplitudes(this); } double res = matchboxAmplitude()->largeNME2(largeNBasis)* me2Norm(); return res; } throw Exception() << "MatchboxMEBase::largeNME2() expects a MatchboxAmplitude object.\n" << "Please check your setup." << Exception::runerror; return 0.; } double MatchboxMEBase::finalStateSymmetry() const { if ( symmetryFactor() > 0.0 ) return symmetryFactor(); double sFactor = 1.; map<long,int> counts; cPDVector checkData; copy(mePartonData().begin()+2,mePartonData().end(),back_inserter(checkData)); cPDVector::iterator p = checkData.begin(); while ( !checkData.empty() ) { if ( counts.find((**p).id()) != counts.end() ) { counts[(**p).id()] += 1; } else { counts[(**p).id()] = 1; } checkData.erase(p); p = checkData.begin(); continue; } for ( map<long,int>::const_iterator c = counts.begin(); c != counts.end(); ++c ) { if ( c->second == 1 ) continue; if ( c->second == 2 ) sFactor /= 2.; else if ( c->second == 3 ) sFactor /= 6.; else if ( c->second == 4 ) sFactor /= 24.; } symmetryFactor(sFactor); return symmetryFactor(); } double MatchboxMEBase::me2Norm(unsigned int addAlphaS) const { // assume that we always have incoming // spin-1/2 or massless spin-1 particles double fac = 1./4.; if ( hasInitialAverage() ) fac = 1.; double couplings = 1.0; if ( (orderInAlphaS() > 0 || addAlphaS != 0) && !hasRunningAlphaS() ) { fac *= pow(lastAlphaS()/SM().alphaS(),double(orderInAlphaS()+addAlphaS)); couplings *= pow(lastAlphaS(),double(orderInAlphaS()+addAlphaS)); } if ( orderInAlphaEW() > 0 && !hasRunningAlphaEW() ) { fac *= pow(lastAlphaEM()/SM().alphaEMMZ(),double(orderInAlphaEW())); couplings *= pow(lastAlphaEM(),double(orderInAlphaEW())); } lastMECouplings(couplings); if ( !hasInitialAverage() ) { if ( mePartonData()[0]->iColour() == PDT::Colour3 || mePartonData()[0]->iColour() == PDT::Colour3bar ) fac /= SM().Nc(); else if ( mePartonData()[0]->iColour() == PDT::Colour8 ) fac /= (SM().Nc()*SM().Nc()-1.); if ( mePartonData()[1]->iColour() == PDT::Colour3 || mePartonData()[1]->iColour() == PDT::Colour3bar ) fac /= SM().Nc(); else if ( mePartonData()[1]->iColour() == PDT::Colour8 ) fac /= (SM().Nc()*SM().Nc()-1.); } return !hasFinalStateSymmetry() ? finalStateSymmetry()*fac : fac; } CrossSection MatchboxMEBase::dSigHatDR() const { getPDFWeight(); if ( !lastXCombPtr()->willPassCuts() ) { lastMECrossSection(ZERO); return lastMECrossSection(); } double xme2 = me2(); if (factory()->verboseDia()){ double diagweightsum = 0.0; for ( vector<Ptr<DiagramBase>::ptr>::const_iterator d = diagrams().begin(); d != diagrams().end(); ++d ) { diagweightsum += phasespace()->diagramWeight(dynamic_cast<const Tree2toNDiagram&>(**d)); } double piWeight = pow(2.*Constants::pi,(int)(3*(meMomenta().size()-2)-4)); double units = pow(lastSHat() / GeV2, mePartonData().size() - 4.); bookMEoverDiaWeight(log(xme2/(diagweightsum*piWeight*units)));// } if ( xme2 == 0. && !oneLoopNoBorn() ) { lastMECrossSection(ZERO); return lastMECrossSection(); } double vme2 = 0.; if ( oneLoop() && !oneLoopNoLoops() ) vme2 = oneLoopInterference(); CrossSection res = ZERO; if ( !oneLoopNoBorn() ) res += (sqr(hbarc)/(2.*lastSHat())) * jacobian()* lastMEPDFWeight() * xme2; if ( oneLoop() && !oneLoopNoLoops() ) res += (sqr(hbarc)/(2.*lastSHat())) * jacobian()* lastMEPDFWeight() * vme2; if ( !onlyOneLoop() ) { for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { (**v).setXComb(lastXCombPtr()); res += (**v).dSigHatDR(); } if ( checkPoles() && oneLoop() ) logPoles(); } double weight = 0.0; bool applied = false; for ( vector<Ptr<MatchboxReweightBase>::ptr>::const_iterator rw = theReweights.begin(); rw != theReweights.end(); ++rw ) { (**rw).setXComb(lastXCombPtr()); if ( !(**rw).apply() ) continue; weight += (**rw).evaluate(); applied = true; } if ( applied ) res *= weight; lastMECrossSection(res); return lastMECrossSection(); } double MatchboxMEBase::oneLoopInterference() const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->oneLoopAmplitudes() ) matchboxAmplitude()->prepareOneLoopAmplitudes(this); double res = matchboxAmplitude()->oneLoopInterference()* me2Norm(1); return res; } throw Exception() << "MatchboxMEBase::oneLoopInterference() expects a MatchboxAmplitude object.\n" << "Please check your setup." << Exception::runerror; return 0.; } MatchboxMEBase::AccuracyHistogram::AccuracyHistogram(double low, double up, unsigned int nbins) : lower(low), upper(up), sameSign(0), oppositeSign(0), nans(0), overflow(0), underflow(0) { double step = (up-low)/nbins; for ( unsigned int k = 1; k <= nbins; ++k ) bins[lower + k*step] = 0.0; } void MatchboxMEBase::AccuracyHistogram::book(double a, double b) { if ( isnan(a) || isnan(b) || isinf(a) || isinf(b) ) { ++nans; return; } if ( a*b >= 0. ) ++sameSign; if ( a*b < 0. ) ++oppositeSign; double r = 1.; if ( abs(a) != 0.0 ) r = abs(1.-abs(b/a)); else if ( abs(b) != 0.0 ) r = abs(b); if ( log10(r) < lower || r == 0.0 ) { ++underflow; return; } if ( log10(r) > upper ) { ++overflow; return; } map<double,double>::iterator bin = bins.upper_bound(log10(r)); if ( bin == bins.end() ) return; bin->second += 1.; } void MatchboxMEBase::AccuracyHistogram::dump(const std::string& folder, const std::string& prefix, const cPDVector& proc) const { ostringstream fname(""); for ( cPDVector::const_iterator p = proc.begin(); p != proc.end(); ++p ) fname << (**p).PDGName(); ofstream out((folder+"/"+prefix+fname.str()+".dat").c_str()); out << "# same sign : " << sameSign << " opposite sign : " << oppositeSign << " nans : " << nans << " overflow : " << overflow << " underflow : " << underflow << "\n"; for ( map<double,double>::const_iterator b = bins.begin(); b != bins.end(); ++b ) { map<double,double>::const_iterator bp = b; --bp; if ( b->second != 0. ) { if ( b != bins.begin() ) out << bp->first; else out << lower; out << " " << b->first << " " << b->second << "\n" << flush; } } ofstream gpout((folder+"/"+prefix+fname.str()+".gp").c_str()); gpout << "set terminal png\n" << "set xlabel 'accuracy of pole cancellation [decimal places]'\n" << "set ylabel 'counts\n" << "set xrange [-20:0]\n" << "set output '" << prefix << fname.str() << ".png'\n" << "plot '" << prefix << fname.str() << ".dat' using (0.5*($1+$2)):3 with linespoints pt 7 ps 1 not"; } void MatchboxMEBase::AccuracyHistogram::persistentOutput(PersistentOStream& os) const { os << lower << upper << bins << sameSign << oppositeSign << nans << overflow << underflow; } void MatchboxMEBase::AccuracyHistogram::persistentInput(PersistentIStream& is) { is >> lower >> upper >> bins >> sameSign >> oppositeSign >> nans >> overflow >> underflow; } void MatchboxMEBase::logPoles() const { double res2me = oneLoopDoublePole(); double res1me = oneLoopSinglePole(); double res2i = 0.; double res1i = 0.; for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { res2i += (**v).oneLoopDoublePole(); res1i += (**v).oneLoopSinglePole(); } if (res2me != 0.0 || res2i != 0.0) epsilonSquarePoleHistograms[mePartonData()].book(res2me,res2i); if (res1me != 0.0 || res1i != 0.0) epsilonPoleHistograms[mePartonData()].book(res1me,res1i); } bool MatchboxMEBase::haveOneLoop() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->haveOneLoop(); return false; } bool MatchboxMEBase::onlyOneLoop() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->onlyOneLoop(); return false; } bool MatchboxMEBase::isDRbar() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->isDRbar(); return false; } bool MatchboxMEBase::isDR() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->isDR(); return false; } bool MatchboxMEBase::isCS() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->isCS(); return false; } bool MatchboxMEBase::isBDK() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->isBDK(); return false; } bool MatchboxMEBase::isExpanded() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->isExpanded(); return false; } Energy2 MatchboxMEBase::mu2() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->mu2(); return 0*GeV2; } double MatchboxMEBase::oneLoopDoublePole() const { if ( matchboxAmplitude() ) { return matchboxAmplitude()->oneLoopDoublePole()* me2Norm(1); } return 0.; } double MatchboxMEBase::oneLoopSinglePole() const { if ( matchboxAmplitude() ) { return matchboxAmplitude()->oneLoopSinglePole()* me2Norm(1); } return 0.; } vector<Ptr<SubtractionDipole>::ptr> MatchboxMEBase::getDipoles(const vector<Ptr<SubtractionDipole>::ptr>& dipoles, const vector<Ptr<MatchboxMEBase>::ptr>& borns) const { vector<Ptr<SubtractionDipole>::ptr> res; // keep track of the dipoles we already did set up set<pair<pair<pair<int,int>,int>,pair<Ptr<MatchboxMEBase>::tptr,Ptr<SubtractionDipole>::tptr> > > done; cPDVector rep = diagrams().front()->partons(); int nreal = rep.size(); // now loop over configs for ( int emitter = 0; emitter < nreal; ++emitter ) { list<Ptr<SubtractionDipole>::ptr> matchDipoles; for ( vector<Ptr<SubtractionDipole>::ptr>::const_iterator d = dipoles.begin(); d != dipoles.end(); ++d ) { if ( !(**d).canHandleEmitter(rep,emitter) ) continue; matchDipoles.push_back(*d); } if ( matchDipoles.empty() ) continue; for ( int emission = 2; emission < nreal; ++emission ) { if ( emission == emitter ) continue; list<Ptr<SubtractionDipole>::ptr> matchDipoles2; for ( list<Ptr<SubtractionDipole>::ptr>::const_iterator d = matchDipoles.begin(); d != matchDipoles.end(); ++d ) { if ( !(**d).canHandleSplitting(rep,emitter,emission) ) continue; matchDipoles2.push_back(*d); } if ( matchDipoles2.empty() ) continue; map<Ptr<DiagramBase>::ptr,SubtractionDipole::MergeInfo> mergeInfo; for ( DiagramVector::const_iterator d = diagrams().begin(); d != diagrams().end(); ++d ) { Ptr<Tree2toNDiagram>::ptr check = new_ptr(Tree2toNDiagram(*dynamic_ptr_cast<Ptr<Tree2toNDiagram>::ptr>(*d))); map<int,int> theMergeLegs; for ( unsigned int i = 0; i < check->external().size(); ++i ) theMergeLegs[i] = -1; int theEmitter = check->mergeEmission(emitter,emission,theMergeLegs); // no underlying Born if ( theEmitter == -1 ) continue; SubtractionDipole::MergeInfo info; info.diagram = check; info.emitter = theEmitter; info.mergeLegs = theMergeLegs; mergeInfo[*d] = info; } if ( mergeInfo.empty() ) continue; for ( int spectator = 0; spectator < nreal; ++spectator ) { if ( spectator == emitter || spectator == emission ) continue; list<Ptr<SubtractionDipole>::ptr> matchDipoles3; for ( list<Ptr<SubtractionDipole>::ptr>::const_iterator d = matchDipoles2.begin(); d != matchDipoles2.end(); ++d ) { if ( !(**d).canHandleSpectator(rep,spectator) ) continue; matchDipoles3.push_back(*d); } if ( matchDipoles3.empty() ) continue; if ( noDipole(emitter,emission,spectator) ) continue; for ( list<Ptr<SubtractionDipole>::ptr>::const_iterator d = matchDipoles3.begin(); d != matchDipoles3.end(); ++d ) { if ( !(**d).canHandle(rep,emitter,emission,spectator) ) continue; for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator b = borns.begin(); b != borns.end(); ++b ) { if ( (**b).onlyOneLoop() ) continue; if ( done.find(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*b,*d))) != done.end() ) continue; // now get to work (**d).clearBookkeeping(); (**d).factory(factory()); (**d).realEmitter(emitter); (**d).realEmission(emission); (**d).realSpectator(spectator); (**d).realEmissionME(const_cast<MatchboxMEBase*>(this)); (**d).underlyingBornME(*b); (**d).setupBookkeeping(mergeInfo); if ( !((**d).empty()) ) { res.push_back((**d).cloneMe()); Ptr<SubtractionDipole>::tptr nDipole = res.back(); done.insert(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*b,*d))); if ( nDipole->isSymmetric() ) done.insert(make_pair(make_pair(make_pair(emission,emitter),spectator),make_pair(*b,*d))); ostringstream dname; dname << fullName() << "." << (**b).name() << "." << (**d).name() << ".[(" << emitter << "," << emission << ")," << spectator << "]"; if ( ! (generator()->preinitRegister(nDipole,dname.str()) ) ) throw Exception() << "MatchboxMEBase::getDipoles(): Dipole " << dname.str() << " already existing." << Exception::runerror; if ( !factory()->reweighters().empty() ) { for ( vector<ReweightPtr>::const_iterator rw = factory()->reweighters().begin(); rw != factory()->reweighters().end(); ++rw ) nDipole->addReweighter(*rw); } if ( !factory()->preweighters().empty() ) { for ( vector<ReweightPtr>::const_iterator rw = factory()->preweighters().begin(); rw != factory()->preweighters().end(); ++rw ) nDipole->addPreweighter(*rw); } nDipole->cloneDependencies(dname.str()); } } } } } } vector<Ptr<SubtractionDipole>::tptr> partners; copy(res.begin(),res.end(),back_inserter(partners)); for ( vector<Ptr<SubtractionDipole>::ptr>::iterator d = res.begin(); d != res.end(); ++d ) (**d).partnerDipoles(partners); return res; } double MatchboxMEBase::colourCorrelatedME2(pair<int,int> ij) const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->treeAmplitudes() ) matchboxAmplitude()->prepareAmplitudes(this); double res = matchboxAmplitude()->colourCorrelatedME2(ij)* me2Norm(); return res; } throw Exception() << "MatchboxMEBase::colourCorrelatedME2() expects a MatchboxAmplitude object.\n" << "Please check your setup." << Exception::runerror; return 0.; } double MatchboxMEBase::largeNColourCorrelatedME2(pair<int,int> ij, Ptr<ColourBasis>::tptr largeNBasis) const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->treeAmplitudes() ) { largeNBasis->prepare(mePartonData(),false); matchboxAmplitude()->prepareAmplitudes(this); } double res = matchboxAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis)* me2Norm(); return res; } throw Exception() << "MatchboxMEBase::largeNColourCorrelatedME2() expects a MatchboxAmplitude object.\n" << "Please check your setup." << Exception::runerror; return 0.; } double MatchboxMEBase::spinColourCorrelatedME2(pair<int,int> ij, const SpinCorrelationTensor& c) const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->treeAmplitudes() ) matchboxAmplitude()->prepareAmplitudes(this); double res = matchboxAmplitude()->spinColourCorrelatedME2(ij,c)* me2Norm(); return res; } throw Exception() << "MatchboxMEBase::spinColourCorrelatedME2() expects a MatchboxAmplitude object.\n" << "Please check your setup." << Exception::runerror; return 0.; } double MatchboxMEBase::spinCorrelatedME2(pair<int,int> ij, const SpinCorrelationTensor& c) const { if ( matchboxAmplitude() ) { if ( matchboxAmplitude()->treeAmplitudes() ) matchboxAmplitude()->prepareAmplitudes(this); double res = matchboxAmplitude()->spinCorrelatedME2(ij,c)* me2Norm(); return res; } throw Exception() << "MatchboxMEBase::spinCorrelatedME2() expects a MatchboxAmplitude object.\n" << "Please check your setup." << Exception::runerror; return 0.; } void MatchboxMEBase::flushCaches() { MEBase::flushCaches(); if ( matchboxAmplitude() ) matchboxAmplitude()->flushCaches(); for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator r = reweights().begin(); r != reweights().end(); ++r ) { (**r).flushCaches(); } for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { (**v).flushCaches(); } } void MatchboxMEBase::print(ostream& os) const { os << "--- MatchboxMEBase setup -------------------------------------------------------\n"; os << " '" << name() << "' for subprocess:\n"; os << " "; for ( PDVector::const_iterator pp = subProcess().legs.begin(); pp != subProcess().legs.end(); ++pp ) { os << (**pp).PDGName() << " "; if ( pp == subProcess().legs.begin() + 1 ) os << "-> "; } os << "\n"; os << " including " << (oneLoop() ? "" : "no ") << "virtual corrections"; if ( oneLoopNoBorn() ) os << " without Born contributions"; if ( oneLoopNoLoops() ) os << " without loop contributions"; os << "\n"; if ( oneLoop() && !onlyOneLoop() ) { os << " using insertion operators\n"; for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { os << " '" << (**v).name() << "' with " << ((**v).isDR() ? "" : "C") << "DR/"; if ( (**v).isCS() ) os << "CS"; if ( (**v).isBDK() ) os << "BDK"; if ( (**v).isExpanded() ) os << "expanded"; os << " conventions\n"; } } os << "--------------------------------------------------------------------------------\n"; os << flush; } void MatchboxMEBase::printLastEvent(ostream& os) const { os << "--- MatchboxMEBase last event information --------------------------------------\n"; os << " for matrix element '" << name() << "'\n"; os << " process considered:\n "; int in = 0; for ( cPDVector::const_iterator p = mePartonData().begin(); p != mePartonData().end(); ++p ) { os << (**p).PDGName() << " "; if ( ++in == 2 ) os << " -> "; } os << " kinematic environment as set by the XComb " << lastXCombPtr() << ":\n" << " sqrt(shat)/GeV = " << sqrt(lastSHat()/GeV2) << " x1 = " << lastX1() << " x2 = " << lastX2() << " alphaS = " << lastAlphaS() << "\n"; os << " momenta/GeV generated from random numbers\n "; copy(lastXComb().lastRandomNumbers().begin(), lastXComb().lastRandomNumbers().end(),ostream_iterator<double>(os," ")); os << ":\n "; for ( vector<Lorentz5Momentum>::const_iterator p = meMomenta().begin(); p != meMomenta().end(); ++p ) { os << (*p/GeV) << "\n "; } os << "last cross section/nb calculated was:\n " << (lastMECrossSection()/nanobarn) << " (pdf weight " << lastMEPDFWeight() << ")\n"; os << "--------------------------------------------------------------------------------\n"; os << flush; } void MatchboxMEBase::logGenerateKinematics(const double * r) const { if ( !verbose() ) return; generator()->log() << "'" << name() << "' generated kinematics\nfrom " << nDim() << " random numbers:\n"; copy(r,r+nDim(),ostream_iterator<double>(generator()->log()," ")); generator()->log() << "\n"; generator()->log() << "storing phase space information in XComb " << lastXCombPtr() << "\n"; generator()->log() << "generated phase space point (in GeV):\n"; vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin(); cPDVector::const_iterator dit = mePartonData().begin(); for ( ; pit != meMomenta().end() ; ++pit, ++dit ) generator()->log() << (**dit).PDGName() << " : " << (*pit/GeV) << "\n"; generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n" << "and Jacobian = " << jacobian() << " sHat/GeV2 = " << (lastSHat()/GeV2) << "\n" << flush; } void MatchboxMEBase::logSetScale() const { if ( !verbose() ) return; generator()->log() << "'" << name() << "' set scales using XComb " << lastXCombPtr() << ":\n" << "scale/GeV2 = " << (scale()/GeV2) << " xi_R = " << renormalizationScaleFactor() << " xi_F = " << factorizationScaleFactor() << "\n" << "alpha_s = " << lastAlphaS() << "\n" << flush; } void MatchboxMEBase::logPDFWeight() const { if ( !verbose() ) return; generator()->log() << "'" << name() << "' calculated pdf weight = " << lastMEPDFWeight() << " from XComb " << lastXCombPtr() << "\n" << "x1 = " << lastX1() << " (" << (mePartonData()[0]->coloured() ? "" : "not ") << "used) " << "x2 = " << lastX2() << " (" << (mePartonData()[1]->coloured() ? "" : "not ") << "used)\n" << flush; } void MatchboxMEBase::logME2() const { if ( !verbose() ) return; generator()->log() << "'" << name() << "' evaluated me2 using XComb " << lastXCombPtr() << "\n" << "and phase space point (in GeV):\n"; vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin(); cPDVector::const_iterator dit = mePartonData().begin(); for ( ; pit != meMomenta().end() ; ++pit, ++dit ) generator()->log() << (**dit).PDGName() << " : " << (*pit/GeV) << "\n"; generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n" << "sHat/GeV2 = " << (lastSHat()/GeV2) << "\n" << flush; } void MatchboxMEBase::logDSigHatDR() const { if ( !verbose() ) return; generator()->log() << "'" << name() << "' evaluated cross section using XComb " << lastXCombPtr() << "\n" << "Jacobian = " << jacobian() << " sHat/GeV2 = " << (lastSHat()/GeV2) << " dsig/nb = " << (lastMECrossSection()/nanobarn) << "\n" << flush; } void MatchboxMEBase::cloneDependencies(const std::string& prefix) { if ( phasespace() ) { Ptr<MatchboxPhasespace>::ptr myPhasespace = phasespace()->cloneMe(); ostringstream pname; pname << (prefix == "" ? fullName() : prefix) << "/" << myPhasespace->name(); if ( ! (generator()->preinitRegister(myPhasespace,pname.str()) ) ) throw Exception() << "MatchboxMEBase::cloneDependencies(): Phasespace generator " << pname.str() << " already existing." << Exception::runerror; myPhasespace->cloneDependencies(pname.str()); phasespace(myPhasespace); } theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude()); if ( matchboxAmplitude() ) { Ptr<MatchboxAmplitude>::ptr myAmplitude = matchboxAmplitude()->cloneMe(); ostringstream pname; pname << (prefix == "" ? fullName() : prefix) << "/" << myAmplitude->name(); if ( ! (generator()->preinitRegister(myAmplitude,pname.str()) ) ) throw Exception() << "MatchboxMEBase::cloneDependencies(): Amplitude " << pname.str() << " already existing." << Exception::runerror; myAmplitude->cloneDependencies(pname.str()); matchboxAmplitude(myAmplitude); amplitude(myAmplitude); matchboxAmplitude()->orderInGs(orderInAlphaS()); matchboxAmplitude()->orderInGem(orderInAlphaEW()); } if ( scaleChoice() ) { Ptr<MatchboxScaleChoice>::ptr myScaleChoice = scaleChoice()->cloneMe(); ostringstream pname; pname << (prefix == "" ? fullName() : prefix) << "/" << myScaleChoice->name(); if ( ! (generator()->preinitRegister(myScaleChoice,pname.str()) ) ) throw Exception() << "MatchboxMEBase::cloneDependencies(): Scale choice " << pname.str() << " already existing." << Exception::runerror; scaleChoice(myScaleChoice); } for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw = theReweights.begin(); rw != theReweights.end(); ++rw ) { Ptr<MatchboxReweightBase>::ptr myReweight = (**rw).cloneMe(); ostringstream pname; pname << (prefix == "" ? fullName() : prefix) << "/" << (**rw).name(); if ( ! (generator()->preinitRegister(myReweight,pname.str()) ) ) throw Exception() << "MatchboxMEBase::cloneDependencies(): Reweight " << pname.str() << " already existing." << Exception::runerror; myReweight->cloneDependencies(pname.str()); *rw = myReweight; } for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { Ptr<MatchboxInsertionOperator>::ptr myIOP = (**v).cloneMe(); ostringstream pname; pname << (prefix == "" ? fullName() : prefix) << "/" << (**v).name(); if ( ! (generator()->preinitRegister(myIOP,pname.str()) ) ) throw Exception() << "MatchboxMEBase::cloneDependencies(): Insertion operator " << pname.str() << " already existing." << Exception::runerror; *v = myIOP; } } void MatchboxMEBase::prepareXComb(MatchboxXCombData& xc) const { // fixme We need to pass on the partons from the xcmob here, not // assuming one subprocess per matrix element if ( phasespace() ) xc.nDimPhasespace(phasespace()->nDim(diagrams().front()->partons())); if ( matchboxAmplitude() ) { xc.nDimAmplitude(matchboxAmplitude()->nDimAdditional()); if ( matchboxAmplitude()->colourBasis() ) { size_t cdim = matchboxAmplitude()->colourBasis()->prepare(diagrams(),noCorrelations()); xc.colourBasisDim(cdim); } if ( matchboxAmplitude()->isExternal() ) { xc.externalId(matchboxAmplitude()->externalId(diagrams().front()->partons())); } } int insertionAdd = 0; for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { insertionAdd = max(insertionAdd,(**v).nDimAdditional()); } xc.nDimInsertions(insertionAdd); xc.nLight(getNLight()); for (size_t inlv=0; inlv<getNLightJetVec().size(); ++inlv) xc.nLightJetVec(getNLightJetVec()[inlv]); for (size_t inhv=0; inhv<getNHeavyJetVec().size(); ++inhv) xc.nHeavyJetVec(getNHeavyJetVec()[inhv]); for (size_t inlpv=0; inlpv<getNLightProtonVec().size(); ++inlpv) xc.nLightProtonVec(getNLightProtonVec()[inlpv]); xc.olpId(olpProcess()); if ( initVerbose() ) { ostringstream fname_strm; // only allow alphanumeric, / and _ in filename BOOST_FOREACH (const char c, name()) { switch (c) { case '+' : fname_strm << "+"; break; case '-' : fname_strm << "-"; break; case '~' : fname_strm << "_tilde"; break; case ']' : break; case ',' : fname_strm << "__"; break; default : fname_strm << (isalnum(c) ? c : '_'); break; } } fname_strm << ".diagrams"; const string fname = fname_strm.str(); ifstream test(fname.c_str()); if ( !test ) { test.close(); ofstream out(fname.c_str()); for ( vector<Ptr<DiagramBase>::ptr>::const_iterator d = diagrams().begin(); d != diagrams().end(); ++d ) { DiagramDrawer::drawDiag(out,dynamic_cast<const Tree2toNDiagram&>(**d)); out << "\n"; } } } } StdXCombPtr MatchboxMEBase::makeXComb(Energy newMaxEnergy, const cPDPair & inc, tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler, tPExtrPtr newExtractor, tCascHdlPtr newCKKW, const PBPair & newPartonBins, tCutsPtr newCuts, const DiagramVector & newDiagrams, bool mir, const PartonPairVec&, tStdXCombPtr newHead, tMEPtr newME) { if ( !newME ) newME = this; Ptr<MatchboxXComb>::ptr xc = new_ptr(MatchboxXComb(newMaxEnergy, inc, newEventHandler, newSubProcessHandler, newExtractor, newCKKW, newPartonBins, newCuts, newME, newDiagrams, mir, newHead)); prepareXComb(*xc); return xc; } StdXCombPtr MatchboxMEBase::makeXComb(tStdXCombPtr newHead, const PBPair & newPartonBins, const DiagramVector & newDiagrams, tMEPtr newME) { if ( !newME ) newME = this; Ptr<MatchboxXComb>::ptr xc = new_ptr(MatchboxXComb(newHead, newPartonBins, newME, newDiagrams)); prepareXComb(*xc); return xc; } void MatchboxMEBase::persistentOutput(PersistentOStream & os) const { os << theLastXComb << theFactory << thePhasespace << theAmplitude << theScaleChoice << theVirtuals << theReweights << theSubprocess << theOneLoop << theOneLoopNoBorn << theOneLoopNoLoops << epsilonSquarePoleHistograms << epsilonPoleHistograms << theOLPProcess << theNoCorrelations << theHavePDFs << checkedPDFs<<theDiagramWeightVerboseDown<<theDiagramWeightVerboseUp; } void MatchboxMEBase::persistentInput(PersistentIStream & is, int) { is >> theLastXComb >> theFactory >> thePhasespace >> theAmplitude >> theScaleChoice >> theVirtuals >> theReweights >> theSubprocess >> theOneLoop >> theOneLoopNoBorn >> theOneLoopNoLoops >> epsilonSquarePoleHistograms >> epsilonPoleHistograms >> theOLPProcess >> theNoCorrelations >> theHavePDFs >> checkedPDFs>>theDiagramWeightVerboseDown>>theDiagramWeightVerboseUp; lastMatchboxXComb(theLastXComb); } void MatchboxMEBase::Init() { static ClassDocumentation<MatchboxMEBase> documentation ("MatchboxMEBase is the base class for matrix elements " "in the context of the matchbox NLO interface."); } IBPtr MatchboxMEBase::clone() const { return new_ptr(*this); } IBPtr MatchboxMEBase::fullclone() const { return new_ptr(*this); } void MatchboxMEBase::doinit() { MEBase::doinit(); if ( !theAmplitude ) theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude()); if ( matchboxAmplitude() ) matchboxAmplitude()->init(); if ( phasespace() ) { phasespace()->init(); matchboxAmplitude()->checkReshuffling(phasespace()); } if ( scaleChoice() ) { scaleChoice()->init(); } for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw = theReweights.begin(); rw != theReweights.end(); ++rw ) { (**rw).init(); } for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { (**v).init(); } } void MatchboxMEBase::bookMEoverDiaWeight(double x) const { if (MEoverDiaWeight.size()==0){ theDiagramWeightVerboseDown=min(theDiagramWeightVerboseDown,x*0.9); theDiagramWeightVerboseUp=max(theDiagramWeightVerboseUp,x*1.1); } map<double,double>::iterator bx =MEoverDiaWeight.upper_bound(x); if ( bx == MEoverDiaWeight.end() ) { return; } bx->second += 1.; Nevents++; if (int(Nevents)%1000==0){ ofstream out((RunDirectories::runStorage()+"/"+name()+"-MeoDiaW.dat").c_str()); int i=0; double m=0.; for ( map<double,double>::const_iterator bx = MEoverDiaWeight.begin();bx != MEoverDiaWeight.end(); ++bx,i++ ) { out << " " << bx->first<<" "<<( bx->second/double(Nevents))<<"\n "; m=max(m,bx->second/double(Nevents)); } out.close(); ofstream gpout((RunDirectories::runStorage()+"/"+name()+"-MeoDiaW.gp").c_str()); gpout << "set terminal epslatex color solid\n" << "set output '" << name()<<"-MeoDiaW"<< "-plot.tex'\n" << "#set logscale x\n" << "set xrange [" << theDiagramWeightVerboseDown << ":" << theDiagramWeightVerboseUp << "]\n" << "set yrange [0.:"<<(m*0.95)<<"]\n" << "set xlabel '$log(ME/\\sum DiaW)$'\n" << "set size 0.7,0.7\n" << "plot 1 w lines lc rgbcolor \"#DDDDDD\" notitle, '" << name()<<"-MeoDiaW" << ".dat' with histeps lc rgbcolor \"#00AACC\" t '$"<<name()<<"$'"; gpout.close(); } } void MatchboxMEBase::doinitrun() { MEBase::doinitrun(); if ( matchboxAmplitude() ) matchboxAmplitude()->initrun(); if ( phasespace() ) { phasespace()->initrun(); } if ( scaleChoice() ) { scaleChoice()->initrun(); } for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw = theReweights.begin(); rw != theReweights.end(); ++rw ) { (**rw).initrun(); } for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v = virtuals().begin(); v != virtuals().end(); ++v ) { (**v).initrun(); } if ( factory()->verboseDia() ) { for ( int k = 0; k < factory()->diagramWeightVerboseNBins() ; ++k ) { MEoverDiaWeight[theDiagramWeightVerboseDown+ double(k)*(theDiagramWeightVerboseUp- theDiagramWeightVerboseDown) /double(factory()->diagramWeightVerboseNBins()) ] = 0.; } Nevents=0.; ofstream out("DiagramWeights.sh"); out<<"P=$(pwd)" <<"\ncd "<<RunDirectories::runStorage() <<"\nrm -f DiagramWeights.tex" <<"\n echo \"\\documentclass{article}\" >> DiagramWeights.tex" <<"\n echo \"\\usepackage{amsmath,amsfonts,amssymb,graphicx,color}\" >> DiagramWeights.tex" <<"\n echo \"\\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}\" >> DiagramWeights.tex" <<"\n echo \"\\begin{document}\" >> DiagramWeights.tex" <<"\n echo \"\\setlength{\\parindent}{0cm}\" >> DiagramWeights.tex" <<"\n\n for i in $(ls *.gp | sed s/'\\.gp'//g) ; " <<"\n do" <<"\n echo \"\\input{\"\"$i\"-plot\"}\" >> DiagramWeights.tex" <<"\n done" <<"\n echo \"\\end{document}\" >> DiagramWeights.tex " <<"\n for i in *.gp ; do " <<"\n gnuplot $i " <<"\n done " <<"\n pdflatex DiagramWeights.tex \ncp DiagramWeights.pdf $P"; out.close(); } } void MatchboxMEBase::dofinish() { MEBase::dofinish(); for ( map<cPDVector,AccuracyHistogram>::const_iterator b = epsilonSquarePoleHistograms.begin(); b != epsilonSquarePoleHistograms.end(); ++b ) { b->second.dump(factory()->poleData(),"epsilonSquarePoles-",b->first); } for ( map<cPDVector,AccuracyHistogram>::const_iterator b = epsilonPoleHistograms.begin(); b != epsilonPoleHistograms.end(); ++b ) { b->second.dump(factory()->poleData(),"epsilonPoles-",b->first); } } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass<MatchboxMEBase,MEBase> describeHerwigMatchboxMEBase("Herwig::MatchboxMEBase", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.h b/MatrixElement/Matchbox/Base/MatchboxMEBase.h --- a/MatrixElement/Matchbox/Base/MatchboxMEBase.h +++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.h @@ -1,1137 +1,1142 @@ // -*- C++ -*- // // MatchboxMEBase.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2012 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef HERWIG_MatchboxMEBase_H #define HERWIG_MatchboxMEBase_H // // This is the declaration of the MatchboxMEBase class. // #include "ThePEG/MatrixElement/MEBase.h" #include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h" #include "Herwig/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h" #include "Herwig/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h" #include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxReweightBase.h" #include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.fh" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh" #include "Herwig/MatrixElement/Matchbox/InsertionOperators/MatchboxInsertionOperator.h" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh" #include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h" #include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXComb.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief MatchboxMEBase is the base class for matrix elements * in the context of the matchbox NLO interface. * * @see \ref MatchboxMEBaseInterfaces "The interfaces" * defined for MatchboxMEBase. */ class MatchboxMEBase: public MEBase, public LastMatchboxXCombInfo { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ MatchboxMEBase(); /** * The destructor. */ virtual ~MatchboxMEBase(); //@} public: /** * Return the factory which produced this matrix element */ Ptr<MatchboxFactory>::tptr factory() const; /** * Set the factory which produced this matrix element */ void factory(Ptr<MatchboxFactory>::tptr f); /** @name Subprocess and diagram information. */ //@{ /** * Return the subprocess. */ const Process& subProcess() const { return theSubprocess; } /** * Access the subprocess. */ Process& subProcess() { return theSubprocess; } /** * Return the diagram generator. */ Ptr<Tree2toNGenerator>::tptr diagramGenerator() const; /** * Return the process data. */ Ptr<ProcessData>::tptr processData() const; /** * Return true, if this matrix element does not want to * make use of mirroring processes; in this case all * possible partonic subprocesses with a fixed assignment * of incoming particles need to be provided through the diagrams * added with the add(...) method. */ virtual bool noMirror () const { return true; } /** * Add all possible diagrams with the add() function. */ virtual void getDiagrams() const; using MEBase::getDiagrams; /** * With the information previously supplied with the * setKinematics(...) method, a derived class may optionally * override this method to weight the given diagrams with their * (although certainly not physical) relative probabilities. */ virtual Selector<DiagramIndex> diagrams(const DiagramVector &) const; using MEBase::diagrams; /** * Return a Selector with possible colour geometries for the selected * diagram weighted by their relative probabilities. */ virtual Selector<const ColourLines *> colourGeometries(tcDiagPtr diag) const; /** * Return true, if this amplitude is capable of consistently filling * the rho matrices for the spin correllations */ virtual bool canFillRhoMatrix() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->canFillRhoMatrix(); return false; } /** * construct the spin information for the interaction */ virtual void constructVertex(tSubProPtr) {} /** * construct the spin information for the interaction */ virtual void constructVertex(tSubProPtr sub, const ColourLines* cl); /** * Return the order in \f$\alpha_S\f$ in which this matrix element * is given. */ virtual unsigned int orderInAlphaS() const; using MEBase::orderInAlphaS; /** * Return the order in \f$\alpha_{EM}\f$ in which this matrix * element is given. Returns 0. */ virtual unsigned int orderInAlphaEW() const; using MEBase::orderInAlphaEW; /** * Return true, if this amplitude already includes averaging over * incoming parton's quantum numbers. */ virtual bool hasInitialAverage() const { return matchboxAmplitude() ? matchboxAmplitude()->hasInitialAverage() : false; } /** * Return true, if this amplitude already includes symmetry factors * for identical outgoing particles. */ virtual bool hasFinalStateSymmetry() const { return matchboxAmplitude() ? matchboxAmplitude()->hasFinalStateSymmetry() : false; } /** * Return the number of light flavours, this matrix * element is calculated for. */ virtual unsigned int getNLight() const; /** * Return the vector that contains the PDG ids of * the light flavours, which are contained in the * jet particle group. */ virtual vector<int> getNLightJetVec() const; /** * Return the vector that contains the PDG ids of * the heavy flavours, which are contained in the * jet particle group. */ virtual vector<int> getNHeavyJetVec() const; /** * Return the vector that contains the PDG ids of * the light flavours, which are contained in the * proton particle group. */ virtual vector<int> getNLightProtonVec() const; /** * Return true, if this matrix element is handled by a BLHA one-loop provider */ virtual bool isOLPTree() const { return matchboxAmplitude() ? matchboxAmplitude()->isOLPTree() : false; } /** * Return true, if this matrix element is handled by a BLHA one-loop provider */ virtual bool isOLPLoop() const { return matchboxAmplitude() ? matchboxAmplitude()->isOLPLoop() : false; } /** * Return true, if colour and spin correlated matrix elements should * be ordered from the OLP */ virtual bool needsOLPCorrelators() const { return matchboxAmplitude() ? matchboxAmplitude()->needsOLPCorrelators() : true; } /** * Return the process index, if this is an OLP handled matrix element */ const vector<int>& olpProcess() const { return theOLPProcess; } /** * Set the process index, if this is an OLP handled matrix element */ void olpProcess(int pType, int id) { if ( theOLPProcess.empty() ) theOLPProcess.resize(5,0); theOLPProcess[pType] = id; } /** * Return true, if this is a real emission matrix element which does * not require colour correlators. */ bool noCorrelations() const { return theNoCorrelations; } /** * Indicate that this is a real emission matrix element which does * not require colour correlators. */ void needsNoCorrelations() { theNoCorrelations = true; } /** * Indicate that this is a virtual matrix element which does * require colour correlators. */ void needsCorrelations() { theNoCorrelations = false; } //@} /** @name Phasespace generation */ //@{ /** * Return the phase space generator to be used. */ Ptr<MatchboxPhasespace>::tptr phasespace() const { return thePhasespace; } /** * Set the phase space generator to be used. */ void phasespace(Ptr<MatchboxPhasespace>::ptr ps) { thePhasespace = ps; } /** * Set the XComb object to be used in the next call to * generateKinematics() and dSigHatDR(). */ virtual void setXComb(tStdXCombPtr xc); /** * Return true, if the XComb steering this matrix element * should keep track of the random numbers used to generate * the last phase space point */ virtual bool keepRandomNumbers() const { return true; } /** * Generate incoming parton momenta. This default * implementation performs the standard mapping * from x1,x2 -> tau,y making 1/tau flat; incoming * parton momenta are stored in meMomenta()[0,1], * only massless partons are supported so far; * return the Jacobian of the mapping */ double generateIncomingPartons(const double* r1, const double* r2); /** * Generate internal degrees of freedom given nDim() uniform random * numbers in the interval ]0,1[. To help the phase space generator, * the 'dSigHatDR' should be a smooth function of these numbers, * although this is not strictly necessary. The return value should * be true of the generation succeeded. If so the generated momenta * should be stored in the meMomenta() vector. Derived classes * must call this method once internal degrees of freedom are setup * and finally return the result of this method. */ virtual bool generateKinematics(const double * r); /** * The number of internal degreed of freedom used in the matrix * element. */ virtual int nDim() const; /** * The number of internal degrees of freedom used in the matrix * element for generating a Born phase space point */ virtual int nDimBorn() const; /** * Return true, if this matrix element will generate momenta for the * incoming partons itself. The matrix element is required to store * the incoming parton momenta in meMomenta()[0,1]. No mapping in * tau and y is performed by the PartonExtractor object, if a * derived class returns true here. The phase space jacobian is to * include a factor 1/(x1 x2). */ virtual bool haveX1X2() const { return (phasespace() ? phasespace()->haveX1X2() : false) || diagrams().front()->partons().size() == 3; } /** * Return true, if this matrix element expects * the incoming partons in their center-of-mass system */ virtual bool wantCMS() const { return (phasespace() ? phasespace()->wantCMS() : true) && diagrams().front()->partons().size() != 3; } /** * Return the meMomenta as generated at the last * phase space point. */ const vector<Lorentz5Momentum>& lastMEMomenta() const { return meMomenta(); } /** * Access the meMomenta. */ vector<Lorentz5Momentum>& lastMEMomenta() { return meMomenta(); } //@} /** @name Scale choices, couplings and PDFs */ //@{ /** * Set the scale choice object */ void scaleChoice(Ptr<MatchboxScaleChoice>::ptr sc) { theScaleChoice = sc; } /** * Return the scale choice object */ Ptr<MatchboxScaleChoice>::tptr scaleChoice() const { return theScaleChoice; } /** * Set scales and alphaS */ void setScale() const; /** * Indicate that this matrix element is running alphas by itself. */ virtual bool hasRunningAlphaS() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->hasRunningAlphaS(); return false; } /** * Indicate that this matrix element is running alphaew by itself. */ virtual bool hasRunningAlphaEW() const { if ( matchboxAmplitude() ) return matchboxAmplitude()->hasRunningAlphaEW(); return false; } /** * Return the scale associated with the phase space point provided * by the last call to setKinematics(). */ virtual Energy2 scale() const { return lastScale(); } /** * Return the renormalization scale for the last generated phasespace point. */ virtual Energy2 factorizationScale() const; /** * Get the factorization scale factor */ virtual double factorizationScaleFactor() const; /** * Return the (QCD) renormalization scale for the last generated phasespace point. */ virtual Energy2 renormalizationScale() const; /** * Get the renormalization scale factor */ virtual double renormalizationScaleFactor() const; /** * Return the QED renormalization scale for the last generated phasespace point. */ virtual Energy2 renormalizationScaleQED() const; /** + * Return the shower scale for the last generated phasespace point. + */ + virtual Energy2 showerScale() const; + + /** * Set veto scales on the particles at the given * SubProcess which has been generated using this * matrix element. */ virtual void setVetoScales(tSubProPtr) const; /** * Return true, if fixed couplings are used. */ bool fixedCouplings() const; /** * Return true, if fixed couplings are used. */ bool fixedQEDCouplings() const; /** * Return the value of \f$\alpha_S\f$ associated with the phase * space point provided by the last call to setKinematics(). This * versions returns SM().alphaS(scale()). */ virtual double alphaS() const { return lastAlphaS(); } /** * Return the value of \f$\alpha_EM\f$ associated with the phase * space point provided by the last call to setKinematics(). This * versions returns SM().alphaEM(scale()). */ virtual double alphaEM() const { return lastAlphaEM(); } /** * Return true, if this matrix element provides the PDF * weight for the first incoming parton itself. */ virtual bool havePDFWeight1() const; /** * Return true, if this matrix element provides the PDF * weight for the second incoming parton itself. */ virtual bool havePDFWeight2() const; /** * Set the PDF weight. */ void getPDFWeight(Energy2 factorizationScale = ZERO) const; /** * Supply the PDF weight for the first incoming parton. */ double pdf1(Energy2 factorizationScale = ZERO, double xEx = 1., double xFactor = 1.) const; /** * Supply the PDF weight for the second incoming parton. */ double pdf2(Energy2 factorizationScale = ZERO, double xEx = 1., double xFactor = 1.) const; //@} /** @name Amplitude information and matrix element evaluation */ //@{ /** * Return the amplitude. */ Ptr<MatchboxAmplitude>::tptr matchboxAmplitude() const { return theAmplitude; } /** * Set the amplitude. */ void matchboxAmplitude(Ptr<MatchboxAmplitude>::ptr amp) { theAmplitude = amp; } /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double me2() const; /** * Return the matrix element for the kinematical configuation * previously provided by the last call to setKinematics(), suitably * scaled by sHat() to give a dimension-less number. */ virtual double largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const; /** * Return the symmetry factor for identical final state particles. */ virtual double finalStateSymmetry() const; /** * Return the normalizing factor for the matrix element averaged * over quantum numbers and including running couplings. */ double me2Norm(unsigned int addAlphaS = 0) const; /** * Return the matrix element squared differential in the variables * given by the last call to generateKinematics(). */ virtual CrossSection dSigHatDR() const; //@} /** @name One-loop corrections */ //@{ /** * Return the one-loop/tree interference. */ virtual double oneLoopInterference() const; /** * Return true, if this matrix element is capable of calculating * one-loop (QCD) corrections. */ virtual bool haveOneLoop() const; /** * Return true, if this matrix element only provides * one-loop (QCD) corrections. */ virtual bool onlyOneLoop() const; /** * Return true, if the amplitude is DRbar renormalized, otherwise * MSbar is assumed. */ virtual bool isDRbar() const; /** * Return true, if one loop corrections have been calculated in * dimensional reduction. Otherwise conventional dimensional * regularization is assumed. Note that renormalization is always * assumed to be MSbar. */ virtual bool isDR() const; /** * Return true, if one loop corrections are given in the conventions * of the integrated dipoles. */ virtual bool isCS() const; /** * Return true, if one loop corrections are given in the conventions * of BDK. */ virtual bool isBDK() const; /** * Return true, if one loop corrections are given in the conventions * of everything expanded. */ virtual bool isExpanded() const; /** * Return the value of the dimensional regularization * parameter. Note that renormalization scale dependence is fully * restored in DipoleIOperator. */ virtual Energy2 mu2() const; /** * If defined, return the coefficient of the pole in epsilon^2 */ virtual double oneLoopDoublePole() const; /** * If defined, return the coefficient of the pole in epsilon */ virtual double oneLoopSinglePole() const; /** * Return true, if cancellationn of epsilon poles should be checked. */ bool checkPoles() const; /** * Simple histogram for accuracy checks */ struct AccuracyHistogram { /** * The lower bound */ double lower; /** * The upper bound */ double upper; /** * The bins, indexed by upper bound. */ map<double,double> bins; /** * The number of points of same sign */ unsigned long sameSign; /** * The number of points of opposite sign */ unsigned long oppositeSign; /** * The number of points being nan or inf */ unsigned long nans; /** * The overflow */ unsigned long overflow; /** * The underflow */ unsigned long underflow; /** * Constructor */ AccuracyHistogram(double low = -40., double up = 0., unsigned int nbins = 80); /** * Book two values to be checked for numerical compatibility */ void book(double a, double b); /** * Write to file. */ void dump(const std::string& folder, const std::string& prefix, const cPDVector& proc) const; /** * Write to persistent ostream */ void persistentOutput(PersistentOStream&) const; /** * Read from persistent istream */ void persistentInput(PersistentIStream&); }; /** * Perform the check of epsilon pole cancellation. */ void logPoles() const; /** * Return the virtual corrections */ const vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() const { return theVirtuals; } /** * Return the virtual corrections */ vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() { return theVirtuals; } /** * Instruct this matrix element to include one-loop corrections */ void doOneLoop() { theOneLoop = true; } /** * Return true, if this matrix element includes one-loop corrections */ bool oneLoop() const { return theOneLoop; } /** * Instruct this matrix element to include one-loop corrections but * no Born contributions */ void doOneLoopNoBorn() { theOneLoop = true; theOneLoopNoBorn = true; } /** * Return true, if this matrix element includes one-loop corrections * but no Born contributions */ bool oneLoopNoBorn() const { return theOneLoopNoBorn || onlyOneLoop(); } /** * Instruct this matrix element to include one-loop corrections but * no actual loop contributions */ void doOneLoopNoLoops() { theOneLoop = true; theOneLoopNoLoops = true; } /** * Return true, if this matrix element includes one-loop corrections * but no actual loop contributions */ bool oneLoopNoLoops() const { return theOneLoopNoLoops; } //@} /** @name Dipole subtraction */ //@{ /** * If this matrix element is considered a real * emission matrix element, return all subtraction * dipoles needed given a set of subtraction terms * and underlying Born matrix elements to choose * from. */ vector<Ptr<SubtractionDipole>::ptr> getDipoles(const vector<Ptr<SubtractionDipole>::ptr>&, const vector<Ptr<MatchboxMEBase>::ptr>&) const; /** * If this matrix element is considered a real emission matrix * element, but actually neglecting a subclass of the contributing * diagrams, return true if the given emitter-emission-spectator * configuration should not be considered when setting up * subtraction dipoles. */ virtual bool noDipole(int,int,int) const { return false; } /** * If this matrix element is considered an underlying Born matrix * element in the context of a subtracted real emission, but * actually neglecting a subclass of the contributing diagrams, * return true if the given emitter-spectator configuration * should not be considered when setting up subtraction dipoles. */ virtual bool noDipole(int,int) const { return false; } /** * Return the colour correlated matrix element squared with * respect to the given two partons as appearing in mePartonData(), * suitably scaled by sHat() to give a dimension-less number. */ virtual double colourCorrelatedME2(pair<int,int>) const; /** * Return the colour correlated matrix element squared in the * large-N approximation with respect to the given two partons as * appearing in mePartonData(), suitably scaled by sHat() to give a * dimension-less number. */ virtual double largeNColourCorrelatedME2(pair<int,int> ij, Ptr<ColourBasis>::tptr largeNBasis) const; /** * Return the colour and spin correlated matrix element squared for * the gluon indexed by the first argument using the given * correlation tensor. */ virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator, const SpinCorrelationTensor& c) const; /** * Return the spin correlated matrix element squared for * the vector boson indexed by the first argument using the given * correlation tensor. */ virtual double spinCorrelatedME2(pair<int,int> emitterSpectator, const SpinCorrelationTensor& c) const; //@} /** @name Caching and diagnostic information */ //@{ /** * Inform this matrix element that a new phase space * point is about to be generated, so all caches should * be flushed. */ virtual void flushCaches(); /** * Return true, if verbose */ bool verbose() const; /** * Return true, if verbose */ bool initVerbose() const; /** * Dump the setup to an ostream */ void print(ostream&) const; /** * Print debug information on the last event */ virtual void printLastEvent(ostream&) const; /** * Write out diagnostic information for * generateKinematics */ void logGenerateKinematics(const double * r) const; /** * Write out diagnostic information for * setting scales */ void logSetScale() const; /** * Write out diagnostic information for * pdf evaluation */ void logPDFWeight() const; /** * Write out diagnostic information for * me2 evaluation */ void logME2() const; /** * Write out diagnostic information * for dsigdr evaluation */ void logDSigHatDR() const; //@} /** @name Reweight objects */ //@{ /** * Insert a reweight object */ void addReweight(Ptr<MatchboxReweightBase>::ptr rw) { theReweights.push_back(rw); } /** * Return the reweights */ const vector<Ptr<MatchboxReweightBase>::ptr>& reweights() const { return theReweights; } /** * Access the reweights */ vector<Ptr<MatchboxReweightBase>::ptr>& reweights() { return theReweights; } //@} /** @name Methods used to setup MatchboxMEBase objects */ //@{ /** * Return true if this object needs to be initialized before all * other objects (except those for which this function also returns * true). This default version always returns false, but subclasses * may override it to return true. */ virtual bool preInitialize() const { return true; } /** * Clone this matrix element. */ Ptr<MatchboxMEBase>::ptr cloneMe() const { return dynamic_ptr_cast<Ptr<MatchboxMEBase>::ptr>(clone()); } /** * Clone the dependencies, using a given prefix. */ void cloneDependencies(const std::string& prefix = ""); /** * Prepare an xcomb */ void prepareXComb(MatchboxXCombData&) const; /** * For the given event generation setup return a xcomb object * appropriate to this matrix element. */ virtual StdXCombPtr makeXComb(Energy newMaxEnergy, const cPDPair & inc, tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler, tPExtrPtr newExtractor, tCascHdlPtr newCKKW, const PBPair & newPartonBins, tCutsPtr newCuts, const DiagramVector & newDiagrams, bool mir, const PartonPairVec& allPBins, tStdXCombPtr newHead = tStdXCombPtr(), tMEPtr newME = tMEPtr()); /** * For the given event generation setup return a dependent xcomb object * appropriate to this matrix element. */ virtual StdXCombPtr makeXComb(tStdXCombPtr newHead, const PBPair & newPartonBins, const DiagramVector & newDiagrams, tMEPtr newME = tMEPtr()); //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object after the setup phase before saving an * EventGenerator to disk. * @throws InitException if object could not be initialized properly. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); //@} private: /** * The factory which produced this matrix element */ Ptr<MatchboxFactory>::tptr theFactory; /** * The phase space generator to be used. */ Ptr<MatchboxPhasespace>::ptr thePhasespace; /** * The amplitude to be used */ Ptr<MatchboxAmplitude>::ptr theAmplitude; /** * The scale choice object */ Ptr<MatchboxScaleChoice>::ptr theScaleChoice; /** * The virtual corrections. */ vector<Ptr<MatchboxInsertionOperator>::ptr> theVirtuals; /** * A vector of reweight objects the sum of which * should be applied to reweight this matrix element */ vector<Ptr<MatchboxReweightBase>::ptr> theReweights; private: /** * The subprocess to be considered. */ Process theSubprocess; /** * True, if this matrix element includes one-loop corrections */ bool theOneLoop; /** * True, if this matrix element includes one-loop corrections * but no Born contributions */ bool theOneLoopNoBorn; /** * True, if this matrix element includes one-loop corrections * but no actual loop contributions (e.g. finite collinear terms) */ bool theOneLoopNoLoops; /** * The process index, if this is an OLP handled matrix element */ vector<int> theOLPProcess; /** * Histograms of epsilon^2 pole cancellation */ mutable map<cPDVector,AccuracyHistogram> epsilonSquarePoleHistograms; /** * Histograms of epsilon pole cancellation */ mutable map<cPDVector,AccuracyHistogram> epsilonPoleHistograms; /** * True, if this is a real emission matrix element which does * not require colour correlators. */ bool theNoCorrelations; /** * Flag which pdfs should be included. */ mutable pair<bool,bool> theHavePDFs; /** * True, if already checked for which PDFs to include. */ mutable bool checkedPDFs; /** * Diagnostic Diagram for TreePhaseSpace */ void bookMEoverDiaWeight(double x) const; mutable map<double,double > MEoverDiaWeight; mutable int Nevents; /** * Range of diagram weight verbosity */ mutable double theDiagramWeightVerboseDown, theDiagramWeightVerboseUp; private: /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MatchboxMEBase & operator=(const MatchboxMEBase &); }; inline PersistentOStream& operator<<(PersistentOStream& os, const MatchboxMEBase::AccuracyHistogram& h) { h.persistentOutput(os); return os; } inline PersistentIStream& operator>>(PersistentIStream& is, MatchboxMEBase::AccuracyHistogram& h) { h.persistentInput(is); return is; } } #endif /* HERWIG_MatchboxMEBase_H */ diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximation.cc b/MatrixElement/Matchbox/Matching/ShowerApproximation.cc --- a/MatrixElement/Matchbox/Matching/ShowerApproximation.cc +++ b/MatrixElement/Matchbox/Matching/ShowerApproximation.cc @@ -1,685 +1,685 @@ // -*- C++ -*- // // ShowerApproximation.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2012 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the ShowerApproximation class. // #include "ShowerApproximation.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h" using namespace Herwig; ShowerApproximation::ShowerApproximation() : HandlerBase(), theExtrapolationX(1.0), theBelowCutoff(false), theFFPtCut(1.0*GeV), theFFScreeningScale(ZERO), theFIPtCut(1.0*GeV), theFIScreeningScale(ZERO), theIIPtCut(1.0*GeV), theIIScreeningScale(ZERO), theSafeCut(0.0*GeV), theRestrictPhasespace(true), theHardScaleFactor(1.0), theRenormalizationScaleFactor(1.0), theFactorizationScaleFactor(1.0), theRealEmissionScaleInSubtraction(showerScale), theBornScaleInSubtraction(showerScale), theEmissionScaleInSubtraction(showerScale), theRealEmissionScaleInSplitting(showerScale), theBornScaleInSplitting(showerScale), theEmissionScaleInSplitting(showerScale), theRenormalizationScaleFreeze(1.*GeV), theFactorizationScaleFreeze(1.*GeV), maxPtIsMuF(false) {} ShowerApproximation::~ShowerApproximation() {} void ShowerApproximation::setLargeNBasis() { assert(dipole()->realEmissionME()->matchboxAmplitude()); if ( !dipole()->realEmissionME()->matchboxAmplitude()->treeAmplitudes() ) return; if ( !theLargeNBasis ) { if ( !dipole()->realEmissionME()->matchboxAmplitude()->colourBasis() ) throw Exception() << "ShowerApproximation::setLargeNBasis(): Expecting a colour basis object." << Exception::runerror; theLargeNBasis = dipole()->realEmissionME()->matchboxAmplitude()->colourBasis()->cloneMe(); theLargeNBasis->clear(); theLargeNBasis->doLargeN(); } } void ShowerApproximation::setDipole(Ptr<SubtractionDipole>::tptr dip) { theDipole = dip; setLargeNBasis(); } Ptr<SubtractionDipole>::tptr ShowerApproximation::dipole() const { return theDipole; } Ptr<TildeKinematics>::tptr ShowerApproximation::showerTildeKinematics() const { return Ptr<TildeKinematics>::tptr(); } Ptr<InvertedTildeKinematics>::tptr ShowerApproximation::showerInvertedTildeKinematics() const { return Ptr<InvertedTildeKinematics>::tptr(); } void ShowerApproximation::checkCutoff() { assert(!showerTildeKinematics()); } void ShowerApproximation::getShowerVariables() { // check for the cutoff dipole()->isAboveCutoff(isAboveCutoff()); // get the hard scale dipole()->showerHardScale(hardScale()); // set the shower scale and variables for completeness dipole()->showerScale(dipole()->lastPt()); dipole()->showerParameters().resize(1); dipole()->showerParameters()[0] = dipole()->lastZ(); // check for phase space dipole()->isInShowerPhasespace(isInShowerPhasespace()); } bool ShowerApproximation::isAboveCutoff() const { if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) { return dipole()->lastPt() >= max(ffPtCut(),safeCut()); } else if ( ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) || ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) ) { return dipole()->lastPt() >= max(fiPtCut(),safeCut()); } else { assert(dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2); return dipole()->lastPt() >= max(iiPtCut(),safeCut()); } return true; } Energy ShowerApproximation::hardScale() const { if ( !maxPtIsMuF ) { if ( !bornCXComb()->mePartonData()[0]->coloured() && !bornCXComb()->mePartonData()[1]->coloured() ) { Energy maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m(); maxPt *= hardScaleFactor(); return maxPt; } Energy maxPt = generator()->maximumCMEnergy(); vector<Lorentz5Momentum>::const_iterator p = bornCXComb()->meMomenta().begin() + 2; cPDVector::const_iterator pp = bornCXComb()->mePartonData().begin() + 2; for ( ; p != bornCXComb()->meMomenta().end(); ++p, ++pp ) if ( (**pp).coloured() ) maxPt = min(maxPt,p->mt()); if ( maxPt == generator()->maximumCMEnergy() ) maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m(); maxPt *= hardScaleFactor(); return maxPt; } else { - return hardScaleFactor()*sqrt(bornCXComb()->lastCentralScale()); + return hardScaleFactor()*sqrt(bornCXComb()->lastShowerScale()); } } bool ShowerApproximation::isInShowerPhasespace() const { if ( !dipole()->isAboveCutoff() ) return false; if ( !restrictPhasespace() ) return true; InvertedTildeKinematics& kinematics = const_cast<InvertedTildeKinematics&>(*dipole()->invertedTildeKinematics()); tcStdXCombPtr tmpreal = kinematics.realXComb(); tcStdXCombPtr tmpborn = kinematics.bornXComb(); Ptr<SubtractionDipole>::tptr tmpdip = kinematics.dipole(); Energy hard = dipole()->showerHardScale(); Energy pt = dipole()->lastPt(); double z = dipole()->lastZ(); pair<double,double> zbounds(0.,1.); kinematics.dipole(const_ptr_cast<Ptr<SubtractionDipole>::tptr>(theDipole)); kinematics.prepare(realCXComb(),bornCXComb()); if ( pt > hard ) { kinematics.dipole(tmpdip); kinematics.prepare(tmpreal,tmpborn); return false; } try { zbounds = kinematics.zBounds(pt,hard); } catch(...) { kinematics.dipole(tmpdip); kinematics.prepare(tmpreal,tmpborn); throw; } kinematics.dipole(tmpdip); kinematics.prepare(tmpreal,tmpborn); return z > zbounds.first && z < zbounds.second; } Energy2 ShowerApproximation::showerEmissionScale() const { Energy2 mur = sqr(dipole()->lastPt()); if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) { return mur + sqr(ffScreeningScale()); } else if ( ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) || ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) ) { return mur + sqr(fiScreeningScale()); } else { assert(dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2); return mur + sqr(iiScreeningScale()); } return mur; } Energy2 ShowerApproximation::bornRenormalizationScale() const { return sqr(dipole()->underlyingBornME()->renormalizationScaleFactor()) * dipole()->underlyingBornME()->renormalizationScale(); } Energy2 ShowerApproximation::bornFactorizationScale() const { return sqr(dipole()->underlyingBornME()->factorizationScaleFactor()) * dipole()->underlyingBornME()->factorizationScale(); } Energy2 ShowerApproximation::realRenormalizationScale() const { return sqr(dipole()->realEmissionME()->renormalizationScaleFactor()) * dipole()->realEmissionME()->renormalizationScale(); } Energy2 ShowerApproximation::realFactorizationScale() const { return sqr(dipole()->realEmissionME()->factorizationScaleFactor()) * dipole()->realEmissionME()->factorizationScale(); } double ShowerApproximation::bornPDFWeight(Energy2 muf) const { if ( !bornCXComb()->mePartonData()[0]->coloured() && !bornCXComb()->mePartonData()[1]->coloured() ) return 1.; if ( muf < sqr(theFactorizationScaleFreeze) ) muf = sqr(theFactorizationScaleFreeze); double pdfweight = 1.; if ( bornCXComb()->mePartonData()[0]->coloured() && dipole()->underlyingBornME()->havePDFWeight1() ) pdfweight *= dipole()->underlyingBornME()->pdf1(muf,theExtrapolationX); if ( bornCXComb()->mePartonData()[1]->coloured() && dipole()->underlyingBornME()->havePDFWeight2() ) pdfweight *= dipole()->underlyingBornME()->pdf2(muf,theExtrapolationX); return pdfweight; } double ShowerApproximation::realPDFWeight(Energy2 muf) const { if ( !realCXComb()->mePartonData()[0]->coloured() && !realCXComb()->mePartonData()[1]->coloured() ) return 1.; if ( muf < sqr(theFactorizationScaleFreeze) ) muf = sqr(theFactorizationScaleFreeze); double pdfweight = 1.; if ( realCXComb()->mePartonData()[0]->coloured() && dipole()->realEmissionME()->havePDFWeight1() ) pdfweight *= dipole()->realEmissionME()->pdf1(muf,theExtrapolationX); if ( realCXComb()->mePartonData()[1]->coloured() && dipole()->realEmissionME()->havePDFWeight2() ) pdfweight *= dipole()->realEmissionME()->pdf2(muf,theExtrapolationX); return pdfweight; } double ShowerApproximation::scaleWeight(int rScale, int bScale, int eScale) const { double emissionAlpha = 1.; Energy2 emissionScale = ZERO; Energy2 showerscale = ZERO; if ( eScale == showerScale || bScale == showerScale || eScale == showerScale ) { showerscale = showerRenormalizationScale(); if ( showerscale < sqr(theRenormalizationScaleFreeze) ) showerscale = sqr(theFactorizationScaleFreeze); } if ( eScale == showerScale ) { emissionAlpha = SM().alphaS(showerscale); emissionScale = showerFactorizationScale(); } else if ( eScale == realScale ) { emissionAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS(); emissionScale = dipole()->realEmissionME()->lastScale(); } else if ( eScale == bornScale ) { emissionAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS(); emissionScale = dipole()->underlyingBornME()->lastScale(); } double emissionPDF = realPDFWeight(emissionScale); double couplingFactor = 1.; if ( bScale != rScale ) { double bornAlpha = 1.; if ( bScale == showerScale ) { bornAlpha = SM().alphaS(showerscale); } else if ( bScale == realScale ) { bornAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS(); } else if ( bScale == bornScale ) { bornAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS(); } double realAlpha = 1.; if ( rScale == showerScale ) { realAlpha = SM().alphaS(showerscale); } else if ( rScale == realScale ) { realAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS(); } else if ( rScale == bornScale ) { realAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS(); } couplingFactor *= pow(realAlpha/bornAlpha,(double)(dipole()->underlyingBornME()->orderInAlphaS())); } Energy2 hardScale = ZERO; if ( bScale == showerScale ) { hardScale = showerFactorizationScale(); } else if ( bScale == realScale ) { hardScale = dipole()->realEmissionME()->lastScale(); } else if ( bScale == bornScale ) { hardScale = dipole()->underlyingBornME()->lastScale(); } double bornPDF = bornPDFWeight(hardScale); if ( bornPDF < 1e-8 ) bornPDF = 0.0; if ( emissionPDF < 1e-8 ) emissionPDF = 0.0; if ( emissionPDF == 0.0 || bornPDF == 0.0 ) return 0.0; return emissionAlpha * emissionPDF * couplingFactor / bornPDF; } double ShowerApproximation::channelWeight(int emitter, int emission, int spectator, int) const { double cfac = 1.; double Nc = generator()->standardModel()->Nc(); if (realCXComb()->mePartonData()[emitter]->iColour() == PDT::Colour8){ if (realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour8) cfac = Nc; else if ( realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour3 || realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour3bar) cfac = 0.5; else assert(false); } else if ((realCXComb()->mePartonData()[emitter] ->iColour() == PDT::Colour3 || realCXComb()->mePartonData()[emitter] ->iColour() == PDT::Colour3bar)) cfac = (sqr(Nc)-1.)/(2.*Nc); else assert(false); // do the most simple thing for the time being; needs fixing later if ( realCXComb()->mePartonData()[emission]->id() == ParticleID::g ) { Energy2 pipk = realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[spectator]; Energy2 pipj = realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[emission]; Energy2 pjpk = realCXComb()->meMomenta()[emission] * realCXComb()->meMomenta()[spectator]; return cfac *GeV2 * pipk / ( pipj * ( pipj + pjpk ) ); } return cfac * GeV2 / (realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[emission]); } double ShowerApproximation::channelWeight() const { double currentChannel = channelWeight(dipole()->realEmitter(), dipole()->realEmission(), dipole()->realSpectator(), dipole()->bornEmitter()); if ( currentChannel == 0. ) return 0.; double sum = 0.; for ( vector<Ptr<SubtractionDipole>::tptr>::const_iterator dip = dipole()->partnerDipoles().begin(); dip != dipole()->partnerDipoles().end(); ++dip ) sum += channelWeight((**dip).realEmitter(), (**dip).realEmission(), (**dip).realSpectator(), (**dip).bornEmitter()); assert(sum > 0.0); return currentChannel / sum; } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ShowerApproximation::persistentOutput(PersistentOStream & os) const { os << theLargeNBasis << theBornXComb << theRealXComb << theTildeXCombs << theDipole << theBelowCutoff << ounit(theFFPtCut,GeV) << ounit(theFFScreeningScale,GeV) << ounit(theFIPtCut,GeV) << ounit(theFIScreeningScale,GeV) << ounit(theIIPtCut,GeV) << ounit(theIIScreeningScale,GeV) << ounit(theSafeCut,GeV) << theRestrictPhasespace << theHardScaleFactor << theRenormalizationScaleFactor << theFactorizationScaleFactor << theExtrapolationX << theRealEmissionScaleInSubtraction << theBornScaleInSubtraction << theEmissionScaleInSubtraction << theRealEmissionScaleInSplitting << theBornScaleInSplitting << theEmissionScaleInSplitting << ounit(theRenormalizationScaleFreeze,GeV) << ounit(theFactorizationScaleFreeze,GeV) << maxPtIsMuF << theHardScaleProfile; } void ShowerApproximation::persistentInput(PersistentIStream & is, int) { is >> theLargeNBasis >> theBornXComb >> theRealXComb >> theTildeXCombs >> theDipole >> theBelowCutoff >> iunit(theFFPtCut,GeV) >> iunit(theFFScreeningScale,GeV) >> iunit(theFIPtCut,GeV) >> iunit(theFIScreeningScale,GeV) >> iunit(theIIPtCut,GeV) >> iunit(theIIScreeningScale,GeV) >> iunit(theSafeCut,GeV) >> theRestrictPhasespace >> theHardScaleFactor >> theRenormalizationScaleFactor >> theFactorizationScaleFactor >> theExtrapolationX >> theRealEmissionScaleInSubtraction >> theBornScaleInSubtraction >> theEmissionScaleInSubtraction >> theRealEmissionScaleInSplitting >> theBornScaleInSplitting >> theEmissionScaleInSplitting >> iunit(theRenormalizationScaleFreeze,GeV) >> iunit(theFactorizationScaleFreeze,GeV) >> maxPtIsMuF >> theHardScaleProfile; } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeAbstractClass<ShowerApproximation,HandlerBase> describeHerwigShowerApproximation("Herwig::ShowerApproximation", "Herwig.so"); void ShowerApproximation::Init() { static ClassDocumentation<ShowerApproximation> documentation ("ShowerApproximation describes the shower emission to be used " "in NLO matching."); static Parameter<ShowerApproximation,Energy> interfaceFFPtCut ("FFPtCut", "Set the pt infrared cutoff", &ShowerApproximation::theFFPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,Energy> interfaceFIPtCut ("FIPtCut", "Set the pt infrared cutoff", &ShowerApproximation::theFIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,Energy> interfaceIIPtCut ("IIPtCut", "Set the pt infrared cutoff", &ShowerApproximation::theIIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,Energy> interfaceSafeCut ("SafeCut", "Set the enhanced infrared cutoff for the Matching.", &ShowerApproximation::theSafeCut, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,Energy> interfaceFFScreeningScale ("FFScreeningScale", "Set the screening scale", &ShowerApproximation::theFFScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,Energy> interfaceFIScreeningScale ("FIScreeningScale", "Set the screening scale", &ShowerApproximation::theFIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,Energy> interfaceIIScreeningScale ("IIScreeningScale", "Set the screening scale", &ShowerApproximation::theIIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Switch<ShowerApproximation,bool> interfaceRestrictPhasespace ("RestrictPhasespace", "Switch on or off phasespace restrictions", &ShowerApproximation::theRestrictPhasespace, true, false, false); static SwitchOption interfaceRestrictPhasespaceOn (interfaceRestrictPhasespace, "On", "Perform phasespace restrictions", true); static SwitchOption interfaceRestrictPhasespaceOff (interfaceRestrictPhasespace, "Off", "Do not perform phasespace restrictions", false); static Parameter<ShowerApproximation,double> interfaceHardScaleFactor ("HardScaleFactor", "The hard scale factor.", &ShowerApproximation::theHardScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,double> interfaceRenormalizationScaleFactor ("RenormalizationScaleFactor", "The hard scale factor.", &ShowerApproximation::theRenormalizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,double> interfaceFactorizationScaleFactor ("FactorizationScaleFactor", "The hard scale factor.", &ShowerApproximation::theFactorizationScaleFactor, 1.0, 0.0, 0, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,double> interfaceExtrapolationX ("ExtrapolationX", "The x from which on extrapolation should be performed.", &ShowerApproximation::theExtrapolationX, 1.0, 0.0, 1.0, false, false, Interface::limited); static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSubtraction ("RealEmissionScaleInSubtraction", "Set the scale choice for the real emission cross section in the matching subtraction.", &ShowerApproximation::theRealEmissionScaleInSubtraction, showerScale, false, false); static SwitchOption interfaceRealEmissionScaleInSubtractionRealScale (interfaceRealEmissionScaleInSubtraction, "RealScale", "Use the real emission scale.", realScale); static SwitchOption interfaceRealEmissionScaleInSubtractionBornScale (interfaceRealEmissionScaleInSubtraction, "BornScale", "Use the Born scale.", bornScale); static SwitchOption interfaceRealEmissionScaleInSubtractionShowerScale (interfaceRealEmissionScaleInSubtraction, "ShowerScale", "Use the shower scale", showerScale); static Switch<ShowerApproximation,int> interfaceBornScaleInSubtraction ("BornScaleInSubtraction", "Set the scale choice for the Born cross section in the matching subtraction.", &ShowerApproximation::theBornScaleInSubtraction, showerScale, false, false); static SwitchOption interfaceBornScaleInSubtractionRealScale (interfaceBornScaleInSubtraction, "RealScale", "Use the real emission scale.", realScale); static SwitchOption interfaceBornScaleInSubtractionBornScale (interfaceBornScaleInSubtraction, "BornScale", "Use the Born scale.", bornScale); static SwitchOption interfaceBornScaleInSubtractionShowerScale (interfaceBornScaleInSubtraction, "ShowerScale", "Use the shower scale", showerScale); static Switch<ShowerApproximation,int> interfaceEmissionScaleInSubtraction ("EmissionScaleInSubtraction", "Set the scale choice for the emission in the matching subtraction.", &ShowerApproximation::theEmissionScaleInSubtraction, showerScale, false, false); static SwitchOption interfaceEmissionScaleInSubtractionRealScale (interfaceEmissionScaleInSubtraction, "RealScale", "Use the real emission scale.", realScale); static SwitchOption interfaceEmissionScaleInSubtractionEmissionScale (interfaceEmissionScaleInSubtraction, "BornScale", "Use the Born scale.", bornScale); static SwitchOption interfaceEmissionScaleInSubtractionShowerScale (interfaceEmissionScaleInSubtraction, "ShowerScale", "Use the shower scale", showerScale); static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSplitting ("RealEmissionScaleInSplitting", "Set the scale choice for the real emission cross section in the splitting.", &ShowerApproximation::theRealEmissionScaleInSplitting, showerScale, false, false); static SwitchOption interfaceRealEmissionScaleInSplittingRealScale (interfaceRealEmissionScaleInSplitting, "RealScale", "Use the real emission scale.", realScale); static SwitchOption interfaceRealEmissionScaleInSplittingBornScale (interfaceRealEmissionScaleInSplitting, "BornScale", "Use the Born scale.", bornScale); static SwitchOption interfaceRealEmissionScaleInSplittingShowerScale (interfaceRealEmissionScaleInSplitting, "ShowerScale", "Use the shower scale", showerScale); static Switch<ShowerApproximation,int> interfaceBornScaleInSplitting ("BornScaleInSplitting", "Set the scale choice for the Born cross section in the splitting.", &ShowerApproximation::theBornScaleInSplitting, showerScale, false, false); static SwitchOption interfaceBornScaleInSplittingRealScale (interfaceBornScaleInSplitting, "RealScale", "Use the real emission scale.", realScale); static SwitchOption interfaceBornScaleInSplittingBornScale (interfaceBornScaleInSplitting, "BornScale", "Use the Born scale.", bornScale); static SwitchOption interfaceBornScaleInSplittingShowerScale (interfaceBornScaleInSplitting, "ShowerScale", "Use the shower scale", showerScale); static Switch<ShowerApproximation,int> interfaceEmissionScaleInSplitting ("EmissionScaleInSplitting", "Set the scale choice for the emission in the splitting.", &ShowerApproximation::theEmissionScaleInSplitting, showerScale, false, false); static SwitchOption interfaceEmissionScaleInSplittingRealScale (interfaceEmissionScaleInSplitting, "RealScale", "Use the real emission scale.", realScale); static SwitchOption interfaceEmissionScaleInSplittingEmissionScale (interfaceEmissionScaleInSplitting, "BornScale", "Use the Born scale.", bornScale); static SwitchOption interfaceEmissionScaleInSplittingShowerScale (interfaceEmissionScaleInSplitting, "ShowerScale", "Use the shower scale", showerScale); static Parameter<ShowerApproximation,Energy> interfaceRenormalizationScaleFreeze ("RenormalizationScaleFreeze", "The freezing scale for the renormalization scale.", &ShowerApproximation::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Parameter<ShowerApproximation,Energy> interfaceFactorizationScaleFreeze ("FactorizationScaleFreeze", "The freezing scale for the factorization scale.", &ShowerApproximation::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV, false, false, Interface::lowerlim); static Reference<ShowerApproximation,HardScaleProfile> interfaceHardScaleProfile ("HardScaleProfile", "The hard scale profile to use.", &ShowerApproximation::theHardScaleProfile, false, false, true, true, false); static Reference<ShowerApproximation,ColourBasis> interfaceLargeNBasis ("LargeNBasis", "Set the large-N colour basis implementation.", &ShowerApproximation::theLargeNBasis, false, false, true, true, false); static Switch<ShowerApproximation,bool> interfaceMaxPtIsMuF ("MaxPtIsMuF", "", &ShowerApproximation::maxPtIsMuF, false, false, false); static SwitchOption interfaceMaxPtIsMuFYes (interfaceMaxPtIsMuF, "Yes", "", true); static SwitchOption interfaceMaxPtIsMuFNo (interfaceMaxPtIsMuF, "No", "", false); } diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc --- a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc +++ b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc @@ -1,533 +1,533 @@ // -*- C++ -*- // // ShowerApproximationGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2012 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the ShowerApproximationGenerator class. // #include <config.h> #include "ShowerApproximationGenerator.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/EventRecord/Particle.h" #include "ThePEG/Repository/UseRandom.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/PDF/PartonExtractor.h" #include "ThePEG/Cuts/Cuts.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" using namespace Herwig; ShowerApproximationGenerator::ShowerApproximationGenerator() : thePresamplingPoints(2000), theMaxTry(100000), theFreezeGrid(500000), theDoCompensate(false) {} ShowerApproximationGenerator::~ShowerApproximationGenerator() {} double ShowerApproximationGenerator::generateFraction(tcPDPtr pd, double r, double xmin) const { if ( pd->coloured() || pd->id() == ParticleID::gamma ) { return pow(xmin,r); } double x0 = 1.e-5; return 1. + x0 - x0*pow((1.+x0)/x0,r); } double ShowerApproximationGenerator::invertFraction(tcPDPtr pd, double x, double xmin) const { if ( pd->coloured() || pd->id() == ParticleID::gamma ) { return log(x)/log(xmin); } double x0 = 1.e-5; return log((1.-x+x0)/x0)/log((1.+x0)/x0); } bool ShowerApproximationGenerator::prepare(bool didproject) { tSubProPtr oldSub = lastIncomingXComb->subProcess(); tcStdXCombPtr cIncomingXC = lastIncomingXComb; bool hasFractions = thePhasespace->haveX1X2() || cIncomingXC->mePartonData().size() == 3; theLastMomenta.resize(cIncomingXC->mePartonData().size()); if ( !hasFractions ) theLastRandomNumbers.resize(thePhasespace->nDim(cIncomingXC->mePartonData()) + 2); else theLastRandomNumbers.resize(thePhasespace->nDim(cIncomingXC->mePartonData())); if ( !hasFractions ) { double x1 = oldSub->incoming().first->momentum().plus() / lastIncomingXComb->lastParticles().first->momentum().plus(); theLastRandomNumbers[0] = invertFraction(oldSub->incoming().first->dataPtr(),x1, lastIncomingXComb->cuts()->x1Min()); double x2 = oldSub->incoming().second->momentum().minus() / lastIncomingXComb->lastParticles().second->momentum().minus(); theLastRandomNumbers[1] = invertFraction(oldSub->incoming().second->dataPtr(),x2, lastIncomingXComb->cuts()->x2Min()); } theLastMomenta = cIncomingXC->meMomenta(); theLastPartons.first = oldSub->incoming().first->data().produceParticle(oldSub->incoming().first->momentum()); theLastPartons.second = oldSub->incoming().second->data().produceParticle(oldSub->incoming().second->momentum()); thePhasespace->setXComb(lastIncomingXComb); // this is a brute force fix for private ticket #241 ; only done to get fixed // for the release but will need to be looked at in more detail later on by // cleaning up the XCombs for these cases if ( theLastMomenta.size() == 3 && didproject ) { // boost them where they belong so invertKinematics is doing something sensible Boost toLab = (lastIncomingXComb->lastPartons().first->momentum() + lastIncomingXComb->lastPartons().second->momentum()).boostVector(); for ( int i = 0; i < 3; ++i ) theLastMomenta[i].boost(toLab); } thePhasespace->invertKinematics(theLastMomenta, !hasFractions ? &theLastRandomNumbers[2] : &theLastRandomNumbers[0]); theLastBornXComb->clean(); theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons, theLastMomenta,theLastRandomNumbers); if ( !theLastBornXComb->cuts()->initSubProcess(theLastBornXComb->lastSHat(), theLastBornXComb->lastY(), theLastBornXComb->mirror()) ) return false; theLastBornME->setXComb(theLastBornXComb); if ( !theLastBornME->generateKinematics(!hasFractions ? &theLastRandomNumbers[2] : &theLastRandomNumbers[0]) ) return false; CrossSection bornXS = theLastBornME->dSigHatDR(); if ( bornXS == ZERO ) return false; return true; } bool ShowerApproximationGenerator::generate(const vector<double>& r) { theLastBornXComb->clean(); bool hasFractions = thePhasespace->haveX1X2() || theLastBornXComb->mePartonData().size() == 3; if ( !hasFractions ) { double x = generateFraction(theLastPartons.first->dataPtr(),r[0], lastIncomingXComb->cuts()->x1Min()); Energy Q = lastIncomingXComb->lastParticles().first->momentum().plus(); Energy mass = theLastPartons.first->dataPtr()->mass(); double xi = (sqr(x*Q) - sqr(mass))/(sqr(Q)*x); Lorentz5Momentum p1(ZERO,ZERO,xi*Q/2.); p1.setMass(mass); p1.rescaleEnergy(); theLastPartons.first->set5Momentum(p1); x = generateFraction(theLastPartons.second->dataPtr(),r[1], lastIncomingXComb->cuts()->x2Min()); Q = lastIncomingXComb->lastParticles().second->momentum().minus(); mass = theLastPartons.second->dataPtr()->mass(); xi = (sqr(x*Q) - sqr(mass))/(sqr(Q)*x); Lorentz5Momentum p2(ZERO,ZERO,-xi*Q/2.); p2.setMass(mass); p2.rescaleEnergy(); theLastPartons.second->set5Momentum(p2); } else { theLastBornME->setXComb(theLastBornXComb); theLastBornXComb->lastParticles(lastIncomingXComb->lastParticles()); theLastBornXComb->lastP1P2(make_pair(0.0, 0.0)); theLastBornXComb->lastS(lastIncomingXComb->lastS()); if ( !theLastBornME->generateKinematics(&r[0]) ) return false; theLastPartons.first->set5Momentum(theLastBornME->lastMEMomenta()[0]); theLastPartons.second->set5Momentum(theLastBornME->lastMEMomenta()[1]); } theLastPresamplingMomenta.resize(theLastMomenta.size()); Boost toCMS = (theLastPartons.first->momentum() + theLastPartons.second->momentum()).findBoostToCM(); theLastPresamplingMomenta[0] = theLastPartons.first->momentum(); if ( !hasFractions ) theLastPresamplingMomenta[0].boost(toCMS); theLastPresamplingMomenta[1] = theLastPartons.second->momentum(); if ( !hasFractions ) theLastPresamplingMomenta[1].boost(toCMS); if ( hasFractions ) { for ( size_t k = 2; k < theLastBornME->lastMEMomenta().size(); ++k ) theLastPresamplingMomenta[k] = theLastBornME->lastMEMomenta()[k]; } theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons, theLastPresamplingMomenta,r); if ( !theLastBornXComb->cuts()->initSubProcess(theLastBornXComb->lastSHat(), theLastBornXComb->lastY(), theLastBornXComb->mirror()) ) return false; if ( !hasFractions ) { theLastBornME->setXComb(theLastBornXComb); if ( !theLastBornME->generateKinematics(&r[2]) ) return false; } CrossSection bornXS = theLastBornME->dSigHatDR(); if ( bornXS == ZERO ) return false; return true; } void ShowerApproximationGenerator::restore() { theLastBornXComb->clean(); bool hasFractions = thePhasespace->haveX1X2() || theLastBornXComb->mePartonData().size() == 3; if ( !hasFractions ) { tSubProPtr oldSub = lastIncomingXComb->subProcess(); theLastPartons.first->set5Momentum(oldSub->incoming().first->momentum()); theLastPartons.second->set5Momentum(oldSub->incoming().second->momentum()); } else { theLastBornME->setXComb(theLastBornXComb); theLastBornXComb->lastParticles(lastIncomingXComb->lastParticles()); theLastBornXComb->lastP1P2(make_pair(0.0, 0.0)); theLastBornXComb->lastS(lastIncomingXComb->lastS()); theLastBornME->generateKinematics(&theLastRandomNumbers[0]); theLastPartons.first->set5Momentum(theLastBornME->lastMEMomenta()[0]); theLastPartons.second->set5Momentum(theLastBornME->lastMEMomenta()[1]); } theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons, theLastMomenta,theLastRandomNumbers); if ( !hasFractions ) { theLastBornME->setXComb(theLastBornXComb); theLastBornME->generateKinematics(&theLastRandomNumbers[2]); } theLastBornME->dSigHatDR(); } void ShowerApproximationGenerator:: handle(EventHandler & eh, const tPVector &, const Hint &) { theFactory->setHardTreeEmitter(-1); theFactory->setHardTreeSpectator(-1); theFactory->setHardTreeSubprocess(SubProPtr()); lastIncomingXComb = dynamic_ptr_cast<tStdXCombPtr>(eh.lastXCombPtr()); if ( !lastIncomingXComb ) throw Exception() << "ShowerApproximationGenerator::handle(): Expecting a standard event handler." << Exception::runerror; bool didproject = false; if ( lastIncomingXComb->lastProjector() ) { lastIncomingXComb = lastIncomingXComb->lastProjector(); didproject = true; } const StandardXComb& xc = *lastIncomingXComb; map<cPDVector,set<Ptr<ShowerApproximationKernel>::ptr> >::const_iterator kernelit = theKernelMap.find(xc.mePartonData()); if ( kernelit == theKernelMap.end() ) { list<MatchboxFactory::SplittingChannel> channels = theFactory->getSplittingChannels(lastIncomingXComb); set<Ptr<ShowerApproximationKernel>::ptr> newKernels; for ( list<MatchboxFactory::SplittingChannel>::const_iterator c = channels.begin(); c != channels.end(); ++c ) { Ptr<ShowerApproximationKernel>::ptr kernel = new_ptr(ShowerApproximationKernel()); kernel->setBornXComb(c->bornXComb); kernel->setRealXComb(c->realXComb); kernel->setTildeXCombs(c->tildeXCombs); kernel->setDipole(c->dipole); kernel->showerApproximation(theShowerApproximation); kernel->presamplingPoints(thePresamplingPoints); kernel->maxtry(theMaxTry); kernel->freezeGrid(theFreezeGrid); kernel->showerApproximationGenerator(this); kernel->doCompensate(theDoCompensate); if ( kernel->dipole()->bornEmitter() > 1 && kernel->dipole()->bornSpectator() > 1 ) { kernel->ptCut(ffPtCut()); } else if ( ( kernel->dipole()->bornEmitter() > 1 && kernel->dipole()->bornSpectator() < 2 ) || ( kernel->dipole()->bornEmitter() < 2 && kernel->dipole()->bornSpectator() > 1 ) ) { kernel->ptCut(fiPtCut()); } else { assert(kernel->dipole()->bornEmitter() < 2 && kernel->dipole()->bornSpectator() < 2); kernel->ptCut(iiPtCut()); } newKernels.insert(kernel); } theKernelMap[xc.mePartonData()] = newKernels; kernelit = theKernelMap.find(xc.mePartonData()); } if ( kernelit->second.empty() ) return; const set<Ptr<ShowerApproximationKernel>::ptr>& kernels = kernelit->second; theLastBornME = (**kernels.begin()).dipole()->underlyingBornME(); if ( theLastBornME->phasespace()->wantCMS() != thePhasespace->wantCMS() ) { throw Exception() << "Mismatch in centre-of-mass-system requirements of hard matrix element phasespace (" << (theLastBornME->phasespace()->wantCMS()?"true":"false") << ") and shower approximation phasespace (" << (thePhasespace->wantCMS()?"true":"false") << ")" << Exception::abortnow; } theLastBornME->phasespace(thePhasespace); theLastBornXComb = (**kernels.begin()).bornXComb(); if ( !prepare(didproject) ) return; Energy winnerPt = ZERO; Ptr<ShowerApproximationKernel>::ptr winnerKernel; try { for ( set<Ptr<ShowerApproximationKernel>::ptr>::const_iterator k = kernels.begin(); k != kernels.end(); ++k ) { if ( (**k).generate() != 0. && (*k)->dipole()->lastPt() > winnerPt){ winnerKernel = *k; winnerPt = winnerKernel->dipole()->lastPt(); } } } catch(ShowerApproximationKernel::MaxTryException&) { throw Exception() << "Too many tries needed to generate the matrix element correction in '" << name() << "'" << Exception::eventerror; } if ( !winnerKernel || winnerPt == ZERO ) return; //Hardest emission should be this one. - winnerKernel->realXComb()->lastCentralScale(sqr(winnerPt)); - winnerKernel->bornXComb()->lastCentralScale(sqr(winnerPt)); - lastIncomingXComb->lastCentralScale(sqr(winnerPt)); + winnerKernel->realXComb()->lastShowerScale(sqr(winnerPt)); + winnerKernel->bornXComb()->lastShowerScale(sqr(winnerPt)); + lastIncomingXComb->lastShowerScale(sqr(winnerPt)); SubProPtr oldSub = lastIncomingXComb->subProcess(); SubProPtr newSub; try { tcDiagPtr bornDiag = lastIncomingXComb->lastDiagram(); tcDiagPtr realDiag = winnerKernel->dipole()->realEmissionDiagram(bornDiag); winnerKernel->realXComb()->externalDiagram(realDiag); newSub = winnerKernel->realXComb()->construct(); } catch(Veto&) { return; } if ( !theShowerApproximation->needsTruncatedShower() ){ tParticleSet firstS = oldSub->incoming().first->siblings(); assert(firstS.empty() || firstS.size() == 1); if ( !firstS.empty() ) { eh.currentStep()->removeParticle(*firstS.begin()); } tParticleSet secondS = oldSub->incoming().second->siblings(); assert(secondS.empty() || secondS.size() == 1); if ( !secondS.empty() ) { eh.currentStep()->removeParticle(*secondS.begin()); } // prevent the colliding particles from disappearing // in the initial state and appearing // in the final state when we've cut off all their // (physical) children; only applies to the case // where we have a parton extractor not build from // noPDF, so check wether the incoming particle // doesnt equal the incoming parton -- this needs fixing in ThePEG PPtr dummy = new_ptr(Particle(getParticleData(ParticleID::gamma))); bool usedDummy = false; if ( eh.currentStep()->incoming().first != oldSub->incoming().first ) { eh.currentStep()->addDecayProduct(eh.currentStep()->incoming().first,dummy); usedDummy = true; } if ( eh.currentStep()->incoming().second != oldSub->incoming().second ) { eh.currentStep()->addDecayProduct(eh.currentStep()->incoming().second,dummy); usedDummy = true; } eh.currentStep()->removeSubProcess(oldSub); eh.currentStep()->addSubProcess(newSub); // get rid of the dummy if ( usedDummy ) { eh.currentStep()->removeParticle(dummy); } eh.select(winnerKernel->realXComb()); winnerKernel->realXComb()->recreatePartonBinInstances(winnerKernel->realXComb()->lastScale()); winnerKernel->realXComb()->refillPartonBinInstances(&(xc.lastRandomNumbers()[0])); winnerKernel->realXComb()->pExtractor()->constructRemnants(winnerKernel->realXComb()->partonBinInstances(), newSub, eh.currentStep()); } else{ theFactory->setHardTreeSubprocess(newSub); theFactory->setHardTreeEmitter(winnerKernel->dipole()->bornEmitter()); theFactory->setHardTreeSpectator(winnerKernel->dipole()->bornSpectator()); } } IBPtr ShowerApproximationGenerator::clone() const { return new_ptr(*this); } IBPtr ShowerApproximationGenerator::fullclone() const { return new_ptr(*this); } // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). void ShowerApproximationGenerator::persistentOutput(PersistentOStream & os) const { os << theShowerApproximation << thePhasespace << theFactory << theKernelMap << thePresamplingPoints << theMaxTry << theFreezeGrid << lastIncomingXComb << theLastBornME << ounit(theLastMomenta,GeV) << ounit(theLastPresamplingMomenta,GeV) << theLastRandomNumbers << theLastBornXComb << theLastPartons << theDoCompensate; } void ShowerApproximationGenerator::persistentInput(PersistentIStream & is, int) { is >> theShowerApproximation >> thePhasespace >> theFactory >> theKernelMap >> thePresamplingPoints >> theMaxTry >> theFreezeGrid >> lastIncomingXComb >> theLastBornME >> iunit(theLastMomenta,GeV) >> iunit(theLastPresamplingMomenta,GeV) >> theLastRandomNumbers >> theLastBornXComb >> theLastPartons >> theDoCompensate; } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeClass<ShowerApproximationGenerator,StepHandler> describeHerwigShowerApproximationGenerator("Herwig::ShowerApproximationGenerator", "Herwig.so"); void ShowerApproximationGenerator::Init() { static ClassDocumentation<ShowerApproximationGenerator> documentation ("ShowerApproximationGenerator generates emissions according to a " "shower approximation entering a NLO matching."); static Reference<ShowerApproximationGenerator,ShowerApproximation> interfaceShowerApproximation ("ShowerApproximation", "Set the shower approximation to sample.", &ShowerApproximationGenerator::theShowerApproximation, false, false, true, false, false); static Reference<ShowerApproximationGenerator,MatchboxPhasespace> interfacePhasespace ("Phasespace", "The phase space generator to use.", &ShowerApproximationGenerator::thePhasespace, false, false, true, false, false); static Reference<ShowerApproximationGenerator,MatchboxFactory> interfaceFactory ("Factory", "The factory object to use.", &ShowerApproximationGenerator::theFactory, false, false, true, false, false); static Parameter<ShowerApproximationGenerator,unsigned long> interfacePresamplingPoints ("PresamplingPoints", "Set the number of presampling points.", &ShowerApproximationGenerator::thePresamplingPoints, 2000, 1, 0, false, false, Interface::lowerlim); static Parameter<ShowerApproximationGenerator,unsigned long> interfaceMaxTry ("MaxTry", "Set the number of maximum attempts.", &ShowerApproximationGenerator::theMaxTry, 100000, 1, 0, false, false, Interface::lowerlim); static Parameter<ShowerApproximationGenerator,unsigned long> interfaceFreezeGrid ("FreezeGrid", "", &ShowerApproximationGenerator::theFreezeGrid, 500000, 1, 0, false, false, Interface::lowerlim); static Switch<ShowerApproximationGenerator,bool> interfaceDoCompensate ("DoCompensate", "", &ShowerApproximationGenerator::theDoCompensate, false, false, false); static SwitchOption interfaceDoCompensateYes (interfaceDoCompensate, "Yes", "", true); static SwitchOption interfaceDoCompensateNo (interfaceDoCompensate, "No", "", false); } diff --git a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc --- a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc +++ b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc @@ -1,213 +1,214 @@ // -*- C++ -*- // // InvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2012 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the InvertedTildeKinematics class. // #include <limits> #include "InvertedTildeKinematics.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ThePEG/Utilities/Rebinder.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h" using namespace Herwig; InvertedTildeKinematics::InvertedTildeKinematics() : HandlerBase(), theJacobian(0.0), thePtCut(0.0*GeV) {} InvertedTildeKinematics::~InvertedTildeKinematics() {} // If needed, insert default implementations of virtual function defined // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). Lorentz5Momentum InvertedTildeKinematics::getKt(const Lorentz5Momentum& p1, const Lorentz5Momentum& p2, Energy pt, double phi, bool spacelike) const { Lorentz5Momentum P; if ( !spacelike ) P = p1 + p2; else P = p1 - p2; Energy2 Q2 = abs(P.m2()); Lorentz5Momentum Q = !spacelike ? Lorentz5Momentum(ZERO,ZERO,ZERO,sqrt(Q2),sqrt(Q2)) : Lorentz5Momentum(ZERO,ZERO,sqrt(Q2),ZERO,-sqrt(Q2)); if ( spacelike && Q.z() < P.z() ) Q.setZ(-Q.z()); bool boost = abs((P-Q).vect().mag2()/GeV2) > 1e-10 || abs((P-Q).t()/GeV) > 1e-5; + boost &= (P*Q-Q.mass2())/GeV2 > 1e-8; Lorentz5Momentum inFrame1; if ( boost ) inFrame1 = p1 + ((P*p1-Q*p1)/(P*Q-Q.mass2()))*(P-Q); else inFrame1 = p1; Energy ptx = inFrame1.x(); Energy pty = inFrame1.y(); Energy q = 2.*inFrame1.z(); Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q)); Energy Qy = sqrt(4.*sqr(pty)+sqr(q)); double cPhi = cos(phi); double sPhi = sqrt(1.-sqr(cPhi)); if ( phi > Constants::pi ) sPhi = -sPhi; Lorentz5Momentum kt; if ( !spacelike ) { kt.setT(ZERO); kt.setX(pt*Qy*cPhi/Qp); kt.setY(-pt*(4*ptx*pty*cPhi/Qp+q*sPhi)/Qy); kt.setZ(2.*pt*(-ptx*q*cPhi/Qp + pty*sPhi)/Qy); } else { kt.setT(2.*pt*(ptx*q*cPhi+pty*Qp*sPhi)/(q*Qy)); kt.setX(pt*(Qp*q*cPhi+4.*ptx*pty*sPhi)/(q*Qy)); kt.setY(pt*Qy*sPhi/q); kt.setZ(ZERO); } if ( boost ) kt = kt + ((P*kt-Q*kt)/(P*Q-Q.mass2()))*(P-Q); kt.setMass(-pt); kt.rescaleRho(); return kt; } Energy InvertedTildeKinematics::lastScale() const { if ( ( theDipole->bornEmitter() < 2 && theDipole->bornSpectator() > 1 ) || ( theDipole->bornEmitter() > 1 && theDipole->bornSpectator() < 2 ) ) { return -(bornEmitterMomentum()-bornSpectatorMomentum()).m(); } return (bornEmitterMomentum()+bornSpectatorMomentum()).m(); } pair<Energy,double> InvertedTildeKinematics::generatePtZ(double& jac, const double * r, double pow) const { double kappaMin = ptCut() != ZERO ? sqr(ptCut()/ptMax()) : sqr(0.1*GeV/GeV); double kappa; using namespace RandomHelpers; if ( ptCut() > ZERO ) { pair<double,double> kw = pow==1. ? generate(inverse(0.,kappaMin,1.),r[0]) : generate(power(0.,-pow,kappaMin,1.),r[0]); kappa = kw.first; jac *= kw.second; } else { pair<double,double> kw = generate((piecewise(), flat(1e-4,kappaMin), match(inverse(0.,kappaMin,1.))),r[0]); kappa = kw.first; jac *= kw.second; } Energy pt = sqrt(kappa)*ptMax(); pair<double,double> zLims = zBounds(pt); pair<double,double> zw(0,0);// = // generate(inverse(0.,zLims.first,zLims.second)+ // inverse(1.,zLims.first,zLims.second),r[1]); // FlatZ = 1 if ( theDipole->samplingZ() == 1 ) { zw = generate(flat(zLims.first,zLims.second),r[1]); } // OneOverZ = 2 if ( theDipole->samplingZ() == 2 ) { zw = generate(inverse(0.0,zLims.first,zLims.second),r[1]); } // OneOverOneMinusZ = 3 if ( theDipole->samplingZ() == 3 ) { zw = generate(inverse(1.0,zLims.first,zLims.second),r[1]); } // OneOverZOneMinusZ = 4 if ( theDipole->samplingZ() == 4 ) { zw = generate(inverse(0.0,zLims.first,zLims.second) + inverse(1.0,zLims.first,zLims.second),r[1]); } double z = zw.first; jac *= zw.second; jac *= sqr(ptMax()/lastScale()); return make_pair(pt,z); } void InvertedTildeKinematics::rebind(const TranslationMap & trans) { theDipole = trans.translate(theDipole); HandlerBase::rebind(trans); } IVector InvertedTildeKinematics::getReferences() { IVector ret = HandlerBase::getReferences(); ret.push_back(theDipole); return ret; } void InvertedTildeKinematics::persistentOutput(PersistentOStream & os) const { os << theDipole << theRealXComb << theBornXComb << ounit(theRealEmitterMomentum,GeV) << ounit(theRealEmissionMomentum,GeV) << ounit(theRealSpectatorMomentum,GeV) << theJacobian << ounit(thePtCut,GeV); } void InvertedTildeKinematics::persistentInput(PersistentIStream & is, int) { is >> theDipole >> theRealXComb >> theBornXComb >> iunit(theRealEmitterMomentum,GeV) >> iunit(theRealEmissionMomentum,GeV) >> iunit(theRealSpectatorMomentum,GeV) >> theJacobian >> iunit(thePtCut,GeV); } void InvertedTildeKinematics::Init() { static ClassDocumentation<InvertedTildeKinematics> documentation ("InvertedTildeKinematics is the base class for the inverted 'tilde' " "kinematics being used for subtraction terms in the " "formalism of Catani and Seymour."); } // *** Attention *** The following static variable is needed for the type // description system in ThePEG. Please check that the template arguments // are correct (the class and its base class), and that the constructor // arguments are correct (the class name and the name of the dynamically // loadable library where the class implementation can be found). DescribeAbstractClass<InvertedTildeKinematics,HandlerBase> describeInvertedTildeKinematics("Herwig::InvertedTildeKinematics", "Herwig.so"); diff --git a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h --- a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h +++ b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h @@ -1,161 +1,169 @@ // -*- C++ -*- // // MatchboxScaleChoice.h is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2012 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef Herwig_MatchboxScaleChoice_H #define Herwig_MatchboxScaleChoice_H // // This is the declaration of the MatchboxScaleChoice class. // #include "ThePEG/Handlers/HandlerBase.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/Handlers/LastXCombInfo.h" namespace Herwig { using namespace ThePEG; /** * \ingroup Matchbox * \author Simon Platzer * * \brief MatchboxScaleChoice is the base class for scale choices * within Matchbox. * */ class MatchboxScaleChoice: public HandlerBase, public LastXCombInfo<StandardXComb> { public: /** @name Standard constructors and destructors. */ //@{ /** * The default constructor. */ MatchboxScaleChoice(); /** * The destructor. */ virtual ~MatchboxScaleChoice(); //@} public: /** * Clone this scale choice. */ Ptr<MatchboxScaleChoice>::ptr cloneMe() const { return dynamic_ptr_cast<Ptr<MatchboxScaleChoice>::ptr>(clone()); } /** * Set the XComb object. */ virtual void setXComb(tStdXCombPtr xc) { theLastXComb = xc; } /** * Return the renormalization scale. This default version returns * shat. */ virtual Energy2 renormalizationScale() const { return theFixedScale == ZERO ? lastSHat() : sqr(theFixedScale); } /** * Return the factorization scale. This default version returns * shat. */ virtual Energy2 factorizationScale() const { return theFixedScale == ZERO ? lastSHat() : sqr(theFixedScale); } /** * Return the QED renormalization scale. This default version returns * the Z mass squared. */ virtual Energy2 renormalizationScaleQED() const { if ( theFixedQEDScale != ZERO ) return sqr(theFixedQEDScale); Energy mZ = getParticleData(ParticleID::Z0)->hardProcessMass(); return mZ*mZ; } + /** + * Return the shower hard scale. This default implementation returns the + * factorization scale. + */ + virtual Energy2 showerScale() const { + return factorizationScale(); + } + public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual IBPtr fullclone() const; //@} // If needed, insert declarations of virtual function defined in the // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). private: /** * A fixed scale choice. If zero, shat will be used. */ Energy theFixedScale; /** * A fixed QED scale choice. If zero, shat will be used. */ Energy theFixedQEDScale; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ MatchboxScaleChoice & operator=(const MatchboxScaleChoice &); }; } #endif /* Herwig_MatchboxScaleChoice_H */ diff --git a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc new file mode 100644 --- /dev/null +++ b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.cc @@ -0,0 +1,2200 @@ +// -*- C++ -*- +// +// This is the implementation of the non-inlined, non-templated member +// functions of the MEPP2GammaGammaPowheg class. +// + +#include "MEPP2GammaGammaPowheg.h" +#include "ThePEG/Interface/ClassDocumentation.h" +#include "ThePEG/Interface/Switch.h" +#include "ThePEG/Interface/Parameter.h" +#include "ThePEG/Interface/Reference.h" +#include "ThePEG/Persistency/PersistentOStream.h" +#include "ThePEG/Persistency/PersistentIStream.h" +#include "ThePEG/PDT/EnumParticles.h" +#include "ThePEG/MatrixElement/Tree2toNDiagram.h" +#include "ThePEG/Cuts/Cuts.h" +#include "ThePEG/Utilities/SimplePhaseSpace.h" +#include "Herwig/Models/StandardModel/StandardModel.h" +#include "Herwig/Utilities/Maths.h" +#include "Herwig/Shower/Base/ShowerTree.h" +#include "Herwig/Shower/Base/ShowerProgenitor.h" +#include "Herwig/Shower/Base/ShowerParticle.h" +#include "Herwig/Shower/Base/Branching.h" +#include "Herwig/Shower/Base/HardTree.h" +#include "ThePEG/Utilities/DescribeClass.h" + +using namespace Herwig; + +// The following static variable is needed for the type +// description system in ThePEG. +DescribeClass<MEPP2GammaGammaPowheg,Herwig::HwMEBase> +describeMEPP2GammaGammaPowheg("Herwig::MEPP2GammaGammaPowheg", + "HwMEHadron.so HwPowhegMEHadron.so"); + +unsigned int MEPP2GammaGammaPowheg::orderInAlphaS() const { + return 0; +} + +unsigned int MEPP2GammaGammaPowheg::orderInAlphaEW() const { + return 2; +} + +IBPtr MEPP2GammaGammaPowheg::clone() const { + return new_ptr(*this); +} + +IBPtr MEPP2GammaGammaPowheg::fullclone() const { + return new_ptr(*this); +} + +MEPP2GammaGammaPowheg::MEPP2GammaGammaPowheg() + : contrib_(1), power_(0.1), process_(0), threeBodyProcess_(0), + maxflavour_(5), alphaS_(0.), fixedAlphaS_(false), + supressionFunction_(0), supressionScale_(0), lambda_(20.*GeV), + preQCDqqbarq_(5.), preQCDqqbarqbar_(0.5), preQCDqg_(50.), preQCDgqbar_(50.), + preQEDqqbarq_(40.), preQEDqqbarqbar_(0.5), preQEDqgq_(1.), preQEDgqbarqbar_(1.), + minpT_(2.*GeV), scaleChoice_(0), scalePreFactor_(1.) +{} + +void MEPP2GammaGammaPowheg::getDiagrams() const { + tcPDPtr gamma = getParticleData(ParticleID::gamma); + tcPDPtr g = getParticleData(ParticleID::g); + for(int ix=1;ix<=maxflavour_;++ix) { + tcPDPtr qk = getParticleData(ix); + tcPDPtr qb = qk->CC(); + // gamma gamma + if(process_==0 || process_ == 1) { + add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 1, gamma, 2, gamma, -1))); + add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 2, gamma, 1, gamma, -2))); + } + // gamma +jet + if(process_==0 || process_ == 2) { + add(new_ptr((Tree2toNDiagram(3), qk, qb, qb, 1, gamma, + 2, g, -4))); + add(new_ptr((Tree2toNDiagram(3), qk, qk, qb, 2, gamma, + 1, g, -5))); + add(new_ptr((Tree2toNDiagram(3), qk, qk, g, 1, gamma, + 2, qk, -6))); + add(new_ptr((Tree2toNDiagram(2), qk, g, 1, qk, 3, gamma, + 3, qk, -7))); + add(new_ptr((Tree2toNDiagram(3), g, qb, qb, 2, gamma, + 1, qb, -8))); + add(new_ptr((Tree2toNDiagram(2), g, qb, 1, qb, 3, gamma, + 3, qb, -9))); + } + // gamma + jet + gamma + if((process_==0 && contrib_==1) || process_ == 3) { + // gamma + g + gamma + if(threeBodyProcess_==0 || threeBodyProcess_==1) { + add(new_ptr((Tree2toNDiagram(4), qk, qk, qk, qb, 1, gamma, + 2, gamma, 3, g, -10))); + add(new_ptr((Tree2toNDiagram(4), qk, qk, qk, qb, 3, gamma, + 2, gamma, 1, g, -12))); + } + // Z + q + gamma + if(threeBodyProcess_==0 || threeBodyProcess_==2) { + add(new_ptr((Tree2toNDiagram(4),qk,qk,qk,g,1,gamma,2,gamma,3,qk, -20))); + add(new_ptr((Tree2toNDiagram(4),qk,qk,qk,g,2,gamma,1,gamma,3,qk, -21))); + add(new_ptr((Tree2toNDiagram(3),qk,qk,g,1,gamma,2,qk,5,gamma,5,qk,-22))); + } + // Z + qbar + gamma + if(threeBodyProcess_==0 || threeBodyProcess_==3) { + add(new_ptr((Tree2toNDiagram(4),g,qb,qb,qb,3,gamma,2,gamma,1,qb ,-30))); + add(new_ptr((Tree2toNDiagram(4),g,qb,qb,qb,2,gamma,3,gamma,1,qb ,-31))); + add(new_ptr((Tree2toNDiagram(3),g,qb,qb ,2,gamma,1,qb,5,gamma,5,qb,-32))); + } + } + } +} + +Energy2 MEPP2GammaGammaPowheg::scale() const { + Energy2 scale; + if(scaleChoice_==0) { + Energy pt; + if(meMomenta()[2].perp(meMomenta()[0].vect())>= + meMomenta()[3].perp(meMomenta()[0].vect())){ + pt = meMomenta()[2].perp(meMomenta()[0].vect()); + } else { + pt = meMomenta()[3].perp(meMomenta()[0].vect()); + } + scale = sqr(pt); + } + else if(scaleChoice_==1) { + scale = sHat(); + } + return scalePreFactor_*scale; +} + +int MEPP2GammaGammaPowheg::nDim() const { + return HwMEBase::nDim() + ( contrib_>=1 ? 3 : 0 ); +} + +bool MEPP2GammaGammaPowheg::generateKinematics(const double * r) { + // radiative variables + if(contrib_>=1) { + zTilde_ = r[nDim()-1]; + vTilde_ = r[nDim()-2]; + phi_ = Constants::twopi*r[nDim()-3]; + } + // set the jacobian + jacobian(1.0); + // set up the momenta + for ( int i = 2, N = meMomenta().size(); i < N; ++i ) + meMomenta()[i] = Lorentz5Momentum(ZERO); + // generate sHat + Energy2 shat(sHat()); + if(mePartonData().size()==5) { + double eps = sqr(meMomenta()[2].mass())/shat; + jacobian(jacobian()*(1.-eps)); + shat *= eps+zTilde_*(1.-eps); + } + // momenta of the core process + double ctmin = -1.0, ctmax = 1.0; + Energy q = ZERO; + try { + q = SimplePhaseSpace:: + getMagnitude(shat, meMomenta()[2].mass(), ZERO); + } + catch ( ImpossibleKinematics ) { + return false; + } + Energy e = 0.5*sqrt(shat); + Energy2 m22 = meMomenta()[2].mass2(); + Energy2 e0e2 = 2.0*e*sqrt(sqr(q) + m22); + Energy2 e1e2 = 2.0*e*sqrt(sqr(q) + m22); + Energy2 e0e3 = 2.0*e*sqrt(sqr(q)); + Energy2 e1e3 = 2.0*e*sqrt(sqr(q)); + Energy2 pq = 2.0*e*q; + if(mePartonData().size()==4) { + Energy2 thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[2]); + if ( thmin > ZERO ) ctmax = min(ctmax, (e0e2 - m22 - thmin)/pq); + thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[2]); + if ( thmin > ZERO ) ctmin = max(ctmin, (thmin + m22 - e1e2)/pq); + thmin = lastCuts().minTij(mePartonData()[1], mePartonData()[3]); + if ( thmin > ZERO ) ctmax = min(ctmax, (e1e3 - thmin)/pq); + thmin = lastCuts().minTij(mePartonData()[0], mePartonData()[3]); + if ( thmin > ZERO ) ctmin = max(ctmin, (thmin - e0e3)/pq); + Energy ptmin = max(lastCuts().minKT(mePartonData()[2]), + lastCuts().minKT(mePartonData()[3])); + if ( ptmin > ZERO ) { + double ctm = 1.0 - sqr(ptmin/q); + if ( ctm <= 0.0 ) return false; + ctmin = max(ctmin, -sqrt(ctm)); + ctmax = min(ctmax, sqrt(ctm)); + } + double ymin2 = lastCuts().minYStar(mePartonData()[2]); + double ymax2 = lastCuts().maxYStar(mePartonData()[2]); + double ymin3 = lastCuts().minYStar(mePartonData()[3]); + double ymax3 = lastCuts().maxYStar(mePartonData()[3]); + double ytot = lastCuts().Y() + lastCuts().currentYHat(); + if ( ymin2 + ytot > -0.9*Constants::MaxRapidity ) + ctmin = max(ctmin, sqrt(sqr(q) + m22)*tanh(ymin2)/q); + if ( ymax2 + ytot < 0.9*Constants::MaxRapidity ) + ctmax = min(ctmax, sqrt(sqr(q) + m22)*tanh(ymax2)/q); + if ( ymin3 + ytot > -0.9*Constants::MaxRapidity ) + ctmax = min(ctmax, tanh(-ymin3)); + if ( ymax3 + ytot < 0.9*Constants::MaxRapidity ) + ctmin = max(ctmin, tanh(-ymax3)); + if ( ctmin >= ctmax ) return false; + } + double cth = getCosTheta(ctmin, ctmax, r[0]); + Energy pt = q*sqrt(1.0-sqr(cth)); + phi(rnd(2.0*Constants::pi)); + meMomenta()[2].setVect(Momentum3( pt*sin(phi()), pt*cos(phi()), q*cth)); + meMomenta()[3].setVect(Momentum3(-pt*sin(phi()), -pt*cos(phi()), -q*cth)); + meMomenta()[2].rescaleEnergy(); + meMomenta()[3].rescaleEnergy(); + // jacobian + tHat(pq*cth + m22 - e0e2); + uHat(m22 - shat - tHat()); + jacobian(pq/shat*Constants::pi*jacobian()); + // end for 2->2 processes + if(mePartonData().size()==4) { + vector<LorentzMomentum> out(2); + out[0] = meMomenta()[2]; + out[1] = meMomenta()[3]; + tcPDVector tout(2); + tout[0] = mePartonData()[2]; + tout[1] = mePartonData()[3]; + if ( !lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]) ) + return false; + return true; + } + // special for 2-3 processes + pair<double,double> x = make_pair(lastX1(),lastX2()); + // partons + pair<tcPDPtr,tcPDPtr> partons = make_pair(mePartonData()[0],mePartonData()[1]); + // If necessary swap the particle data objects so that + // first beam gives the incoming quark + if(lastPartons().first ->dataPtr()!=partons.first) { + swap(x.first,x.second); + } + // use vTilde to select the dipole for emission + // gamma gamma g processes + if(mePartonData()[4]->id()==ParticleID::g) { + if(vTilde_<=0.5) { + dipole_ = IIQCD1; + vTilde_ = 4.*vTilde_; + } + else { + dipole_ = IIQCD2; + vTilde_ = 4.*(vTilde_-0.25); + } + jacobian(2.*jacobian()); + } + // gamma gamma q processes + else if(mePartonData()[4]->id()>0&&mePartonData()[4]->id()<6) { + if(vTilde_<=1./3.) { + dipole_ = IIQCD2; + vTilde_ = 3.*vTilde_; + } + else if(vTilde_<=2./3.) { + dipole_ = IFQED1; + vTilde_ = 3.*vTilde_-1.; + } + else { + dipole_ = FIQED1; + vTilde_ = 3.*vTilde_-2.; + } + jacobian(3.*jacobian()); + } + // gamma gamma qbar processes + else if(mePartonData()[4]->id()<0&&mePartonData()[4]->id()>-6) { + if(vTilde_<=1./3.) { + dipole_ = IIQCD1; + vTilde_ = 3.*vTilde_; + } + else if(vTilde_<=2./3.) { + dipole_ = IFQED2; + vTilde_ = 3.*vTilde_-1.; + } + else { + dipole_ = FIQED2; + vTilde_ = 3.*vTilde_-2.; + } + jacobian(3.*jacobian()); + } + else { + assert(false); + } + // initial-initial dipoles + if(dipole_<=4) { + double z = shat/sHat(); + double vt = vTilde_*(1.-z); + double vJac = 1.-z; + Energy pT = sqrt(shat*vt*(1.-vt-z)/z); + if(pT<MeV) return false; + double rapidity; + Energy rs=sqrt(lastS()); + Lorentz5Momentum pcmf; + // emission from first beam + if(dipole_<=2) { + rapidity = -log(x.second*sqrt(lastS())/pT*vt); + pcmf = Lorentz5Momentum(ZERO,ZERO, + 0.5*rs*(x.first*z-x.second), + 0.5*rs*(x.first*z+x.second)); + } + // emission from second beam + else { + rapidity = log(x.first *sqrt(lastS())/pT*vt); + pcmf = Lorentz5Momentum(ZERO,ZERO, + 0.5*rs*(x.first-x.second*z), + 0.5*rs*(x.first+x.second*z)); + } + pcmf.rescaleMass(); + Boost blab(pcmf.boostVector()); + // emission from the quark radiation + vector<Lorentz5Momentum> pnew(5); + pnew [0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first, + 0.5*rs*x.first,ZERO); + pnew [1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second, + 0.5*rs*x.second,ZERO) ; + pnew [2] = meMomenta()[2]; + pnew [3] = meMomenta()[3]; + pnew [4] = Lorentz5Momentum(pT*cos(phi_),pT*sin(phi_), + pT*sinh(rapidity), + pT*cosh(rapidity), ZERO); + pnew[4].rescaleEnergy(); + Lorentz5Momentum K = pnew [0]+pnew [1]-pnew [4]; + Lorentz5Momentum Kt = pcmf; + Lorentz5Momentum Ksum = K+Kt; + Energy2 K2 = K.m2(); + Energy2 Ksum2 = Ksum.m2(); + for(unsigned int ix=2;ix<4;++ix) { + pnew [ix].boost(blab); + pnew [ix] = pnew [ix] - 2.*Ksum*(Ksum*pnew [ix])/Ksum2 + +2*K*(Kt*pnew [ix])/K2; + pnew[ix].rescaleEnergy(); + } + pcmf = Lorentz5Momentum(ZERO,ZERO, + 0.5*rs*(x.first-x.second), + 0.5*rs*(x.first+x.second)); + pcmf.rescaleMass(); + blab = pcmf.boostVector(); + for(unsigned int ix=0;ix<pnew.size();++ix) + pnew[ix].boost(-blab); + // phase-space prefactors + jacobian(jacobian()*vJac); + if(dipole_%2!=0) swap(pnew[3],pnew[4]); + for(unsigned int ix=2;ix<meMomenta().size();++ix) + meMomenta()[ix] = pnew[ix]; + } + else if(dipole_<=8) { + double x = shat/sHat(); + double z = vTilde_; + double x1 = -1./x; + double x3 = 1.-z/x; + double x2 = 2.+x1-x3; + double xT = sqrt(4.*(1-x)*(1-z)*z/x); + // rotate the momenta into the Breit-frame + Lorentz5Momentum pin,pcmf; + if(dipole_<=6) { + pin = x*meMomenta()[0]; + pcmf = pin+meMomenta()[1]; + } + else { + pin = x*meMomenta()[1]; + pcmf = pin+meMomenta()[0]; + } + Boost bv = pcmf.boostVector(); + meMomenta()[2].boost(bv); + meMomenta()[3].boost(bv); + Lorentz5Momentum q = meMomenta()[3]-pin; + Axis axis(q.vect().unit()); + LorentzRotation rot; + double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); + rot = LorentzRotation(); + if(axis.perp2()>1e-20) { + rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); + rot.rotateX(Constants::pi); + } + if(abs(1.-q.e()/q.vect().mag())>1e-6) + rot.boostZ(q.e()/q.vect().mag()); + pin *= rot; + if(pin.perp2()/GeV2>1e-20) { + Boost trans = -1./pin.e()*pin.vect(); + trans.setZ(0.); + rot.boost(trans); + } + rot.invert(); + Energy Q = sqrt(-q.m2()); + meMomenta()[4] = rot*Lorentz5Momentum( 0.5*Q*xT*cos(phi_), 0.5*Q*xT*sin(phi_), + -0.5*Q*x2,0.5*Q*sqrt(sqr(x2)+sqr(xT))); + meMomenta()[3] = rot*Lorentz5Momentum(-0.5*Q*xT*cos(phi_),-0.5*Q*xT*sin(phi_), + -0.5*Q*x3,0.5*Q*sqrt(sqr(x3)+sqr(xT))); + + double ratio; + if(dipole_<=6) { + ratio = 2.*((meMomenta()[3]+meMomenta()[4])*meMomenta()[0])/sHat(); + } + else { + ratio = 2.*((meMomenta()[3]+meMomenta()[4])*meMomenta()[1])/sHat(); + } + jacobian(jacobian()*ratio); + } + else { + assert(false); + } + vector<LorentzMomentum> out(3); + tcPDVector tout(3); + for(unsigned int ix=0;ix<3;++ix) { + out[ix] = meMomenta() [2+ix]; + tout[ix] = mePartonData()[2+ix]; + } + return lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]); +} + +double MEPP2GammaGammaPowheg::me2() const { + // Born configurations + if(mePartonData().size()==4) { + // gamma gamma core process + if(mePartonData()[3]->id()==ParticleID::gamma) { + return 2.*Constants::twopi*alphaEM_* + loGammaGammaME(mePartonData(),meMomenta(),true); + } + // V jet core process + else if(mePartonData()[3]->id()==ParticleID::g) { + return 2.*Constants::twopi*alphaS_* + loGammagME(mePartonData(),meMomenta(),true); + } + else if(mePartonData()[3]->id()>0) { + return 2.*Constants::twopi*alphaS_* + loGammaqME(mePartonData(),meMomenta(),true); + } + else if(mePartonData()[3]->id()<0) { + return 2.*Constants::twopi*alphaS_* + loGammaqbarME(mePartonData(),meMomenta(),true); + } + else + assert(false); + } + // hard emission configurations + else { + if(mePartonData()[4]->id()==ParticleID::g) + return sHat()*realGammaGammagME (mePartonData(),meMomenta(),dipole_,Hard,true); + else if(mePartonData()[4]->id()>0&&mePartonData()[4]->id()<6) + return sHat()*realGammaGammaqME (mePartonData(),meMomenta(),dipole_,Hard,true); + else if(mePartonData()[4]->id()<0&&mePartonData()[4]->id()>-6) + return sHat()*realGammaGammaqbarME(mePartonData(),meMomenta(),dipole_,Hard,true); + else + assert(false); + } +} + +CrossSection MEPP2GammaGammaPowheg::dSigHatDR() const { + // couplings + if(!fixedAlphaS_) alphaS_ = SM().alphaS(scale()); + alphaEM_ = SM().alphaEM(); + // cross section + CrossSection preFactor = + jacobian()/(16.0*sqr(Constants::pi)*sHat())*sqr(hbarc); + loME_ = me2(); + + if( contrib_== 0 || mePartonData().size()==5 || + (mePartonData().size()==4&& mePartonData()[3]->coloured())) + return loME_*preFactor; + else + return NLOWeight()*preFactor; +} + + +Selector<MEBase::DiagramIndex> +MEPP2GammaGammaPowheg::diagrams(const DiagramVector & diags) const { + if(mePartonData().size()==4) { + if(mePartonData()[3]->id()==ParticleID::gamma) { + + Selector<DiagramIndex> sel; + for ( DiagramIndex i = 0; i < diags.size(); ++i ){ + sel.insert(meInfo()[abs(diags[i]->id())], i); + } + return sel; + } + else { + Selector<DiagramIndex> sel; + for ( DiagramIndex i = 0; i < diags.size(); ++i ){ + sel.insert(meInfo()[abs(diags[i]->id())%2], i); + } + return sel; + } + } + else { + Selector<DiagramIndex> sel; + for ( DiagramIndex i = 0; i < diags.size(); ++i ) { + if(abs(diags[i]->id()) == 10 && dipole_ == IIQCD2 ) + sel.insert(1., i); + else if(abs(diags[i]->id()) == 12 && dipole_ == IIQCD1 ) + sel.insert(1., i); + else if(abs(diags[i]->id()) == 20 && dipole_ == IIQCD2 ) + sel.insert(1., i); + else if(abs(diags[i]->id()) == 21 && dipole_ == IFQED1 ) + sel.insert(1., i); + else if(abs(diags[i]->id()) == 22 && dipole_ == FIQED1 ) + sel.insert(1., i); + else + sel.insert(0., i); + } + return sel; + } +} + +Selector<const ColourLines *> +MEPP2GammaGammaPowheg::colourGeometries(tcDiagPtr diag) const { + // colour lines for V gamma + static ColourLines cs("1 -2"); + static ColourLines ct("1 2 -3"); + // colour lines for q qbar -> V g + static const ColourLines cqqbar[2]={ColourLines("1 -2 5,-3 -5"), + ColourLines("1 5,-5 2 -3")}; + // colour lines for q g -> V q + static const ColourLines cqg [2]={ColourLines("1 2 -3,3 5"), + ColourLines("1 -2,2 3 5")}; + // colour lines for g qbar -> V qbar + static const ColourLines cgqbar[2]={ColourLines("-3 -2 1,-1 -5"), + ColourLines("-2 1,-1 -3 -5")}; + // colour lines for q qbar -> V gamma g + static const ColourLines cqqbarg[4]={ColourLines("1 2 3 7,-4 -7"), + ColourLines("1 2 7,-4 3 -7"), + ColourLines("1 7,-4 3 2 -7"), + ColourLines("1 2 7,-4 3 -7")}; + // colour lines for q g -> V gamma q + static const ColourLines cqgq [3]={ColourLines("1 2 3 -4,4 7"), + ColourLines("1 2 3 -4,4 7"), + ColourLines("1 2 -3,3 5 7")}; + // colour lines for gbar -> V gamma qbar + static const ColourLines cqbargqbar[3]={ColourLines("1 -2 -3 -4,-1 -7"), + ColourLines("1 -2 -3 -4,-1 -7"), + ColourLines("1 -2 -3,-1 -5 -7")}; + Selector<const ColourLines *> sel; + switch(abs(diag->id())) { + case 1 :case 2 : + sel.insert(1.0, &ct); + break; + case 3 : + sel.insert(1.0, &cs); + break; + case 4 : + sel.insert(1.0, &cqqbar[0]); + break; + case 5: + sel.insert(1.0, &cqqbar[1]); + break; + case 6: + sel.insert(1.0, &cqg[0]); + break; + case 7: + sel.insert(1.0, &cqg[1]); + break; + case 8: + sel.insert(1.0, &cgqbar[0]); + break; + case 9: + sel.insert(1.0, &cgqbar[1]); + break; + case 10: case 11: case 12: case 13: + sel.insert(1.0, &cqqbarg[abs(diag->id())-10]); + break; + case 20: case 21: case 22: + sel.insert(1.0, &cqgq[abs(diag->id())-20]); + break; + case 30: case 31: case 32: + sel.insert(1.0, &cqbargqbar[abs(diag->id())-30]); + break; + default: + assert(false); + } + return sel; +} + +void MEPP2GammaGammaPowheg::persistentOutput(PersistentOStream & os) const { + os << FFPvertex_ << FFGvertex_ + << contrib_ << power_ << gluon_ << prefactor_ + << process_ << threeBodyProcess_<< maxflavour_ + << alphaS_ << fixedAlphaS_ + << supressionFunction_ << supressionScale_ << ounit(lambda_,GeV) + << alphaQCD_ << alphaQED_ << ounit(minpT_,GeV) + << preQCDqqbarq_ << preQCDqqbarqbar_ << preQCDqg_ << preQCDgqbar_ + << preQEDqqbarq_ << preQEDqqbarqbar_ << preQEDqgq_ << preQEDgqbarqbar_ + << scaleChoice_ << scalePreFactor_; +} + +void MEPP2GammaGammaPowheg::persistentInput(PersistentIStream & is, int) { + is >> FFPvertex_ >> FFGvertex_ + >> contrib_ >> power_ >> gluon_ >> prefactor_ + >> process_ >> threeBodyProcess_ >> maxflavour_ + >> alphaS_ >> fixedAlphaS_ + >> supressionFunction_ >> supressionScale_ >> iunit(lambda_,GeV) + >> alphaQCD_ >> alphaQED_ >> iunit(minpT_,GeV) + >> preQCDqqbarq_ >> preQCDqqbarqbar_ >> preQCDqg_ >> preQCDgqbar_ + >> preQEDqqbarq_ >> preQEDqqbarqbar_ >> preQEDqgq_ >> preQEDgqbarqbar_ + >> scaleChoice_ >> scalePreFactor_; +} + +void MEPP2GammaGammaPowheg::Init() { + + static ClassDocumentation<MEPP2GammaGammaPowheg> documentation + ("TheMEPP2GammaGammaPowheg class implements gamma gamma production at NLO"); + + static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceProcess + ("Process", + "Which processes to include", + &MEPP2GammaGammaPowheg::process_, 0, false, false); + static SwitchOption interfaceProcessAll + (interfaceProcess, + "All", + "Include all the processes", + 0); + static SwitchOption interfaceProcessGammaGamma + (interfaceProcess, + "GammaGamma", + "Only include gamma gamma", + 1); + static SwitchOption interfaceProcessVJet + (interfaceProcess, + "VJet", + "Only include gamma + jet", + 2); + static SwitchOption interfaceProcessHard + (interfaceProcess, + "Hard", + "Only include hard radiation contributions", + 3); + + static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceThreeBodyProcess + ("ThreeBodyProcess", + "The possible three body processes to include", + &MEPP2GammaGammaPowheg::threeBodyProcess_, 0, false, false); + static SwitchOption interfaceThreeBodyProcessAll + (interfaceThreeBodyProcess, + "All", + "Include all processes", + 0); + static SwitchOption interfaceThreeBodyProcessqqbar + (interfaceThreeBodyProcess, + "qqbar", + "Only include q qbar -> gamma gamma g processes", + 1); + static SwitchOption interfaceThreeBodyProcessqg + (interfaceThreeBodyProcess, + "qg", + "Only include q g -> gamma gamma q processes", + 2); + static SwitchOption interfaceThreeBodyProcessgqbar + (interfaceThreeBodyProcess, + "gqbar", + "Only include g qbar -> gamma gamma qbar processes", + 3); + + static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceContribution + ("Contribution", + "Which contributions to the cross section to include", + &MEPP2GammaGammaPowheg::contrib_, 1, false, false); + static SwitchOption interfaceContributionLeadingOrder + (interfaceContribution, + "LeadingOrder", + "Just generate the leading order cross section", + 0); + static SwitchOption interfaceContributionPositiveNLO + (interfaceContribution, + "PositiveNLO", + "Generate the positive contribution to the full NLO cross section", + 1); + static SwitchOption interfaceContributionNegativeNLO + (interfaceContribution, + "NegativeNLO", + "Generate the negative contribution to the full NLO cross section", + 2); + + static Parameter<MEPP2GammaGammaPowheg,int> interfaceMaximumFlavour + ("MaximumFlavour", + "The maximum flavour allowed for the incoming quarks", + &MEPP2GammaGammaPowheg::maxflavour_, 5, 1, 5, + false, false, Interface::limited); + + static Parameter<MEPP2GammaGammaPowheg,double> interfaceAlphaS + ("AlphaS", + "The value of alphaS to use if using a fixed alphaS", + &MEPP2GammaGammaPowheg::alphaS_, 0.118, 0.0, 0.2, + false, false, Interface::limited); + + static Switch<MEPP2GammaGammaPowheg,bool> interfaceFixedAlphaS + ("FixedAlphaS", + "Use a fixed value of alphaS", + &MEPP2GammaGammaPowheg::fixedAlphaS_, false, false, false); + static SwitchOption interfaceFixedAlphaSYes + (interfaceFixedAlphaS, + "Yes", + "Use a fixed alphaS", + true); + static SwitchOption interfaceFixedAlphaSNo + (interfaceFixedAlphaS, + "No", + "Use a running alphaS", + false); + + static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceSupressionFunction + ("SupressionFunction", + "Choice of the supression function", + &MEPP2GammaGammaPowheg::supressionFunction_, 0, false, false); + static SwitchOption interfaceSupressionFunctionNone + (interfaceSupressionFunction, + "None", + "Default POWHEG approach", + 0); + static SwitchOption interfaceSupressionFunctionThetaFunction + (interfaceSupressionFunction, + "ThetaFunction", + "Use theta functions at scale Lambda", + 1); + static SwitchOption interfaceSupressionFunctionSmooth + (interfaceSupressionFunction, + "Smooth", + "Supress high pT by pt^2/(pt^2+lambda^2)", + 2); + + static Parameter<MEPP2GammaGammaPowheg,Energy> interfaceSupressionScale + ("SupressionScale", + "The square of the scale for the supression function", + &MEPP2GammaGammaPowheg::lambda_, GeV, 20.0*GeV, 0.0*GeV, 0*GeV, + false, false, Interface::lowerlim); + + static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceSupressionScaleChoice + ("SupressionScaleChoice", + "Choice of the supression scale", + &MEPP2GammaGammaPowheg::supressionScale_, 0, false, false); + static SwitchOption interfaceSupressionScaleChoiceFixed + (interfaceSupressionScaleChoice, + "Fixed", + "Use a fixed scale", + 0); + static SwitchOption interfaceSupressionScaleChoiceVariable + (interfaceSupressionScaleChoice, + "Variable", + "Use the pT of the hard process as the scale", + 1); + + static Reference<MEPP2GammaGammaPowheg,ShowerAlpha> interfaceShowerAlphaQCD + ("ShowerAlphaQCD", + "Reference to the object calculating the QCD coupling for the shower", + &MEPP2GammaGammaPowheg::alphaQCD_, false, false, true, false, false); + + static Reference<MEPP2GammaGammaPowheg,ShowerAlpha> interfaceShowerAlphaQED + ("ShowerAlphaQED", + "Reference to the object calculating the QED coupling for the shower", + &MEPP2GammaGammaPowheg::alphaQED_, false, false, true, false, false); + + static Parameter<MEPP2GammaGammaPowheg,double> interfacepreQCDqqbarq + ("preQCDqqbarq", + "The constant for the Sudakov overestimate for the " + "q qbar -> V Gamma +g with emission from the q", + &MEPP2GammaGammaPowheg::preQCDqqbarq_, 23.0, 0.0, 1000.0, + false, false, Interface::limited); + + static Parameter<MEPP2GammaGammaPowheg,double> interfacepreQCDqqbarqbar + ("preQCDqqbarqbar", + "The constant for the Sudakov overestimate for the " + "q qbar -> V Gamma +g with emission from the qbar", + &MEPP2GammaGammaPowheg::preQCDqqbarqbar_, 23.0, 0.0, 1000.0, + false, false, Interface::limited); + + static Switch<MEPP2GammaGammaPowheg,unsigned int> interfaceScaleChoice + ("ScaleChoice", + "The scale choice to use", + &MEPP2GammaGammaPowheg::scaleChoice_, 0, false, false); + static SwitchOption interfaceScaleChoicepT + (interfaceScaleChoice, + "pT", + "Use the pT of the photons", + 0); + static SwitchOption interfaceScaleChoiceMGammaGamma + (interfaceScaleChoice, + "MGammaGamma", + "Use the mass of the photon pair", + 1); + + static Parameter<MEPP2GammaGammaPowheg,double> interfaceScalePreFactor + ("ScalePreFactor", + "Prefactor to change factorization/renormalisation scale", + &MEPP2GammaGammaPowheg::scalePreFactor_, 1.0, 0.1, 10.0, + false, false, Interface::limited); + + +// prefactor_.push_back(preQCDqg_); +// prefactor_.push_back(preQCDgqbar_); +// prefactor_.push_back(preQEDqqbarq_); +// prefactor_.push_back(preQEDqqbarqbar_); +// prefactor_.push_back(preQEDqgq_); +// prefactor_.push_back(preQEDgqbarqbar_); +} + +double MEPP2GammaGammaPowheg::NLOWeight() const { + // if leading-order return + if(contrib_==0) return loME_; + // prefactors + CFfact_ = 4./3.*alphaS_/Constants::twopi; + TRfact_ = 1./2.*alphaS_/Constants::twopi; + // scale + Energy2 mu2 = scale(); + // virtual pieces + double virt = CFfact_*subtractedVirtual(); + // extract the partons and stuff for the real emission + // and collinear counter terms + // hadrons + pair<tcBeamPtr,tcBeamPtr> hadrons= + make_pair(dynamic_ptr_cast<tcBeamPtr>(lastParticles().first->dataPtr() ), + dynamic_ptr_cast<tcBeamPtr>(lastParticles().second->dataPtr())); + // momentum fractions + pair<double,double> x = make_pair(lastX1(),lastX2()); + // partons + pair<tcPDPtr,tcPDPtr> partons = make_pair(mePartonData()[0],mePartonData()[1]); + // If necessary swap the particle data objects so that + // first beam gives the incoming quark + if(lastPartons().first ->dataPtr()!=partons.first) { + swap(x.first,x.second); + swap(hadrons.first,hadrons.second); + } + // convert the values of z tilde to z + pair<double,double> z; + pair<double,double> zJac; + double rhomax(pow(1.-x.first,1.-power_)); + double rho = zTilde_*rhomax; + z.first = 1.-pow(rho,1./(1.-power_)); + zJac.first = rhomax*pow(1.-z.first,power_)/(1.-power_); + rhomax = pow(1.-x.second,1.-power_); + rho = zTilde_*rhomax; + z.second = 1.-pow(rho,1./(1.-power_)); + zJac.second = rhomax*pow(1.-z.second,power_)/(1.-power_); + // calculate the PDFs + pair<double,double> oldqPDF = + make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,partons.first ,scale(), + x.first )/x.first , + hadrons.second->pdf()->xfx(hadrons.second,partons.second,scale(), + x.second)/x.second); + // real/coll q/qbar + pair<double,double> newqPDF = + make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,partons.first ,scale(), + x.first /z.first )*z.first /x.first , + hadrons.second->pdf()->xfx(hadrons.second,partons.second,scale(), + x.second/z.second)*z.second/x.second); + // real/coll gluon + pair<double,double> newgPDF = + make_pair(hadrons.first ->pdf()->xfx(hadrons.first ,gluon_,scale(), + x.first /z.first )*z.first /x.first , + hadrons.second->pdf()->xfx(hadrons.second,gluon_,scale(), + x.second/z.second)*z.second/x.second); + // coll terms + // g -> q + double collGQ = collinearGluon(mu2,zJac.first,z.first, + oldqPDF.first,newgPDF.first); + // g -> qbar + double collGQbar = collinearGluon(mu2,zJac.second,z.second, + oldqPDF.second,newgPDF.second); + // q -> q + double collQQ = collinearQuark(x.first ,mu2,zJac.first ,z.first , + oldqPDF.first ,newqPDF.first ); + // qbar -> qbar + double collQbarQbar = collinearQuark(x.second,mu2,zJac.second,z.second, + oldqPDF.second,newqPDF.second); + // collinear remnants + double coll = collQQ+collQbarQbar+collGQ+collGQbar; + // real emission contribution + double real1 = subtractedReal(x,z. first,zJac. first,oldqPDF. first, + newqPDF. first,newgPDF. first, true); + double real2 = subtractedReal(x,z.second,zJac.second,oldqPDF.second, + newqPDF.second,newgPDF.second,false); + // the total weight + double wgt = loME_ + loME_*virt + loME_*coll + real1 + real2; + return contrib_ == 1 ? max(0.,wgt) : max(0.,-wgt); +} + +double MEPP2GammaGammaPowheg::loGammaGammaME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first) const { + double output(0.); + // analytic formula for speed + if(!first) { + Energy2 th = (momenta[0]-momenta[2]).m2(); + Energy2 uh = (momenta[0]-momenta[3]).m2(); + output = 4./3.*Constants::pi*SM().alphaEM(ZERO)*(th/uh+uh/th)* + pow(double(particles[0]->iCharge())/3.,4); + } + // HE code result + else { + // wavefunctions for the incoming fermions + SpinorWaveFunction em_in( momenta[0],particles[0],incoming); + SpinorBarWaveFunction ep_in( momenta[1],particles[1],incoming); + // wavefunctions for the outgoing bosons + VectorWaveFunction v1_out(momenta[2],particles[2],outgoing); + VectorWaveFunction v2_out(momenta[3],particles[3],outgoing); + vector<SpinorWaveFunction> f1; + vector<SpinorBarWaveFunction> a1; + vector<VectorWaveFunction> v1,v2; + // calculate the wavefunctions + for(unsigned int ix=0;ix<2;++ix) { + em_in.reset(ix); + f1.push_back(em_in); + ep_in.reset(ix); + a1.push_back(ep_in); + v1_out.reset(2*ix); + v1.push_back(v1_out); + v2_out.reset(2*ix); + v2.push_back(v2_out); + } + vector<double> me(4,0.0); + me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half, + PDT::Spin1,PDT::Spin1)); + vector<Complex> diag(2,0.0); + SpinorWaveFunction inter; + for(unsigned int ihel1=0;ihel1<2;++ihel1) { + for(unsigned int ihel2=0;ihel2<2;++ihel2) { + for(unsigned int ohel1=0;ohel1<2;++ohel1) { + for(unsigned int ohel2=0;ohel2<2;++ohel2) { + inter = FFPvertex_->evaluate(ZERO,5,f1[ihel1].particle(), + f1[ihel1],v1[ohel1]); + diag[0] = FFPvertex_->evaluate(ZERO,inter,a1[ihel2],v2[ohel2]); + inter = FFPvertex_->evaluate(ZERO,5,f1[ihel1].particle(), + f1[ihel1] ,v2[ohel2]); + diag[1] = FFPvertex_->evaluate(ZERO,inter,a1[ihel2],v1[ohel1]); + // individual diagrams + for (size_t ii=0; ii<2; ++ii) me[ii] += std::norm(diag[ii]); + // full matrix element + diag[0] += diag[1]; + output += std::norm(diag[0]); + // storage of the matrix element for spin correlations + me_(ihel1,ihel2,2*ohel1,2*ohel2) = diag[0]; + } + } + } + } + // store diagram info, etc. + DVector save(3); + for (size_t i = 0; i < 3; ++i) save[i] = 0.25 * me[i]; + meInfo(save); + // spin and colour factors + output *= 0.125/3./norm(FFPvertex_->norm()); + } + return output; +} + +double MEPP2GammaGammaPowheg::loGammaqME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first) const { + double output(0.); + // analytic formula for speed + if(!first) { + Energy2 sh = (momenta[0]+momenta[1]).m2(); + Energy2 th = (momenta[0]-momenta[2]).m2(); + Energy2 uh = (momenta[0]-momenta[3]).m2(); + output = -1./3./sh/th*(sh*sh+th*th+2.*uh*(sh+th+uh))* + 4.*Constants::pi*SM().alphaEM(ZERO)* + sqr(particles[0]->iCharge()/3.); + } + // HE result + else { + vector<SpinorWaveFunction> fin; + vector<VectorWaveFunction> gin; + vector<SpinorBarWaveFunction> fout; + vector<VectorWaveFunction> vout; + SpinorWaveFunction qin (momenta[0],particles[0],incoming); + VectorWaveFunction glin(momenta[1],particles[1],incoming); + VectorWaveFunction wout(momenta[2],particles[2],outgoing); + SpinorBarWaveFunction qout(momenta[3],particles[3],outgoing); + // polarization states for the particles + for(unsigned int ix=0;ix<2;++ix) { + qin.reset(ix) ; + fin.push_back(qin); + qout.reset(ix); + fout.push_back(qout); + glin.reset(2*ix); + gin.push_back(glin); + wout.reset(2*ix); + vout.push_back(wout); + } + me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1, + PDT::Spin1,PDT::Spin1Half)); + // compute the matrix elements + double me[3]={0.,0.,0.}; + Complex diag[2]; + SpinorWaveFunction inters; + SpinorBarWaveFunction interb; + for(unsigned int ihel1=0;ihel1<2;++ihel1) { + for(unsigned int ihel2=0;ihel2<2;++ihel2) { + for(unsigned int ohel1=0;ohel1<2;++ohel1) { + // intermediates for the diagrams + interb= FFGvertex_->evaluate(scale(),5,particles[3], + fout[ohel1],gin[ihel2]); + inters= FFGvertex_->evaluate(scale(),5,particles[0], + fin[ihel1],gin[ihel2]); + for(unsigned int vhel=0;vhel<2;++vhel) { + diag[0] = FFPvertex_->evaluate(ZERO,fin[ihel1],interb,vout[vhel]); + diag[1] = FFPvertex_->evaluate(ZERO,inters,fout[ohel1],vout[vhel]); + // diagram contributions + me[1] += norm(diag[0]); + me[2] += norm(diag[1]); + // total + diag[0] += diag[1]; + me[0] += norm(diag[0]); + me_(ihel1,2*ihel2,2*vhel,ohel1) = diag[0]; + } + } + } + } + // results + // initial state spin and colour average + double colspin = 1./24./4.; + // and C_F N_c from matrix element + colspin *= 4.; + DVector save; + for(unsigned int ix=0;ix<3;++ix) { + me[ix] *= colspin; + if(ix>0) save.push_back(me[ix]); + } + meInfo(save); + output = me[0]/norm(FFGvertex_->norm()); + } + return output; +} + +double MEPP2GammaGammaPowheg::loGammaqbarME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first) const { + double output(0.); + // analytic formula for speed + if(!first) { + Energy2 sh = (momenta[0]+momenta[1]).m2(); + Energy2 uh = (momenta[0]-momenta[2]).m2(); + Energy2 th = (momenta[0]-momenta[3]).m2(); + output = -1./3./sh/th*(sh*sh+th*th+2.*uh*(sh+th+uh))* + 4.*Constants::pi*SM().alphaEM()* + sqr(particles[1]->iCharge()/3.); + } + // HE result + else { + vector<SpinorBarWaveFunction> ain; + vector<VectorWaveFunction> gin; + vector<SpinorWaveFunction> aout; + vector<VectorWaveFunction> vout; + VectorWaveFunction glin (momenta[0],particles[0],incoming); + SpinorBarWaveFunction qbin (momenta[1],particles[1],incoming); + VectorWaveFunction wout (momenta[2],particles[2],outgoing); + SpinorWaveFunction qbout(momenta[3],particles[3],outgoing); + // polarization states for the particles + for(unsigned int ix=0;ix<2;++ix) { + qbin .reset(ix ); + ain .push_back(qbin ); + qbout.reset(ix ); + aout.push_back(qbout); + glin.reset(2*ix); + gin.push_back(glin); + wout.reset(2*ix); + vout.push_back(wout); + } + // if calculation spin corrections construct the me + me_.reset(ProductionMatrixElement(PDT::Spin1,PDT::Spin1Half, + PDT::Spin1,PDT::Spin1Half)); + // compute the matrix elements + double me[3]={0.,0.,0.}; + Complex diag[2]; + SpinorWaveFunction inters; + SpinorBarWaveFunction interb; + for(unsigned int ihel1=0;ihel1<2;++ihel1) { + for(unsigned int ihel2=0;ihel2<2;++ihel2) { + for(unsigned int ohel1=0;ohel1<2;++ohel1) { + // intermediates for the diagrams + inters= FFGvertex_->evaluate(scale(),5,particles[3], + aout[ohel1],gin[ihel1]); + interb= FFGvertex_->evaluate(scale(),5,particles[1], + ain[ihel2],gin[ihel1]); + for(unsigned int vhel=0;vhel<2;++vhel) { + diag[0]= FFPvertex_->evaluate(ZERO,inters,ain[ihel2],vout[vhel]); + diag[1]= FFPvertex_->evaluate(ZERO,aout[ohel1],interb,vout[vhel]); + // diagram contributions + me[1] += norm(diag[0]); + me[2] += norm(diag[1]); + // total + diag[0] += diag[1]; + me[0] += norm(diag[0]); + me_(2*ihel1,ihel2,2*vhel,ohel1) = diag[0]; + } + } + } + } + // results + // initial state spin and colour average + double colspin = 1./24./4.; + // and C_F N_c from matrix element + colspin *= 4.; + DVector save; + for(unsigned int ix=0;ix<3;++ix) { + me[ix] *= colspin; + if(ix>0) save.push_back(me[ix]); + } + meInfo(save); + output = me[0]/norm(FFGvertex_->norm()); + } + return output; +} + +double MEPP2GammaGammaPowheg::loGammagME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first) const { + double output(0.); + // analytic formula for speed + if(!first) { + Energy2 uh = (momenta[0]-momenta[2]).m2(); + Energy2 th = (momenta[0]-momenta[3]).m2(); + output = 8./9.*double((th*th+uh*uh)/uh/th)* + 4.*Constants::pi*SM().alphaEM(ZERO)* + sqr(particles[0]->iCharge()/3.); + } + else { + vector<SpinorWaveFunction> fin; + vector<SpinorBarWaveFunction> ain; + vector<VectorWaveFunction> gout; + vector<VectorWaveFunction> vout; + SpinorWaveFunction qin (momenta[0],particles[0],incoming); + SpinorBarWaveFunction qbin(momenta[1],particles[1],incoming); + VectorWaveFunction wout(momenta[2],particles[2],outgoing); + VectorWaveFunction glout(momenta[3],particles[3],outgoing); + // polarization states for the particles + for(unsigned int ix=0;ix<2;++ix) { + qin.reset(ix) ; + fin.push_back(qin); + qbin.reset(ix) ; + ain.push_back(qbin); + glout.reset(2*ix); + gout.push_back(glout); + wout.reset(2*ix); + vout.push_back(wout); + } + // if calculation spin corrections construct the me + if(first) me_.reset(ProductionMatrixElement(PDT::Spin1Half,PDT::Spin1Half, + PDT::Spin1,PDT::Spin1)); + // compute the matrix elements + double me[3]={0.,0.,0.}; + Complex diag[2]; + SpinorWaveFunction inters; + SpinorBarWaveFunction interb; + for(unsigned int ihel1=0;ihel1<2;++ihel1) { + for(unsigned int ihel2=0;ihel2<2;++ihel2) { + for(unsigned int ohel1=0;ohel1<2;++ohel1) { + // intermediates for the diagrams + inters= FFGvertex_->evaluate(scale(),5,particles[0], + fin[ihel1],gout[ohel1]); + interb= FFGvertex_->evaluate(scale(),5,particles[1], + ain[ihel2],gout[ohel1]); + for(unsigned int vhel=0;vhel<2;++vhel) { + diag[0]= FFPvertex_->evaluate(ZERO,fin[ihel1],interb,vout[vhel]); + diag[1]= FFPvertex_->evaluate(ZERO,inters,ain[ihel2],vout[vhel]); + // diagram contributions + me[1] += norm(diag[0]); + me[2] += norm(diag[1]); + // total + diag[0] += diag[1]; + me[0] += norm(diag[0]); + if(first) me_(ihel1,ihel2,vhel,2*ohel1) = diag[0]; + } + } + } + } + // results + // initial state spin and colour average + double colspin = 1./9./4.; + // and C_F N_c from matrix element + colspin *= 4.; + DVector save; + for(unsigned int ix=0;ix<3;++ix) { + me[ix] *= colspin; + if(ix>0) save.push_back(me[ix]); + } + meInfo(save); + output = me[0]/norm(FFGvertex_->norm()); + } + return output; +} + +InvEnergy2 MEPP2GammaGammaPowheg:: +realGammaGammagME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + DipoleType dipole, RadiationType rad, + bool ) const { + // matrix element + double sum = realME(particles,momenta); + // loop over the QCD and QCD dipoles + InvEnergy2 dipoles[2]; + pair<double,double> supress[2]; + // compute the two dipole terms + unsigned int iemit = 4, ihard = 3; + double x = (momenta[0]*momenta[1]-momenta[iemit]*momenta[1]- + momenta[iemit]*momenta[0])/(momenta[0]*momenta[1]); + Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[iemit]; + vector<Lorentz5Momentum> pa(4),pb(4); + // momenta for q -> q g/gamma emission + pa[0] = x*momenta[0]; + pa[1] = momenta[1]; + Lorentz5Momentum K = pa[0]+pa[1]; + Lorentz5Momentum Ksum = K+Kt; + Energy2 K2 = K.m2(); + Energy2 Ksum2 = Ksum.m2(); + pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; + pa[2].setMass(momenta[2].mass()); + pa[3] = momenta[ihard] + -2.*Ksum*(Ksum*momenta[ihard])/Ksum2+2*K*(Kt*momenta[ihard])/K2; + pa[3].setMass(ZERO); + cPDVector part(particles.begin(),--particles.end()); + part[3] = particles[ihard]; + // first leading-order matrix element + double lo1 = loGammaGammaME(part,pa); + // first dipole + dipoles[0] = 1./(momenta[0]*momenta[iemit])/x*(2./(1.-x)-(1.+x))*lo1; + supress[0] = supressionFunction(momenta[iemit].perp(),pa[3].perp()); + // momenta for qbar -> qbar g/gamma emission + pb[0] = momenta[0]; + pb[1] = x*momenta[1]; + K = pb[0]+pb[1]; + Ksum = K+Kt; + K2 = K.m2(); + Ksum2 = Ksum.m2(); + pb[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; + pb[2].setMass(momenta[2].mass()); + pb[3] = momenta[ihard] + -2.*Ksum*(Ksum*momenta[ihard])/Ksum2+2*K*(Kt*momenta[ihard])/K2; + pb[3].setMass(ZERO); + // second LO matrix element + double lo2 = loGammaGammaME(part,pb); + // second dipole + dipoles[1] = 1./(momenta[1]*momenta[iemit])/x*(2./(1.-x)-(1.+x))*lo2; + supress[1] = supressionFunction(momenta[iemit].perp(),pb[3].perp()); + for(unsigned int ix=0;ix<2;++ix) dipoles[ix] *= 4./3.; + // denominator for the matrix element + InvEnergy2 denom = abs(dipoles[0]) + abs(dipoles[1]); + // contribution + if( denom==ZERO || dipoles[(dipole-1)/2]==ZERO ) return ZERO; + sum *= abs(dipoles[(dipole-1)/2])/denom; + // final coupling factors + InvEnergy2 output; + if(rad==Subtraction) { + output = alphaS_*alphaEM_* + (sum*UnitRemoval::InvE2*supress[(dipole-1)/2].first + - dipoles[(dipole-1)/2]); + } + else { + output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2; + if(rad==Hard) output *=supress[(dipole-1)/2].second; + else if(rad==Shower) output *=supress[(dipole-1)/2].first ; + } + return output; +} + +InvEnergy2 MEPP2GammaGammaPowheg::realGammaGammaqME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + DipoleType dipole, RadiationType rad, + bool ) const { + double sum = realME(particles,momenta); + // initial-state QCD dipole + double x = (momenta[0]*momenta[1]-momenta[4]*momenta[1]- + momenta[4]*momenta[0])/(momenta[0]*momenta[1]); + Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[4]; + vector<Lorentz5Momentum> pa(4); + pa[0] = momenta[0]; + pa[1] = x*momenta[1]; + Lorentz5Momentum K = pa[0]+pa[1]; + Lorentz5Momentum Ksum = K+Kt; + Energy2 K2 = K.m2(); + Energy2 Ksum2 = Ksum.m2(); + pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; + pa[2].setMass(momenta[2].mass()); + pa[3] = momenta[3] + -2.*Ksum*(Ksum*momenta[3])/Ksum2+2*K*(Kt*momenta[3])/K2; + pa[3].setMass(ZERO); + cPDVector part(particles.begin(),--particles.end()); + part[1] = particles[4]->CC(); + double lo1 = loGammaGammaME(part,pa); + InvEnergy2 D1 = 0.5/(momenta[1]*momenta[4])/x*(1.-2.*x*(1.-x))*lo1; + // initial-final QED dipole + vector<Lorentz5Momentum> pb(4); + x = 1.-(momenta[3]*momenta[4])/(momenta[4]*momenta[0]+momenta[0]*momenta[3]); + pb[3] = momenta[4]+momenta[3]-(1.-x)*momenta[0]; + pb[0] = x*momenta[0]; + pb[1] = momenta[1]; + pb[2] = momenta[2]; + double z = momenta[0]*momenta[3]/(momenta[0]*momenta[3]+momenta[0]*momenta[4]); + part[1] = particles[1]; + part[3] = particles[4]; + double lo2 = loGammaqME(part,pb); + Energy pT = sqrt(-(pb[0]-pb[3]).m2()*(1.-x)*(1.-z)*z/x); + InvEnergy2 DF = 1./(momenta[4]*momenta[3])/x*(1./(1.-x+z)-2.+z)*lo2; + InvEnergy2 DI = 1./(momenta[0]*momenta[3])/x*(1./(1.-x+z)-1.-x)*lo2; + DI *= sqr(double(particles[0]->iCharge())/3.); + DF *= sqr(double(particles[0]->iCharge())/3.); + InvEnergy2 denom = abs(D1)+abs(DI)+abs(DF); + pair<double,double> supress; + InvEnergy2 term; + if ( dipole == IFQED1 ) { + term = DI; + supress = supressionFunction(pT,pb[3].perp()); + } + else if( dipole == FIQED1 ) { + term = DF; + supress = supressionFunction(pT,pb[3].perp()); + } + else { + term = D1; + supress = supressionFunction(momenta[4].perp(),pa[3].perp()); + } + if( denom==ZERO || term == ZERO ) return ZERO; + sum *= abs(term)/denom; + // final coupling factors + InvEnergy2 output; + if(rad==Subtraction) { + output = alphaS_*alphaEM_* + (sum*UnitRemoval::InvE2*supress.first - term); + } + else { + output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2; + if(rad==Hard) output *= supress.second; + else if(rad==Shower) output *= supress.first ; + } + // final coupling factors + return output; +} + +InvEnergy2 MEPP2GammaGammaPowheg:: +realGammaGammaqbarME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + DipoleType dipole, RadiationType rad, + bool) const { + double sum = realME(particles,momenta); + // initial-state QCD dipole + double x = (momenta[0]*momenta[1]-momenta[4]*momenta[1]-momenta[4]*momenta[0])/ + (momenta[0]*momenta[1]); + Lorentz5Momentum Kt = momenta[0]+momenta[1]-momenta[4]; + vector<Lorentz5Momentum> pa(4); + pa[0] = x*momenta[0]; + pa[1] = momenta[1]; + Lorentz5Momentum K = pa[0]+pa[1]; + Lorentz5Momentum Ksum = K+Kt; + Energy2 K2 = K.m2(); + Energy2 Ksum2 = Ksum.m2(); + pa[2] = momenta[2]-2.*Ksum*(Ksum*momenta[2])/Ksum2+2*K*(Kt*momenta[2])/K2; + pa[2].setMass(momenta[2].mass()); + pa[3] = momenta[3] + -2.*Ksum*(Ksum*momenta[3])/Ksum2+2*K*(Kt*momenta[3])/K2; + pa[3].setMass(ZERO); + cPDVector part(particles.begin(),--particles.end()); + part[0] = particles[4]->CC(); + double lo1 = loGammaGammaME(part,pa); + InvEnergy2 D1 = 0.5/(momenta[0]*momenta[4])/x*(1.-2.*x*(1.-x))*lo1; + // initial-final QED dipole + vector<Lorentz5Momentum> pb(4); + x = 1.-(momenta[3]*momenta[4])/(momenta[4]*momenta[1]+momenta[1]*momenta[3]); + pb[3] = momenta[4]+momenta[3]-(1.-x)*momenta[1]; + pb[0] = momenta[0]; + pb[1] = x*momenta[1]; + pb[2] = momenta[2]; + double z = momenta[1]*momenta[3]/(momenta[1]*momenta[3]+momenta[1]*momenta[4]); + part[0] = particles[0]; + part[3] = particles[4]; + double lo2 = loGammaqbarME(part,pb); + Energy pT = sqrt(-(pb[1]-pb[3]).m2()*(1.-x)*(1.-z)*z/x); + InvEnergy2 DF = 1./(momenta[4]*momenta[3])/x*(2./(1.-x+z)-2.+z)*lo2; + InvEnergy2 DI = 1./(momenta[0]*momenta[3])/x*(2./(1.-x+z)-1.-x)*lo2; + InvEnergy2 term; + DI *= sqr(double(particles[1]->iCharge())/3.); + DF *= sqr(double(particles[1]->iCharge())/3.); + InvEnergy2 denom = abs(D1)+abs(DI)+abs(DF); + pair<double,double> supress; + if ( dipole == IFQED2 ) { + term = DI; + supress = supressionFunction(pT,pb[3].perp()); + } + else if( dipole == FIQED2 ) { + term = DF; + supress = supressionFunction(pT,pb[3].perp()); + } + else { + term = D1; + supress = supressionFunction(momenta[4].perp(),pa[3].perp()); + } + if( denom==ZERO || dipole==ZERO ) return ZERO; + sum *= abs(term)/denom; + // final coupling factors + InvEnergy2 output; + if(rad==Subtraction) { + output = alphaS_*alphaEM_* + (sum*UnitRemoval::InvE2*supress.first - term); + } + else { + output = alphaS_*alphaEM_*sum*UnitRemoval::InvE2; + if(rad==Hard) output *= supress.second; + else if(rad==Shower) output *= supress.first ; + } + // final coupling factors + return output; +} + +double MEPP2GammaGammaPowheg:: +realME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta) const { + vector<SpinorWaveFunction> qin; + vector<SpinorBarWaveFunction> qbarin; + vector<VectorWaveFunction> wout,pout,gout; + SpinorWaveFunction q_in; + SpinorBarWaveFunction qbar_in; + VectorWaveFunction g_out; + VectorWaveFunction v_out (momenta[2],particles[2],outgoing); + VectorWaveFunction p_out (momenta[3],particles[3],outgoing); + // q qbar -> gamma gamma g + if(particles[4]->id()==ParticleID::g) { + q_in = SpinorWaveFunction (momenta[0],particles[0],incoming); + qbar_in = SpinorBarWaveFunction (momenta[1],particles[1],incoming); + g_out = VectorWaveFunction (momenta[4],particles[4],outgoing); + } + // q g -> gamma gamma q + else if(particles[4]->id()>0) { + q_in = SpinorWaveFunction (momenta[0],particles[0],incoming); + qbar_in = SpinorBarWaveFunction (momenta[4],particles[4],outgoing); + g_out = VectorWaveFunction (momenta[1],particles[1],incoming); + } + else if(particles[4]->id()<0) { + q_in = SpinorWaveFunction (momenta[4],particles[4],outgoing); + qbar_in = SpinorBarWaveFunction (momenta[1],particles[1],incoming); + g_out = VectorWaveFunction (momenta[0],particles[0],incoming); + } + else assert(false); + for(unsigned int ix=0;ix<2;++ix) { + q_in.reset(ix); + qin.push_back(q_in); + qbar_in.reset(ix); + qbarin.push_back(qbar_in); + g_out.reset(2*ix); + gout.push_back(g_out); + p_out.reset(2*ix); + pout.push_back(p_out); + v_out.reset(2*ix); + wout.push_back(v_out); + } + vector<Complex> diag(6 , 0.); + Energy2 mu2 = scale(); + double sum(0.); + for(unsigned int ihel1=0;ihel1<2;++ihel1) { + for(unsigned int ihel2=0;ihel2<2;++ihel2) { + for(unsigned int whel=0;whel<2;++whel) { + for(unsigned int phel=0;phel<2;++phel) { + for(unsigned int ghel=0;ghel<2;++ghel) { + // first diagram + SpinorWaveFunction inters1 = + FFPvertex_->evaluate(ZERO,5,qin[ihel1].particle(),qin[ihel1],pout[phel]); + SpinorBarWaveFunction inters2 = + FFPvertex_->evaluate(ZERO,5,qin[ihel1].particle()->CC(), + qbarin[ihel2],wout[whel]); + diag[0] = FFGvertex_->evaluate(mu2,inters1,inters2,gout[ghel]); + // second diagram + SpinorWaveFunction inters3 = + FFGvertex_->evaluate(mu2,5,qin[ihel1].particle(),qin[ihel1],gout[ghel]); + SpinorBarWaveFunction inters4 = + FFPvertex_->evaluate(ZERO,5,qbarin[ihel2].particle(), + qbarin[ihel2],pout[phel]); + diag[1] = FFPvertex_->evaluate(ZERO,inters3,inters4,wout[whel]); + // fourth diagram + diag[2] = FFPvertex_->evaluate(ZERO,inters3,inters2,pout[phel]); + // fifth diagram + SpinorBarWaveFunction inters5 = + FFGvertex_->evaluate(mu2,5,qbarin[ihel2].particle(), + qbarin[ihel2],gout[ghel]); + diag[3] = + FFPvertex_->evaluate(ZERO,inters1,inters5,wout[whel]); + // sixth diagram + SpinorWaveFunction inters6 = + FFPvertex_->evaluate(ZERO,5,qbarin[ihel2].particle()->CC(), + qin[ihel1],wout[whel]); + diag[4] = FFGvertex_->evaluate(mu2,inters6,inters4,gout[ghel]); + // eighth diagram + diag[5] = FFPvertex_->evaluate(ZERO,inters6,inters5,pout[phel]); + // sum + Complex dsum = std::accumulate(diag.begin(),diag.end(),Complex(0.)); + sum += norm(dsum); + } + } + } + } + } + // divide out the em and strong couplings + sum /= norm(FFGvertex_->norm()*FFPvertex_->norm()); + // final spin and colour factors spin = 1/4 colour = 4/9 + if(particles[4]->id()==ParticleID::g) sum /= 9.; + // final spin and colour factors spin = 1/4 colour = 4/(3*8) + else sum /= 24.; + // finally identical particle factor + return 0.5*sum; +} + +double MEPP2GammaGammaPowheg::subtractedVirtual() const { + double v = 1+tHat()/sHat(); + double born = (1-v)/v+v/(1-v); + double finite_term = born* + (2./3.*sqr(Constants::pi)-3.+sqr(log(v))+sqr(log(1-v))+3.*log(1-v))+ + 2.+2.*log(v)+2.*log(1-v)+3.*(1-v)/v*(log(v)-log(1-v))+ + (2.+v/(1-v))*sqr(log(v))+(2.+(1-v)/v)*sqr(log(1-v)); + + double virt = ((6.-(2./3.)*sqr(Constants::pi))* + born-2.+finite_term); + + return virt/born; +} + +double MEPP2GammaGammaPowheg::subtractedReal(pair<double,double> x, double z, + double zJac, double oldqPDF, double newqPDF, + double newgPDF,bool order) const { + double vt = vTilde_*(1.-z); + double vJac = 1.-z; + Energy pT = sqrt(sHat()*vt*(1.-vt-z)/z); + // rapidities + double rapidity; + if(order) { + rapidity = -log(x.second*sqrt(lastS())/pT*vt); + } + else { + rapidity = log(x.first *sqrt(lastS())/pT*vt); + } + // CMS system + Energy rs=sqrt(lastS()); + Lorentz5Momentum pcmf = Lorentz5Momentum(ZERO,ZERO,0.5*rs*(x.first-x.second), + 0.5*rs*(x.first+x.second)); + pcmf.rescaleMass(); + Boost blab(pcmf.boostVector()); + // emission from the quark radiation + vector<Lorentz5Momentum> pnew(5); + if(order) { + pnew [0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first/z, + 0.5*rs*x.first/z,ZERO); + pnew [1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second, + 0.5*rs*x.second,ZERO) ; + } + else { + pnew[0] = Lorentz5Momentum(ZERO,ZERO,0.5*rs*x.first, + 0.5*rs*x.first,ZERO); + pnew[1] = Lorentz5Momentum(ZERO,ZERO,-0.5*rs*x.second/z, + 0.5*rs*x.second/z,ZERO) ; + } + pnew [2] = meMomenta()[2]; + pnew [3] = meMomenta()[3]; + pnew [4] = Lorentz5Momentum(pT*cos(phi_),pT*sin(phi_), + pT*sinh(rapidity), + pT*cosh(rapidity), ZERO); + Lorentz5Momentum K = pnew [0]+pnew [1]-pnew [4]; + Lorentz5Momentum Kt = pcmf; + Lorentz5Momentum Ksum = K+Kt; + Energy2 K2 = K.m2(); + Energy2 Ksum2 = Ksum.m2(); + for(unsigned int ix=2;ix<4;++ix) { + pnew [ix].boost(blab); + pnew [ix] = pnew [ix] - 2.*Ksum*(Ksum*pnew [ix])/Ksum2 + +2*K*(Kt*pnew [ix])/K2; + } + // phase-space prefactors + double phase = zJac*vJac/z; + // real emission q qbar + vector<double> output(4,0.); + double realQQ(0.),realGQ(0.); + if(!(zTilde_<1e-7 || vt<1e-7 || 1.-z-vt < 1e-7 )) { + cPDVector particles(mePartonData()); + particles.push_back(gluon_); + // calculate the full 2->3 matrix element + realQQ = sHat()*phase*newqPDF/oldqPDF* + realGammaGammagME(particles,pnew,order ? IIQCD1 : IIQCD2,Subtraction,false); + if(order) { + particles[0] = gluon_; + particles[4] = mePartonData()[0]->CC(); + realGQ = sHat()*phase*newgPDF/oldqPDF* + realGammaGammaqbarME(particles,pnew,IIQCD2,Subtraction,false); + } + else { + particles[1] = gluon_; + particles[4] = mePartonData()[1]->CC(); + realGQ = sHat()*phase*newgPDF/oldqPDF* + realGammaGammaqME (particles,pnew,IIQCD1,Subtraction,false); + } + } + // return the answer + return realQQ+realGQ; +} + +double MEPP2GammaGammaPowheg::collinearQuark(double x, Energy2 mu2, double jac, double z, + double oldPDF, double newPDF) const { + if(1.-z < 1.e-8) return 0.; + return CFfact_*( + // this bit is multiplied by LO PDF + sqr(Constants::pi)/3.-5.+2.*sqr(log(1.-x )) + +(1.5+2.*log(1.-x ))*log(sHat()/mu2) + // NLO PDF bit + +jac /z * newPDF /oldPDF * + (1.-z -(1.+z )*log(sqr(1.-z )/z ) + -(1.+z )*log(sHat()/mu2)-2.*log(z )/(1.-z )) + // + function bit + +jac /z *(newPDF /oldPDF -z )* + 2./(1.-z )*log(sHat()*sqr(1.-z )/mu2)); +} + +double MEPP2GammaGammaPowheg::collinearGluon(Energy2 mu2, double jac, double z, + double oldPDF, double newPDF) const { + if(1.-z < 1.e-8) return 0.; + return TRfact_*jac/z*newPDF/oldPDF* + ((sqr(z)+sqr(1.-z))*log(sqr(1.-z)*sHat()/z/mu2) + +2.*z*(1.-z)); +} + +void MEPP2GammaGammaPowheg::doinit() { + HwMEBase::doinit(); + vector<unsigned int> mopt(2,1); + massOption(mopt); + // get the vertices we need + // get a pointer to the standard model object in the run + static const tcHwSMPtr hwsm + = dynamic_ptr_cast<tcHwSMPtr>(standardModel()); + if (!hwsm) throw InitException() << "hwsm pointer is null in" + << " MEPP2GammaGamma::doinit()" + << Exception::abortnow; + // get pointers to all required Vertex objects + FFPvertex_ = hwsm->vertexFFP(); + FFGvertex_ = hwsm->vertexFFG(); + gluon_ = getParticleData(ParticleID::g); + // sampling factors + prefactor_.push_back(preQCDqqbarq_); + prefactor_.push_back(preQCDqqbarqbar_); + prefactor_.push_back(preQCDqg_); + prefactor_.push_back(preQCDgqbar_); + prefactor_.push_back(preQEDqqbarq_); + prefactor_.push_back(preQEDqqbarqbar_); + prefactor_.push_back(preQEDqgq_); + prefactor_.push_back(preQEDgqbarqbar_); +} + +HardTreePtr MEPP2GammaGammaPowheg:: +generateHardest(ShowerTreePtr tree, + vector<ShowerInteraction::Type> interactions) { + beams_.clear(); + partons_.clear(); + bool QCDAllowed(false),QEDAllowed(false); + for(unsigned int ix=0;ix<interactions.size();++ix) { + if(interactions[ix]==ShowerInteraction::QED) + QEDAllowed = true; + else if(interactions[ix]==ShowerInteraction::QCD) + QCDAllowed = true; + else if(interactions[ix]==ShowerInteraction::Both) { + QEDAllowed = true; + QCDAllowed = true; + } + } + // find the incoming particles + ShowerParticleVector incoming; + // get the particles to be showered + map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit; + vector<ShowerProgenitorPtr> particlesToShower; + //progenitor particles are produced in z direction. + for( cit = tree->incomingLines().begin(); + cit != tree->incomingLines().end(); ++cit ) { + incoming.push_back( cit->first->progenitor() ); + beams_.push_back( cit->first->beam() ); + partons_.push_back( cit->first->progenitor()->dataPtr() ); + particlesToShower.push_back( cit->first ); + } + // find the parton which should be first + if( ( particlesToShower[1]->progenitor()->id() > 0 && + particlesToShower[0]->progenitor()->id() < 0 ) || + ( particlesToShower[0]->progenitor()->id() == ParticleID::g && + particlesToShower[1]->progenitor()->id() < 6 && + particlesToShower[1]->progenitor()->id() > 0 ) ) + swap(particlesToShower[0],particlesToShower[1]); + // check that quark is along +ve z direction + quarkplus_ = particlesToShower[0]->progenitor()->momentum().z() > ZERO; + if( partons_[0]->id() < 0 || + (partons_[0]->id()==ParticleID::g && partons_[1]->id()>0)) { + swap(partons_[0],partons_[1]); + swap(beams_ [0],beams_ [1]); + } + // outgoing partons + for( map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator + cjt= tree->outgoingLines().begin(); + cjt != tree->outgoingLines().end();++cjt ) { + particlesToShower.push_back( cjt->first ); + } + if(particlesToShower.size()!=4) return HardTreePtr(); + if(particlesToShower[2]->id()!=ParticleID::gamma) + swap(particlesToShower[2],particlesToShower[3]); + if(particlesToShower[3]->progenitor()->id()==ParticleID::gamma) { + if(QCDAllowed) return hardQCDEmission(particlesToShower); + } + else { + if(QEDAllowed) return hardQEDEmission(particlesToShower); + } + return HardTreePtr(); +} + +HardTreePtr MEPP2GammaGammaPowheg:: +hardQCDEmission(vector<ShowerProgenitorPtr> particlesToShower) { + Energy rootS = sqrt(lastS()); + // limits on the rapidity of the jet + double minyj = -8.0,maxyj = 8.0; + // generate the hard emission + pair<double,double> x = make_pair(particlesToShower[0]->progenitor()->x(), + particlesToShower[1]->progenitor()->x()); + vector<Energy> pT; + Energy pTmax(-GeV); + cPDVector selectedParticles; + vector<Lorentz5Momentum> selectedMomenta; + int iemit(-1); + for(unsigned int ix=0;ix<4;++ix) { + pT.push_back(0.5*generator()->maximumCMEnergy()); + double a = alphaQCD_->overestimateValue()/Constants::twopi* + prefactor_[ix]*(maxyj-minyj); + cPDVector particles; + for(unsigned int iy=0;iy<particlesToShower.size();++iy) + particles.push_back(particlesToShower[iy]->progenitor()->dataPtr()); + if(ix<2) particles.push_back(gluon_); + else if(ix==2) { + particles.push_back(particles[0]->CC()); + particles[0] = gluon_; + } + else { + particles.push_back(particles[1]->CC()); + particles[1] = gluon_; + } + vector<Lorentz5Momentum> momenta(5); + do { + pT[ix] *= pow(UseRandom::rnd(),1./a); + double y = UseRandom::rnd()*(maxyj-minyj)+ minyj; + double vt,z; + if(ix%2==0) { + vt = pT[ix]*exp(-y)/rootS/x.second; + z = (1.-pT[ix]*exp(-y)/rootS/x.second)/(1.+pT[ix]*exp( y)/rootS/x.first ); + if(z>1.||z<x.first) continue; + } + else { + vt = pT[ix]*exp( y)/rootS/x.first ; + z = (1.-pT[ix]*exp( y)/rootS/x.first )/(1.+pT[ix]*exp(-y)/rootS/x.second ); + if(z>1.||z<x.second) continue; + } + if(vt>1.-z || vt<0.) continue; + if(ix%2==0) { + momenta[0] = particlesToShower[0]->progenitor()->momentum()/z; + momenta[1] = particlesToShower[1]->progenitor()->momentum(); + } + else { + momenta[0] = particlesToShower[0]->progenitor()->momentum(); + momenta[1] = particlesToShower[1]->progenitor()->momentum()/z; + } + double phi = Constants::twopi*UseRandom::rnd(); + momenta[2] = particlesToShower[2]->progenitor()->momentum(); + momenta[3] = particlesToShower[3]->progenitor()->momentum(); + if(!quarkplus_) y *= -1.; + momenta[4] = Lorentz5Momentum(pT[ix]*cos(phi),pT[ix]*sin(phi), + pT[ix]*sinh(y),pT[ix]*cosh(y), ZERO); + Lorentz5Momentum K = momenta[0] + momenta[1] - momenta[4]; + Lorentz5Momentum Kt = momenta[2]+momenta[3]; + Lorentz5Momentum Ksum = K+Kt; + Energy2 K2 = K.m2(), Ksum2 = Ksum.m2(); + for(unsigned int iy=2;iy<4;++iy) { + momenta [iy] = momenta [iy] - 2.*Ksum*(Ksum*momenta [iy])/Ksum2 + +2*K*(Kt*momenta [iy])/K2; + } + // matrix element piece + double wgt = alphaQCD_->ratio(sqr(pT[ix]))*z/(1.-vt)/prefactor_[ix]/loME_; + if(ix==0) + wgt *= sqr(pT[ix])*realGammaGammagME(particles,momenta,IIQCD1,Shower,false); + else if(ix==1) + wgt *= sqr(pT[ix])*realGammaGammagME(particles,momenta,IIQCD2,Shower,false); + else if(ix==2) + wgt *= sqr(pT[ix])*realGammaGammaqbarME(particles,momenta,IIQCD1,Shower,false); + else if(ix==3) + wgt *= sqr(pT[ix])*realGammaGammaqME(particles,momenta,IIQCD2,Shower,false); + wgt *= 4.*Constants::pi/alphaS_; + // pdf piece + double pdf[2]; + if(ix%2==0) { + pdf[0] = beams_[0]->pdf()->xfx(beams_[0],partons_ [0], + scale(), x.first ) /x.first; + pdf[1] = beams_[0]->pdf()->xfx(beams_[0],particles[0], + scale()+sqr(pT[ix]),x.first /z)*z/x.first; + } + else { + pdf[0] = beams_[1]->pdf()->xfx(beams_[1],partons_ [1], + scale() ,x.second ) /x.second; + pdf[1] = beams_[1]->pdf()->xfx(beams_[1],particles[1], + scale()+sqr(pT[ix]),x.second/z)*z/x.second; + } + if(pdf[0]<=0.||pdf[1]<=0.) continue; + wgt *= pdf[1]/pdf[0]; + if(wgt>1.) generator()->log() << "Weight greater than one in " + << "MEPP2GammaGammaPowheg::hardQCDEmission() " + << "for channel " << ix + << " Weight = " << wgt << "\n"; + if(UseRandom::rnd()<wgt) break; + } + while(pT[ix]>minpT_); + if(pT[ix]>minpT_ && pT[ix]>pTmax) { + pTmax = pT[ix]; + selectedParticles = particles; + selectedMomenta = momenta; + iemit=ix; + } + } + // if no emission + if(pTmax<ZERO) { + for(unsigned int ix=0;ix<particlesToShower.size();++ix) + particlesToShower[ix]->maximumpT(minpT_,ShowerInteraction::QCD); + return HardTreePtr(); + } + // construct the HardTree object needed to perform the showers + // create the partons + ShowerParticleVector newparticles; + newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[0],false))); + newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[1],false))); + newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[4], true))); + // set the momenta + for(unsigned int ix=0;ix<2;++ix) + newparticles[ix]->set5Momentum(selectedMomenta[ix]); + newparticles[2]->set5Momentum(selectedMomenta[4]); + // create the off-shell particle + Lorentz5Momentum poff = selectedMomenta[iemit%2] - selectedMomenta[4]; + poff.rescaleMass(); + newparticles.push_back(new_ptr(ShowerParticle(partons_[iemit%2],false))); + newparticles.back()->set5Momentum(poff); + for(unsigned int ix=2;ix<particlesToShower.size();++ix) { + newparticles.push_back(new_ptr(ShowerParticle(particlesToShower[ix]-> + progenitor()->dataPtr(),true))); + newparticles.back()->set5Momentum(selectedMomenta[ix]); + } + vector<HardBranchingPtr> inBranch,hardBranch; + // create the branchings for the incoming particles + inBranch.push_back(new_ptr(HardBranching(newparticles[0],SudakovPtr(), + HardBranchingPtr(),HardBranching::Incoming))); + inBranch.push_back(new_ptr(HardBranching(newparticles[1],SudakovPtr(), + HardBranchingPtr(),HardBranching::Incoming))); + // intermediate IS particle + hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(), + inBranch[iemit%2],HardBranching::Incoming))); + inBranch[iemit%2]->addChild(hardBranch.back()); + if(newparticles[3]->id()>0) + inBranch[iemit%2]->type(ShowerPartnerType::QCDColourLine ); + else + inBranch[iemit%2]->type(ShowerPartnerType::QCDAntiColourLine); + // create the branching for the emitted jet + inBranch[iemit%2]->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(), + inBranch[iemit%2], + HardBranching::Outgoing))); + // set the colour partners + hardBranch.back()->colourPartner(inBranch[iemit%2==0 ? 1 : 0]); + inBranch[iemit%2==0 ? 1 : 0]->colourPartner(hardBranch.back()); + // add other particle + hardBranch.push_back(inBranch[iemit%2==0 ? 1 : 0]); + // outgoing particles + for(unsigned int ix=4;ix<newparticles.size();++ix) { + hardBranch.push_back(new_ptr(HardBranching(newparticles[ix],SudakovPtr(), + HardBranchingPtr(), + HardBranching::Outgoing))); + } + // make the tree + HardTreePtr hardtree=new_ptr(HardTree(hardBranch,inBranch,ShowerInteraction::QCD)); + // connect the ShowerParticles with the branchings + // and set the maximum pt for the radiation + set<HardBranchingPtr> hard=hardtree->branchings(); + for(unsigned int ix=0;ix<particlesToShower.size();++ix) { + particlesToShower[ix]->maximumpT(pTmax,ShowerInteraction::QCD); + for(set<HardBranchingPtr>::const_iterator mit=hard.begin(); + mit!=hard.end();++mit) { + if(particlesToShower[ix]->progenitor()->id()==(*mit)->branchingParticle()->id()&& + (( particlesToShower[ix]->progenitor()->isFinalState()&& + (**mit).status()==HardBranching::Outgoing)|| + (!particlesToShower[ix]->progenitor()->isFinalState()&& + (**mit).status()==HardBranching::Incoming))) { + hardtree->connect(particlesToShower[ix]->progenitor(),*mit); + if((**mit).status()==HardBranching::Incoming) { + (*mit)->beam(particlesToShower[ix]->original()->parents()[0]); + } + HardBranchingPtr parent=(*mit)->parent(); + while(parent) { + parent->beam(particlesToShower[ix]->original()->parents()[0]); + parent=parent->parent(); + }; + } + } + } + ColinePtr newline=new_ptr(ColourLine()); + for(set<HardBranchingPtr>::const_iterator cit=hardtree->branchings().begin(); + cit!=hardtree->branchings().end();++cit) { + if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3) + newline->addColoured((**cit).branchingParticle()); + else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar) + newline->addAntiColoured((**cit).branchingParticle()); + } + // return the tree + return hardtree; +} + +HardTreePtr MEPP2GammaGammaPowheg:: +hardQEDEmission(vector<ShowerProgenitorPtr> particlesToShower) { + // return if not emission from quark + if(particlesToShower[0]->progenitor()->id()!=ParticleID::g && + particlesToShower[1]->progenitor()->id()!=ParticleID::g ) + return HardTreePtr(); + // generate the hard emission + pair<double,double> x = make_pair(particlesToShower[0]->progenitor()->x(), + particlesToShower[1]->progenitor()->x()); + vector<Energy> pT; + Energy pTmax(-GeV); + cPDVector selectedParticles; + vector<Lorentz5Momentum> selectedMomenta; + int iemit(-1); + pair<double,double> mewgt(make_pair(0.,0.)); + for(unsigned int ix=0;ix<particlesToShower.size();++ix) { + selectedParticles.push_back(particlesToShower[ix]->progenitor()->dataPtr()); + selectedMomenta.push_back(particlesToShower[ix]->progenitor()->momentum()); + } + selectedParticles.push_back(getParticleData(ParticleID::gamma)); + swap(selectedParticles[3],selectedParticles[4]); + selectedMomenta.push_back(Lorentz5Momentum()); + swap(selectedMomenta[3],selectedMomenta[4]); + Lorentz5Momentum pin,pout; + double xB; + unsigned int iloc; + if(particlesToShower[0]->progenitor()->dataPtr()->charged()) { + pin = particlesToShower[0]->progenitor()->momentum(); + xB = x.first; + iloc = 6; + } + else { + pin = particlesToShower[1]->progenitor()->momentum(); + xB = x.second; + iloc = 7; + } + pout = particlesToShower[3]->progenitor()->momentum(); + Lorentz5Momentum q = pout-pin; + Axis axis(q.vect().unit()); + LorentzRotation rot; + double sinth(sqrt(sqr(axis.x())+sqr(axis.y()))); + rot = LorentzRotation(); + if(axis.perp2()>1e-20) { + rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.)); + rot.rotateX(Constants::pi); + } + if(abs(1.-q.e()/q.vect().mag())>1e-6) + rot.boostZ(q.e()/q.vect().mag()); + Lorentz5Momentum ptemp = rot*pin; + if(ptemp.perp2()/GeV2>1e-20) { + Boost trans = -1./ptemp.e()*ptemp.vect(); + trans.setZ(0.); + rot.boost(trans); + } + rot.invert(); + Energy Q = sqrt(-q.m2()); + double xT = sqrt((1.-xB)/xB); + double xTMin = 2.*minpT_/Q; + double wgt(0.); + double a = alphaQED_->overestimateValue()*prefactor_[iloc]/Constants::twopi; + Lorentz5Momentum p1,p2,p3; + do { + wgt = 0.; + // intergration variables dxT/xT^3 + xT *= 1./sqrt(1.-2.*log(UseRandom::rnd())/a*sqr(xT)); + // dz + double zp = UseRandom::rnd(); + double xp = 1./(1.+0.25*sqr(xT)/zp/(1.-zp)); + if(xT<xTMin) break; + // check allowed + if(xp<xB||xp>1.) continue; + // phase-space piece of the weight + wgt = 4.*sqr(1.-xp)*(1.-zp)*zp/prefactor_[iloc]/loME_; + // coupling + Energy2 pT2 = 0.25*sqr(Q*xT); + wgt *= alphaQED_->ratio(pT2); + // matrix element + wgt *= 4.*Constants::pi/alphaEM_; + // PDF + double pdf[2]; + if(iloc==6) { + pdf[0] = beams_[0]->pdf()-> + xfx(beams_[0],partons_[0],scale() ,x.first ); + pdf[1] = beams_[0]->pdf()-> + xfx(beams_[0],partons_[0],scale()+pT2,x.first /xp); + } + else { + pdf[0] = beams_[1]->pdf()-> + xfx(beams_[1],partons_[1],scale() ,x.second ); + pdf[1] = beams_[1]->pdf()-> + xfx(beams_[1],partons_[1],scale()+pT2,x.second/xp); + } + if(pdf[0]<=0.||pdf[1]<=0.) { + wgt = 0.; + continue; + } + wgt *= pdf[1]/pdf[0]; + // matrix element piece + double phi = Constants::twopi*UseRandom::rnd(); + double x2 = 1.-(1.-zp)/xp; + double x3 = 2.-1./xp-x2; + p1=Lorentz5Momentum(ZERO,ZERO,0.5*Q/xp,0.5*Q/xp,ZERO); + p2=Lorentz5Momentum( 0.5*Q*xT*cos(phi), 0.5*Q*xT*sin(phi), + -0.5*Q*x2,0.5*Q*sqrt(sqr(xT)+sqr(x2))); + p3=Lorentz5Momentum(-0.5*Q*xT*cos(phi),-0.5*Q*xT*sin(phi), + -0.5*Q*x3,0.5*Q*sqrt(sqr(xT)+sqr(x3))); + selectedMomenta[iloc-6] = rot*p1; + selectedMomenta[3] = rot*p3; + selectedMomenta[4] = rot*p2; + if(iloc==6) { + mewgt.first = + sqr(Q)*realGammaGammaqME(selectedParticles,selectedMomenta,IFQED1,Shower,false); + mewgt.second = + sqr(Q)*realGammaGammaqME(selectedParticles,selectedMomenta,FIQED1,Shower,false); + wgt *= mewgt.first+mewgt.second; + } + else { + mewgt.first = + sqr(Q)*realGammaGammaqbarME(selectedParticles,selectedMomenta,IFQED2,Shower,false); + mewgt.second = + sqr(Q)*realGammaGammaqbarME(selectedParticles,selectedMomenta,FIQED2,Shower,false); + wgt *= mewgt.first+mewgt.second; + } + if(wgt>1.) generator()->log() << "Weight greater than one in " + << "MEPP2GammaGammaPowheg::hardQEDEmission() " + << "for IF channel " + << " Weight = " << wgt << "\n"; + } + while(xT>xTMin&&UseRandom::rnd()>wgt); + // if no emission + if(xT<xTMin) { + for(unsigned int ix=0;ix<particlesToShower.size();++ix) + particlesToShower[ix]->maximumpT(minpT_,ShowerInteraction::QED); + return HardTreePtr(); + } + pTmax = 0.5*xT*Q; + iemit = mewgt.first>mewgt.second ? 2 : 3; + // construct the HardTree object needed to perform the showers + // create the partons + ShowerParticleVector newparticles; + newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[0],false))); + newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[1],false))); + newparticles.push_back(new_ptr(ShowerParticle(selectedParticles[3], true))); + // set the momenta + for(unsigned int ix=0;ix<2;++ix) + newparticles[ix]->set5Momentum(selectedMomenta[ix]); + newparticles[2]->set5Momentum(selectedMomenta[3]); + // create the off-shell particle + if(iemit==2) { + if(particlesToShower[0]->progenitor()->dataPtr()->charged()) { + Lorentz5Momentum poff = selectedMomenta[0] - selectedMomenta[3]; + poff.rescaleMass(); + newparticles.push_back(new_ptr(ShowerParticle(partons_[0],false))); + newparticles.back()->set5Momentum(poff); + } + else { + Lorentz5Momentum poff = selectedMomenta[1] - selectedMomenta[3]; + poff.rescaleMass(); + newparticles.push_back(new_ptr(ShowerParticle(partons_[1],false))); + newparticles.back()->set5Momentum(poff); + } + } + else if(iemit==3) { + Lorentz5Momentum poff = selectedMomenta[3]+selectedMomenta[4]; + poff.rescaleMass(); + newparticles.push_back(new_ptr(ShowerParticle(particlesToShower[3] + ->progenitor()->dataPtr(),true))); + newparticles.back()->set5Momentum(poff); + } + else + assert(false); + for(unsigned int ix=2;ix<particlesToShower.size();++ix) { + newparticles.push_back(new_ptr(ShowerParticle(particlesToShower[ix]-> + progenitor()->dataPtr(),true))); + newparticles.back()->set5Momentum(selectedMomenta[ix==2 ? 2 : 4 ]); + } + vector<HardBranchingPtr> inBranch,hardBranch; + // create the branchings for the incoming particles + inBranch.push_back(new_ptr(HardBranching(newparticles[0],SudakovPtr(), + HardBranchingPtr(),HardBranching::Incoming))); + inBranch.push_back(new_ptr(HardBranching(newparticles[1],SudakovPtr(), + HardBranchingPtr(),HardBranching::Incoming))); + if(iemit<3) { + int icharged = iemit; + if(icharged==2) icharged = particlesToShower[0]->progenitor()-> + dataPtr()->charged() ? 0 : 1; + // intermediate IS particle + hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(), + inBranch[icharged],HardBranching::Incoming))); + inBranch[icharged]->addChild(hardBranch.back()); + inBranch[icharged]->type(ShowerPartnerType::QED); + // create the branching for the emitted jet + inBranch[icharged]->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(), + inBranch[icharged], + HardBranching::Outgoing))); + // set the colour partners + if(iemit<2) { + hardBranch.back()->colourPartner(inBranch[icharged==0 ? 1 : 0]); + inBranch[icharged==0 ? 1 : 0]->colourPartner(hardBranch.back()); + } + // add other particle + hardBranch.push_back(inBranch[icharged == 0 ? 1 : 0]); + // outgoing particles + for(unsigned int ix=4;ix<newparticles.size();++ix) { + hardBranch.push_back(new_ptr(HardBranching(newparticles[ix],SudakovPtr(), + HardBranchingPtr(), + HardBranching::Outgoing))); + } + if(iemit==2) { + hardBranch.back()->colourPartner(hardBranch[0]); + hardBranch[0]->colourPartner(hardBranch.back()); + } + } + else { + for(unsigned int ix=0;ix<2;++ix) + hardBranch.push_back(inBranch[ix]); + hardBranch.push_back(new_ptr(HardBranching(newparticles[4],SudakovPtr(), + HardBranchingPtr(), + HardBranching::Outgoing))); + hardBranch.push_back(new_ptr(HardBranching(newparticles[3],SudakovPtr(), + HardBranchingPtr(), + HardBranching::Outgoing))); + hardBranch.back()->type(ShowerPartnerType::QED); + hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[5],SudakovPtr(), + HardBranchingPtr(), + HardBranching::Outgoing))); + hardBranch.back()->addChild(new_ptr(HardBranching(newparticles[2],SudakovPtr(), + HardBranchingPtr(), + HardBranching::Outgoing))); + if(hardBranch[0]->branchingParticle()->dataPtr()->charged()) { + hardBranch.back()->colourPartner(hardBranch[0]); + hardBranch[0]->colourPartner(hardBranch.back()); + } + else { + hardBranch.back()->colourPartner(hardBranch[1]); + hardBranch[1]->colourPartner(hardBranch.back()); + } + } + // make the tree + HardTreePtr hardtree=new_ptr(HardTree(hardBranch,inBranch,ShowerInteraction::QED)); + // connect the ShowerParticles with the branchings + // and set the maximum pt for the radiation + set<HardBranchingPtr> hard=hardtree->branchings(); + for(unsigned int ix=0;ix<particlesToShower.size();++ix) { + particlesToShower[ix]->maximumpT(pTmax,ShowerInteraction::QED); + for(set<HardBranchingPtr>::const_iterator mit=hard.begin(); + mit!=hard.end();++mit) { + if(particlesToShower[ix]->progenitor()->id()==(*mit)->branchingParticle()->id()&& + (( particlesToShower[ix]->progenitor()->isFinalState()&& + (**mit).status()==HardBranching::Outgoing)|| + (!particlesToShower[ix]->progenitor()->isFinalState()&& + (**mit).status()==HardBranching::Incoming))) { + hardtree->connect(particlesToShower[ix]->progenitor(),*mit); + if((**mit).status()==HardBranching::Incoming) { + (*mit)->beam(particlesToShower[ix]->original()->parents()[0]); + } + HardBranchingPtr parent=(*mit)->parent(); + while(parent) { + parent->beam(particlesToShower[ix]->original()->parents()[0]); + parent=parent->parent(); + }; + } + } + } + ColinePtr newline1 = new_ptr(ColourLine()); + ColinePtr newline2 = new_ptr(ColourLine()); + HardBranchingPtr gluon,quark,antiQuark; + for(set<HardBranchingPtr>::const_iterator cit=hardtree->branchings().begin(); + cit!=hardtree->branchings().end();++cit) { + if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour8) { + gluon = *cit; + if((**cit).status()==HardBranching::Incoming) { + newline1->addColoured ((**cit).branchingParticle()); + newline2->addAntiColoured((**cit).branchingParticle()); + } + else { + newline2->addColoured ((**cit).branchingParticle()); + newline1->addAntiColoured((**cit).branchingParticle()); + } + } + else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3) { + if((**cit).status()==HardBranching::Incoming) { + antiQuark = *cit; + newline2->addColoured((**cit).branchingParticle()); + } + else { + quark = *cit; + newline1->addColoured((**cit).branchingParticle()); + } + } + else if((**cit).branchingParticle()->dataPtr()->iColour()==PDT::Colour3bar) { + if((**cit).status()==HardBranching::Incoming) { + quark = *cit; + newline1->addAntiColoured((**cit).branchingParticle()); + } + else { + antiQuark = *cit; + newline2->addAntiColoured((**cit).branchingParticle()); + } + } + } + assert(quark&&antiQuark&&gluon); + gluon->colourPartner(UseRandom::rndbool() ? quark : antiQuark); + // return the tree + return hardtree; +} diff --git a/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h new file mode 100644 --- /dev/null +++ b/MatrixElement/Powheg/MEPP2GammaGammaPowheg.h @@ -0,0 +1,538 @@ +// -*- C++ -*- +#ifndef HERWIG_MEPP2GammaGammaPowheg_H +#define HERWIG_MEPP2GammaGammaPowheg_H +// +// This is the declaration of the MEPP2GammaGammaPowheg class. +// + +#include "Herwig/MatrixElement/HwMEBase.h" +#include "ThePEG/Helicity/Vertex/Vector/FFVVertex.h" +#include "Herwig/MatrixElement/ProductionMatrixElement.h" +#include "Herwig/Shower/Couplings/ShowerAlpha.h" + +namespace Herwig { + +using namespace ThePEG; + +/** + * Here is the documentation of the MEPP2GammaGammaPowheg class. + * + * @see \ref MEPP2GammaGammaPowhegInterfaces "The interfaces" + * defined for MEPP2GammaGammaPowheg. + */ +class MEPP2GammaGammaPowheg: public HwMEBase { + + enum DipoleType { IIQCD1=2, IIQCD2=4, + IFQED1=5, FIQED1=6, IFQED2=7, FIQED2=8 }; + + enum RadiationType {Subtraction,Hard,Shower}; + +public: + + /** @name Standard constructors and destructors. */ + //@{ + /** + * The default constructor. + */ + MEPP2GammaGammaPowheg(); + //@} + + /** @name Member functions for the generation of hard QCD radiation */ + //@{ + /** + * Has a POWHEG style correction + */ + virtual POWHEGType hasPOWHEGCorrection() {return ISR;} + + /** + * Apply the POWHEG style correction + */ + virtual HardTreePtr generateHardest(ShowerTreePtr, + vector<ShowerInteraction::Type>); + //@} + +public: + + /** @name Virtual functions required by the MEBase class. */ + //@{ + /** + * Return the order in \f$\alpha_S\f$ in which this matrix + * element is given. + */ + virtual unsigned int orderInAlphaS() const; + + /** + * Return the order in \f$\alpha_{EW}\f$ in which this matrix + * element is given. + */ + virtual unsigned int orderInAlphaEW() const; + + /** + * The matrix element for the kinematical configuration + * previously provided by the last call to setKinematics(), suitably + * scaled by sHat() to give a dimension-less number. + * @return the matrix element scaled with sHat() to give a + * dimensionless number. + */ + virtual double me2() const; + + /** + * Return the scale associated with the last set phase space point. + */ + virtual Energy2 scale() const; + + /** + * The number of internal degrees of freedom used in the matrix + * element. + */ + virtual int nDim() const; + + /** + * Generate internal degrees of freedom given nDim() uniform + * random numbers in the interval \f$ ]0,1[ \f$. To help the phase space + * generator, the dSigHatDR should be a smooth function of these + * numbers, although this is not strictly necessary. + * @param r a pointer to the first of nDim() consecutive random numbers. + * @return true if the generation succeeded, otherwise false. + */ + virtual bool generateKinematics(const double * r); + + /** + * Return the matrix element squared differential in the variables + * given by the last call to generateKinematics(). + */ + virtual CrossSection dSigHatDR() const; + + /** + * Add all possible diagrams with the add() function. + */ + virtual void getDiagrams() const; + + /** + * Get diagram selector. With the information previously supplied with the + * setKinematics method, a derived class may optionally + * override this method to weight the given diagrams with their + * (although certainly not physical) relative probabilities. + * @param dv the diagrams to be weighted. + * @return a Selector relating the given diagrams to their weights. + */ + virtual Selector<DiagramIndex> diagrams(const DiagramVector & dv) const; + + /** + * Return a Selector with possible colour geometries for the selected + * diagram weighted by their relative probabilities. + * @param diag the diagram chosen. + * @return the possible colour geometries weighted by their + * relative probabilities. + */ + virtual Selector<const ColourLines *> + colourGeometries(tcDiagPtr diag) const; + //@} + +public: + + /** @name Functions used by the persistent I/O system. */ + //@{ + /** + * Function used to write out object persistently. + * @param os the persistent output stream written to. + */ + void persistentOutput(PersistentOStream & os) const; + + /** + * Function used to read in object persistently. + * @param is the persistent input stream read from. + * @param version the version number of the object when written. + */ + void persistentInput(PersistentIStream & is, int version); + //@} + + /** + * The standard Init function used to initialize the interfaces. + * Called exactly once for each class by the class description system + * before the main function starts or + * when this class is dynamically loaded. + */ + static void Init(); + +protected: + + /** + * Calculate of the full next-to-leading order weight + */ + virtual double NLOWeight() const; + + /** + * Leading-order matrix element for \f$q\bar q\to \gamma\gamma\f$ + */ + double loGammaGammaME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first=false) const; + + /** + * Leading-order matrix element for \f$qg\to \gamma q\f$ + */ + double loGammaqME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first=false) const; + + /** + * Leading-order matrix element for \f$g\bar q\to \gamma \bar q\f$ + */ + double loGammaqbarME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first=false) const; + + /** + * Leading-order matrix element for \f$q\bar q\to \gamma g\f$ + */ + double loGammagME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + bool first=false) const; + + /** + * Real emission matrix element for \f$q\bar q\to \gamma \gamma g\f$ + */ + InvEnergy2 realGammaGammagME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + DipoleType dipole, RadiationType rad, + bool first=false) const; + + /** + * Real emission matrix element for \f$qg\to \gamma \gamma q\f$ + */ + InvEnergy2 realGammaGammaqME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + DipoleType dipole, RadiationType rad, + bool first=false) const; + + /** + * Real emission matrix element for \f$g\bar q\to \gamma \gamma \bar q\f$ + */ + InvEnergy2 realGammaGammaqbarME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta, + DipoleType dipole, RadiationType rad, + bool first=false) const; + + /** + * The dipole subtractedvirtual contribution + */ + double subtractedVirtual() const; + + /** + * Subtracted real contribution + */ + double subtractedReal(pair<double,double> x, double z, + double zJac, double oldqPDF, double newqPDF, + double newgPDF,bool order) const; + + /** + * Calculate of the collinear counterterms + */ + //@{ + /** + * Quark collinear counter term + */ + double collinearQuark(double x, Energy2 mu2, double jac, double z, + double oldPDF, double newPDF) const; + + /** + * Gluon collinear counter term + */ + double collinearGluon(Energy2 mu2, double jac, double z, + double oldPDF, double newPDF) const; + //@} + + /** + * The real matrix element divided by \f$2 g_S^2\f$, to be implemented in the + * inheriting classes. + * @param particles The ParticleData objects of the particles + * @param momenta The momenta of the particles + */ + double realME(const cPDVector & particles, + const vector<Lorentz5Momentum> & momenta) const; + + /** + * Generate hard QCD emission + */ + HardTreePtr hardQCDEmission(vector<ShowerProgenitorPtr>); + + /** + * Generate hard QED emission + */ + HardTreePtr hardQEDEmission(vector<ShowerProgenitorPtr>); + + /** + * The supression function + */ + pair<double,double> supressionFunction(Energy pT,Energy scale) const { + if(supressionScale_==0) scale = lambda_; + Energy2 scale2 = sqr(scale), pT2 = sqr(pT); + switch( supressionFunction_ ) { + case 0: + return make_pair(1.,0.); + case 1: + if(pT < scale ) return make_pair(1.,0.); + else return make_pair(0.,1.); + case 2: + return make_pair(scale2/(pT2+scale2),pT2/(pT2+scale2)); + default: + assert(false); + } + } + + +protected: + + /** @name Clone Methods. */ + //@{ + /** + * Make a simple clone of this object. + * @return a pointer to the new object. + */ + virtual IBPtr clone() const; + + /** Make a clone of this object, possibly modifying the cloned object + * to make it sane. + * @return a pointer to the new object. + */ + virtual IBPtr fullclone() const; + //@} +protected: + + /** @name Standard Interfaced functions. */ + //@{ + /** + * Initialize this object after the setup phase before saving an + * EventGenerator to disk. + * @throws InitException if object could not be initialized properly. + */ + virtual void doinit(); + //@} + +private: + + /** + * The assignment operator is private and must never be called. + * In fact, it should not even be implemented. + */ + MEPP2GammaGammaPowheg & operator=(const MEPP2GammaGammaPowheg &); + +private: + + /** + * Vertices + */ + //@{ + /** + * FFPVertex + */ + AbstractFFVVertexPtr FFPvertex_; + + /** + * FFGVertex + */ + AbstractFFVVertexPtr FFGvertex_; + //@} + + /** + * Kinematic variables for the real radiation + */ + //@{ + /** + * First variable + */ + mutable double zTilde_; + + /** + * Second variable + */ + mutable double vTilde_; + + /** + * Azimuthal angle + */ + mutable double phi_; + //@} + + /** + * Whether to generate the positive, negative or leading order contribution + */ + unsigned int contrib_; + + /** + * Power for sampling \f$x_p\f$ + */ + double power_; + + /** + * Pointer to the gluon ParticleData object + */ + tcPDPtr gluon_; + + /** + * Processes + */ + unsigned int process_; + + /** + * Processes + */ + unsigned int threeBodyProcess_; + + /** + * Allowed flavours of the incoming quarks + */ + int maxflavour_; + + /** + * Factor for \f$C_F\f$ dependent pieces + */ + mutable double CFfact_; + + /** + * Factor for \f$T_R\f$ dependent pieces + */ + mutable double TRfact_; + + /** + * Strong coupling + */ + mutable double alphaS_; + + /** + * Use a fixed value of \f$\alpha_S\f$ + */ + bool fixedAlphaS_; + + /** + * Electromagnetic coupling + */ + mutable double alphaEM_; + + /** + * Leading-order matrix element + */ + mutable double loME_; + + /** + * The matrix element + */ + mutable ProductionMatrixElement me_; + + /** + * the selected dipole + */ + mutable DipoleType dipole_; + + /** + * Supression Function + */ + //@{ + /** + * Choice of the supression function + */ + unsigned int supressionFunction_; + + /** + * Choice for the scale in the supression function + */ + unsigned int supressionScale_; + + /** + * Scalar for the supression function + */ + Energy lambda_; + //@} + + + /** + * Hard emission stuff + */ + //@{ + /** + * Whether the quark is in the + or - z direction + */ + bool quarkplus_; + //@} + + /** + * Properties of the incoming particles + */ + //@{ + /** + * Pointers to the BeamParticleData objects + */ + vector<tcBeamPtr> beams_; + + /** + * Pointers to the ParticleDataObjects for the partons + */ + vector<tcPDPtr> partons_; + //@} + + /** + * Constants for the sampling. The distribution is assumed to have the + * form \f$\frac{c}{{\rm GeV}}\times\left(\frac{{\rm GeV}}{p_T}\right)^n\f$ + */ + //@{ + /** + * The prefactor, \f$c\f$ for the \f$q\bar{q}\f$ channel + */ + double preQCDqqbarq_; + /** + * The prefactor, \f$c\f$ for the \f$q\bar{q}\f$ channel + */ + double preQCDqqbarqbar_; + + /** + * The prefactor, \f$c\f$ for the \f$qg\f$ channel + */ + double preQCDqg_; + + /** + * The prefactor, \f$c\f$ for the \f$g\bar{q}\f$ channel + */ + double preQCDgqbar_; + + double preQEDqqbarq_; + double preQEDqqbarqbar_; + double preQEDqgq_; + double preQEDgqbarqbar_; + + /** + * The prefactors as a vector for easy use + */ + vector<double> prefactor_; + //@} + + /** + * The transverse momentum of the jet + */ + Energy minpT_; + + /** + * Pointer to the object calculating the strong coupling + */ + ShowerAlphaPtr alphaQCD_; + + /** + * Pointer to the object calculating the EM + */ + ShowerAlphaPtr alphaQED_; + + /** + * Scale choice + */ + unsigned int scaleChoice_; + + /** + * Scale factor + */ + double scalePreFactor_; + +}; + +} + +#endif /* HERWIG_MEPP2GammaGammaPowheg_H */ diff --git a/MatrixElement/Powheg/Makefile.am b/MatrixElement/Powheg/Makefile.am --- a/MatrixElement/Powheg/Makefile.am +++ b/MatrixElement/Powheg/Makefile.am @@ -1,16 +1,17 @@ pkglib_LTLIBRARIES = HwPowhegMEHadron.la HwPowhegMELepton.la HwPowhegMEHadron_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 6:0:0 HwPowhegMEHadron_la_SOURCES = \ MEqq2gZ2ffPowheg.cc MEqq2gZ2ffPowheg.h \ MEqq2W2ffPowheg.cc MEqq2W2ffPowheg.h \ MEPP2HiggsPowheg.cc MEPP2HiggsPowheg.h \ MEPP2WHPowheg.cc MEPP2WHPowheg.h \ MEPP2ZHPowheg.cc MEPP2ZHPowheg.h \ MEPP2VVPowheg.cc MEPP2VVPowheg.h \ VVKinematics.cc VVKinematics.h \ +MEPP2GammaGammaPowheg.cc MEPP2GammaGammaPowheg.h \ MEPP2HiggsVBFPowheg.cc MEPP2HiggsVBFPowheg.h HwPowhegMELepton_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 1:0:0 HwPowhegMELepton_la_SOURCES = \ MEee2gZ2qqPowheg.cc MEee2gZ2qqPowheg.h \ MEee2gZ2llPowheg.cc MEee2gZ2llPowheg.h diff --git a/Shower/Base/Evolver.cc b/Shower/Base/Evolver.cc --- a/Shower/Base/Evolver.cc +++ b/Shower/Base/Evolver.cc @@ -1,3630 +1,3630 @@ // -*- C++ -*- // // Evolver.cc is a part of Herwig - A multi-purpose Monte Carlo event generator // Copyright (C) 2002-2011 The Herwig Collaboration // // Herwig is licenced under version 2 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // // // This is the implementation of the non-inlined, non-templated member // functions of the Evolver class. // #include "Evolver.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/Reference.h" #include "ThePEG/Interface/RefVector.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "Herwig/Shower/Base/ShowerParticle.h" #include "ThePEG/Utilities/EnumIO.h" #include "ShowerKinematics.h" #include "ThePEG/PDT/EnumParticles.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Handlers/EventHandler.h" #include "ThePEG/Utilities/Throw.h" #include "ShowerTree.h" #include "ShowerProgenitor.h" #include "KinematicsReconstructor.h" #include "PartnerFinder.h" #include "ThePEG/Handlers/StandardXComb.h" #include "ThePEG/PDT/DecayMode.h" #include "Herwig/Shower/ShowerHandler.h" #include "ThePEG/Utilities/DescribeClass.h" #include "ShowerVertex.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h" #include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h" #include "ThePEG/Handlers/StandardXComb.h" using namespace Herwig; namespace { /** * A struct to order the particles in the same way as in the DecayMode's */ struct ParticleOrdering { /** * Operator for the ordering * @param p1 The first ParticleData object * @param p2 The second ParticleData object */ bool operator() (tcPDPtr p1, tcPDPtr p2) { return abs(p1->id()) > abs(p2->id()) || ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) || ( p1->id() == p2->id() && p1->fullName() > p2->fullName() ); } }; typedef multiset<tcPDPtr,ParticleOrdering> OrderedParticles; /** * Cached lookup of decay modes. * Generator::findDecayMode() is not efficient. */ tDMPtr findDecayMode(const string & tag) { static map<string,DMPtr> cache; map<string,DMPtr>::const_iterator pos = cache.find(tag); if ( pos != cache.end() ) return pos->second; tDMPtr dm = CurrentGenerator::current().findDecayMode(tag); cache[tag] = dm; return dm; } } DescribeClass<Evolver,Interfaced> describeEvolver ("Herwig::Evolver","HwShower.so"); bool Evolver::_hardEmissionModeWarn = true; bool Evolver::_missingTruncWarn = true; IBPtr Evolver::clone() const { return new_ptr(*this); } IBPtr Evolver::fullclone() const { return new_ptr(*this); } void Evolver::persistentOutput(PersistentOStream & os) const { os << _model << _splittingGenerator << _maxtry << _meCorrMode << _hardVetoMode << _hardVetoRead << _hardVetoReadOption << _limitEmissions << _spinOpt << _softOpt << _hardPOWHEG << ounit(_iptrms,GeV) << _beta << ounit(_gamma,GeV) << ounit(_iptmax,GeV) << _vetoes << _trunc_Mode << _hardEmissionMode << _reconOpt << isMCatNLOSEvent << isMCatNLOHEvent << isPowhegSEvent << isPowhegHEvent << theFactorizationScaleFactor << theRenormalizationScaleFactor << ounit(muPt,GeV) << interaction_ << _maxTryFSR << _maxFailFSR << _fracFSR << interactions_.size(); for(unsigned int ix=0;ix<interactions_.size();++ix) os << oenum(interactions_[ix]); } void Evolver::persistentInput(PersistentIStream & is, int) { unsigned int isize; is >> _model >> _splittingGenerator >> _maxtry >> _meCorrMode >> _hardVetoMode >> _hardVetoRead >> _hardVetoReadOption >> _limitEmissions >> _spinOpt >> _softOpt >> _hardPOWHEG >> iunit(_iptrms,GeV) >> _beta >> iunit(_gamma,GeV) >> iunit(_iptmax,GeV) >> _vetoes >> _trunc_Mode >> _hardEmissionMode >> _reconOpt >> isMCatNLOSEvent >> isMCatNLOHEvent >> isPowhegSEvent >> isPowhegHEvent >> theFactorizationScaleFactor >> theRenormalizationScaleFactor >> iunit(muPt,GeV) >> interaction_ >> _maxTryFSR >> _maxFailFSR >> _fracFSR >> isize; interactions_.resize(isize); for(unsigned int ix=0;ix<interactions_.size();++ix) is >> ienum(interactions_[ix]); } void Evolver::doinit() { Interfaced::doinit(); // interactions may have been changed through a setup file so we // clear it up here interactions_.clear(); if(interaction_==0) { interactions_.push_back(ShowerInteraction::QCD); interactions_.push_back(ShowerInteraction::QED); } else if(interaction_==1) { interactions_.push_back(ShowerInteraction::QCD); } else if(interaction_==2) { interactions_.push_back(ShowerInteraction::QED); interactions_.push_back(ShowerInteraction::QCD); } else if(interaction_==3) { interactions_.push_back(ShowerInteraction::QED); } else if(interaction_==4) { interactions_.push_back(ShowerInteraction::Both); } // calculate max no of FSR vetos _maxFailFSR = max(int(_maxFailFSR), int(_fracFSR*double(generator()->N()))); } void Evolver::Init() { static ClassDocumentation<Evolver> documentation ("This class is responsible for carrying out the showering,", "including the kinematics reconstruction, in a given scale range," "including the option of the POWHEG approach to simulated next-to-leading order" " radiation\\cite{Nason:2004rx}.", "%\\cite{Nason:2004rx}\n" "\\bibitem{Nason:2004rx}\n" " P.~Nason,\n" " ``A new method for combining NLO QCD with shower Monte Carlo algorithms,''\n" " JHEP {\\bf 0411} (2004) 040\n" " [arXiv:hep-ph/0409146].\n" " %%CITATION = JHEPA,0411,040;%%\n"); static Reference<Evolver,SplittingGenerator> interfaceSplitGen("SplittingGenerator", "A reference to the SplittingGenerator object", &Herwig::Evolver::_splittingGenerator, false, false, true, false); static Reference<Evolver,ShowerModel> interfaceShowerModel ("ShowerModel", "The pointer to the object which defines the shower evolution model.", &Evolver::_model, false, false, true, false, false); static Parameter<Evolver,unsigned int> interfaceMaxTry ("MaxTry", "The maximum number of attempts to generate the shower from a" " particular ShowerTree", &Evolver::_maxtry, 100, 1, 1000, false, false, Interface::limited); static Switch<Evolver, unsigned int> ifaceMECorrMode ("MECorrMode", "Choice of the ME Correction Mode", &Evolver::_meCorrMode, 1, false, false); static SwitchOption off (ifaceMECorrMode,"No","MECorrections off", 0); static SwitchOption on (ifaceMECorrMode,"Yes","hard+soft on", 1); static SwitchOption hard (ifaceMECorrMode,"Hard","only hard on", 2); static SwitchOption soft (ifaceMECorrMode,"Soft","only soft on", 3); static Switch<Evolver, unsigned int> ifaceHardVetoMode ("HardVetoMode", "Choice of the Hard Veto Mode", &Evolver::_hardVetoMode, 1, false, false); static SwitchOption HVoff (ifaceHardVetoMode,"No","hard vetos off", 0); static SwitchOption HVon (ifaceHardVetoMode,"Yes","hard vetos on", 1); static SwitchOption HVIS (ifaceHardVetoMode,"Initial", "only IS emissions vetoed", 2); static SwitchOption HVFS (ifaceHardVetoMode,"Final","only FS emissions vetoed", 3); static Switch<Evolver, unsigned int> ifaceHardVetoRead ("HardVetoScaleSource", "If hard veto scale is to be read", &Evolver::_hardVetoRead, 0, false, false); static SwitchOption HVRcalc (ifaceHardVetoRead,"Calculate","Calculate from hard process", 0); static SwitchOption HVRread (ifaceHardVetoRead,"Read","Read from XComb->lastScale", 1); static Switch<Evolver, bool> ifaceHardVetoReadOption ("HardVetoReadOption", "Apply read-in scale veto to all collisions or just the primary one?", &Evolver::_hardVetoReadOption, false, false, false); static SwitchOption AllCollisions (ifaceHardVetoReadOption, "AllCollisions", "Read-in pT veto applied to primary and secondary collisions.", false); static SwitchOption PrimaryCollision (ifaceHardVetoReadOption, "PrimaryCollision", "Read-in pT veto applied to primary but not secondary collisions.", true); static Parameter<Evolver, Energy> ifaceiptrms ("IntrinsicPtGaussian", "RMS of intrinsic pT of Gaussian distribution:\n" "2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS)", &Evolver::_iptrms, GeV, ZERO, ZERO, 1000000.0*GeV, false, false, Interface::limited); static Parameter<Evolver, double> ifacebeta ("IntrinsicPtBeta", "Proportion of inverse quadratic distribution in generating intrinsic pT.\n" "(1-Beta) is the proportion of Gaussian distribution", &Evolver::_beta, 0, 0, 1, false, false, Interface::limited); static Parameter<Evolver, Energy> ifacegamma ("IntrinsicPtGamma", "Parameter for inverse quadratic:\n" "2*Beta*Gamma/(sqr(Gamma)+sqr(intrinsicpT))", &Evolver::_gamma,GeV, ZERO, ZERO, 100000.0*GeV, false, false, Interface::limited); static Parameter<Evolver, Energy> ifaceiptmax ("IntrinsicPtIptmax", "Upper bound on intrinsic pT for inverse quadratic", &Evolver::_iptmax,GeV, ZERO, ZERO, 100000.0*GeV, false, false, Interface::limited); static RefVector<Evolver,ShowerVeto> ifaceVetoes ("Vetoes", "The vetoes to be checked during showering", &Evolver::_vetoes, -1, false,false,true,true,false); static Switch<Evolver,unsigned int> interfaceLimitEmissions ("LimitEmissions", "Limit the number and type of emissions for testing", &Evolver::_limitEmissions, 0, false, false); static SwitchOption interfaceLimitEmissionsNoLimit (interfaceLimitEmissions, "NoLimit", "Allow an arbitrary number of emissions", 0); static SwitchOption interfaceLimitEmissionsOneInitialStateEmission (interfaceLimitEmissions, "OneInitialStateEmission", "Allow one emission in the initial state and none in the final state", 1); static SwitchOption interfaceLimitEmissionsOneFinalStateEmission (interfaceLimitEmissions, "OneFinalStateEmission", "Allow one emission in the final state and none in the initial state", 2); static SwitchOption interfaceLimitEmissionsHardOnly (interfaceLimitEmissions, "HardOnly", "Only allow radiation from the hard ME correction", 3); static SwitchOption interfaceLimitEmissionsOneEmission (interfaceLimitEmissions, "OneEmission", "Allow one emission in either the final state or initial state, but not both", 4); static Switch<Evolver,bool> interfaceTruncMode ("TruncatedShower", "Include the truncated shower?", &Evolver::_trunc_Mode, 1, false, false); static SwitchOption interfaceTruncMode0 (interfaceTruncMode,"No","Truncated Shower is OFF", 0); static SwitchOption interfaceTruncMode1 (interfaceTruncMode,"Yes","Truncated Shower is ON", 1); static Switch<Evolver,int> interfaceHardEmissionMode ("HardEmissionMode", "Whether to use ME corrections or POWHEG for the hardest emission", &Evolver::_hardEmissionMode, 0, false, false); static SwitchOption interfaceHardEmissionModeDecayMECorrection (interfaceHardEmissionMode, "DecayMECorrection", "Old fashioned ME correction for decays only", -1); static SwitchOption interfaceHardEmissionModeMECorrection (interfaceHardEmissionMode, "MECorrection", "Old fashioned ME correction", 0); static SwitchOption interfaceHardEmissionModePOWHEG (interfaceHardEmissionMode, "POWHEG", "Powheg style hard emission using internal matrix elements", 1); static SwitchOption interfaceHardEmissionModeMatchboxPOWHEG (interfaceHardEmissionMode, "MatchboxPOWHEG", "Powheg style emission for the hard process using Matchbox", 2); static SwitchOption interfaceHardEmissionModeFullPOWHEG (interfaceHardEmissionMode, "FullPOWHEG", "Powheg style emission for the hard process using Matchbox " "and decays using internal matrix elements", 3); static Switch<Evolver,unsigned int > interfaceInteractions ("Interactions", "The interactions to be used in the shower", &Evolver::interaction_, 1, false, false); static SwitchOption interfaceInteractionsQCDFirst (interfaceInteractions, "QCDFirst", "QCD first then QED", 0); static SwitchOption interfaceInteractionsQCDOnly (interfaceInteractions, "QCDOnly", "Only QCD", 1); static SwitchOption interfaceInteractionsQEDFirst (interfaceInteractions, "QEDFirst", "QED first then QCD", 2); static SwitchOption interfaceInteractionsQEDOnly (interfaceInteractions, "QEDOnly", "Only QED", 3); static SwitchOption interfaceInteractionsBothAtOnce (interfaceInteractions, "BothAtOnce", "Generate both at the same time", 4); static Switch<Evolver,unsigned int> interfaceReconstructionOption ("ReconstructionOption", "Treatment of the reconstruction of the transverse momentum of " "a branching from the evolution scale.", &Evolver::_reconOpt, 0, false, false); static SwitchOption interfaceReconstructionOptionCutOff (interfaceReconstructionOption, "CutOff", "Use the cut-off masses in the calculation", 0); static SwitchOption interfaceReconstructionOptionOffShell (interfaceReconstructionOption, "OffShell", "Use the off-shell masses in the calculation veto the emission of the parent," " no veto in generation of emissions from children", 1); static SwitchOption interfaceReconstructionOptionOffShell2 (interfaceReconstructionOption, "OffShell2", "Use the off-shell masses in the calculation veto the emissions from the children." " no veto in generation of emissions from children", 2); static SwitchOption interfaceReconstructionOptionOffShell3 (interfaceReconstructionOption, "OffShell3", "Use the off-shell masses in the calculation veto the emissions from the children." " veto in generation of emissions from children using cut-off for second parton", 3); static Switch<Evolver,unsigned int> interfaceSpinCorrelations ("SpinCorrelations", "Treatment of spin correlations in the parton shower", &Evolver::_spinOpt, 1, false, false); static SwitchOption interfaceSpinCorrelationsOff (interfaceSpinCorrelations, "No", "No spin correlations", 0); static SwitchOption interfaceSpinCorrelationsSpin (interfaceSpinCorrelations, "Yes", "Include the azimuthal spin correlations only", 1); static Switch<Evolver,unsigned int> interfaceSoftCorrelations ("SoftCorrelations", "Option for the treatment of soft correlations in the parton shower", &Evolver::_softOpt, 2, false, false); static SwitchOption interfaceSoftCorrelationsNone (interfaceSoftCorrelations, "No", "No soft correlations", 0); static SwitchOption interfaceSoftCorrelationsFull (interfaceSoftCorrelations, "Full", "Use the full eikonal", 1); static SwitchOption interfaceSoftCorrelationsSingular (interfaceSoftCorrelations, "Singular", "Use original Webber-Marchisini form", 2); static Switch<Evolver,bool> interfaceHardPOWHEG ("HardPOWHEG", "Treatment of powheg emissions which are too hard to have a shower interpretation", &Evolver::_hardPOWHEG, false, false, false); static SwitchOption interfaceHardPOWHEGAsShower (interfaceHardPOWHEG, "AsShower", "Still interpret as shower emissions", false); static SwitchOption interfaceHardPOWHEGRealEmission (interfaceHardPOWHEG, "RealEmission", "Generate shower from the real emmission configuration", true); static Parameter<Evolver,unsigned int> interfaceMaxTryFSR ("MaxTryFSR", "The maximum number of attempted FSR emissions in" " the generation of the FSR", &Evolver::_maxTryFSR, 100000, 10, 100000000, false, false, Interface::limited); static Parameter<Evolver,unsigned int> interfaceMaxFailFSR ("MaxFailFSR", "Maximum number of failures generating the FSR", &Evolver::_maxFailFSR, 100, 1, 100000000, false, false, Interface::limited); static Parameter<Evolver,double> interfaceFSRFailureFraction ("FSRFailureFraction", "Maximum fraction of events allowed to fail due to too many FSR emissions", &Evolver::_fracFSR, 0.001, 1e-10, 1, false, false, Interface::limited); } void Evolver::generateIntrinsicpT(vector<ShowerProgenitorPtr> particlesToShower) { _intrinsic.clear(); if ( !ipTon() || !isISRadiationON() ) return; // don't do anything for the moment for secondary scatters if( !ShowerHandler::currentHandler()->firstInteraction() ) return; // generate intrinsic pT for(unsigned int ix=0;ix<particlesToShower.size();++ix) { // only consider initial-state particles if(particlesToShower[ix]->progenitor()->isFinalState()) continue; if(!particlesToShower[ix]->progenitor()->dataPtr()->coloured()) continue; Energy ipt; if(UseRandom::rnd() > _beta) { ipt=_iptrms*sqrt(-log(UseRandom::rnd())); } else { ipt=_gamma*sqrt(pow(1.+sqr(_iptmax/_gamma), UseRandom::rnd())-1.); } pair<Energy,double> pt = make_pair(ipt,UseRandom::rnd(Constants::twopi)); _intrinsic[particlesToShower[ix]] = pt; } } void Evolver::setupMaximumScales(const vector<ShowerProgenitorPtr> & p, XCPtr xcomb) { // let POWHEG events radiate freely if(_hardEmissionMode>0&&hardTree()) { vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin(); for (; ckt != p.end(); ckt++) (*ckt)->maxHardPt(Constants::MaxEnergy); return; } // return if no vetos if (!hardVetoOn()) return; // find out if hard partonic subprocess. bool isPartonic(false); map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit = _currenttree->incomingLines().begin(); Lorentz5Momentum pcm; for(; cit!=currentTree()->incomingLines().end(); ++cit) { pcm += cit->first->progenitor()->momentum(); isPartonic |= cit->first->progenitor()->coloured(); } // find minimum pt from hard process, the maximum pt from all outgoing // coloured lines (this is simpler and more general than // 2stu/(s^2+t^2+u^2)). Maximum scale for scattering processes will // be transverse mass. Energy ptmax = generator()->maximumCMEnergy(); // general case calculate the scale if (!hardVetoXComb()|| (hardVetoReadOption()&& !ShowerHandler::currentHandler()->firstInteraction())) { // scattering process if(currentTree()->isHard()) { assert(xcomb); // coloured incoming particles if (isPartonic) { map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator cjt = currentTree()->outgoingLines().begin(); for(; cjt!=currentTree()->outgoingLines().end(); ++cjt) { if (cjt->first->progenitor()->coloured()) ptmax = min(ptmax,cjt->first->progenitor()->momentum().mt()); } } if (ptmax == generator()->maximumCMEnergy() ) ptmax = pcm.m(); if(hardVetoXComb()&&hardVetoReadOption()&& !ShowerHandler::currentHandler()->firstInteraction()) { - ptmax=min(ptmax,sqrt(xcomb->lastCentralScale())); + ptmax=min(ptmax,sqrt(xcomb->lastShowerScale())); } } // decay, incoming() is the decaying particle. else { ptmax = currentTree()->incomingLines().begin()->first ->progenitor()->momentum().mass(); } } // hepeup.SCALUP is written into the lastXComb by the // LesHouchesReader itself - use this by user's choice. // Can be more general than this. else { if(currentTree()->isHard()) { assert(xcomb); - ptmax = sqrt( xcomb->lastCentralScale() ); + ptmax = sqrt( xcomb->lastShowerScale() ); } else { ptmax = currentTree()->incomingLines().begin()->first ->progenitor()->momentum().mass(); } } ptmax *= ShowerHandler::currentHandler()->hardScaleFactor(); // set maxHardPt for all progenitors. For partonic processes this // is now the max pt in the FS, for non-partonic processes or // processes with no coloured FS the invariant mass of the IS vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin(); for (; ckt != p.end(); ckt++) (*ckt)->maxHardPt(ptmax); } void Evolver::setupHardScales(const vector<ShowerProgenitorPtr> & p, XCPtr xcomb) { if ( hardVetoXComb() && (!hardVetoReadOption() || ShowerHandler::currentHandler()->firstInteraction()) ) { Energy hardScale = ZERO; if(currentTree()->isHard()) { assert(xcomb); - hardScale = sqrt( xcomb->lastCentralScale() ); + hardScale = sqrt( xcomb->lastShowerScale() ); } else { hardScale = currentTree()->incomingLines().begin()->first ->progenitor()->momentum().mass(); } hardScale *= ShowerHandler::currentHandler()->hardScaleFactor(); vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin(); for (; ckt != p.end(); ckt++) (*ckt)->hardScale(hardScale); muPt = hardScale; } } void Evolver::showerHardProcess(ShowerTreePtr hard, XCPtr xcomb) { isMCatNLOSEvent = false; isMCatNLOHEvent = false; isPowhegSEvent = false; isPowhegHEvent = false; Ptr<SubtractedME>::tptr subme; Ptr<MatchboxMEBase>::tptr me; Ptr<SubtractionDipole>::tptr dipme; Ptr<StandardXComb>::ptr sxc = dynamic_ptr_cast<Ptr<StandardXComb>::ptr>(xcomb); if ( sxc ) { subme = dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(sxc->matrixElement()); me = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(sxc->matrixElement()); dipme = dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(sxc->matrixElement()); } if ( subme ) { if ( subme->showerApproximation() ) { theShowerApproximation = subme->showerApproximation(); // separate MCatNLO and POWHEG-type corrections if ( !subme->showerApproximation()->needsSplittingGenerator() ) { if ( subme->realShowerSubtraction() ) isMCatNLOHEvent = true; else if ( subme->virtualShowerSubtraction() ) isMCatNLOSEvent = true; } else { if ( subme->realShowerSubtraction() ) isPowhegHEvent = true; else if ( subme->virtualShowerSubtraction() || subme->loopSimSubtraction() ) isPowhegSEvent = true; } } } else if ( me ) { if ( me->factory()->showerApproximation() ) { theShowerApproximation = me->factory()->showerApproximation(); if ( !me->factory()->showerApproximation()->needsSplittingGenerator() ) isMCatNLOSEvent = true; else isPowhegSEvent = true; } } string error = "Inconsistent hard emission set-up in Evolver::showerHardProcess(). "; if ( ( isMCatNLOSEvent || isMCatNLOHEvent ) ){ if (_hardEmissionMode > 1) throw Exception() << error << "Cannot generate POWHEG matching with MC@NLO shower " << "approximation. Add 'set Evolver:HardEmissionMode 0' to input file." << Exception::runerror; if ( ShowerHandler::currentHandler()->canHandleMatchboxTrunc()) throw Exception() << error << "Cannot use truncated qtilde shower with MC@NLO shower " << "approximation. Set LHCGenerator:EventHandler" << ":CascadeHandler to '/Herwig/Shower/ShowerHandler' or " << "'/Herwig/DipoleShower/DipoleShowerHandler'." << Exception::runerror; } else if ( ((isPowhegSEvent || isPowhegHEvent) || dipme) && _hardEmissionMode < 2){ if ( ShowerHandler::currentHandler()->canHandleMatchboxTrunc()) throw Exception() << error << "Unmatched events requested for POWHEG shower " << "approximation. Set Evolver:HardEmissionMode to " << "'MatchboxPOWHEG' or 'FullPOWHEG'." << Exception::runerror; else if (_hardEmissionModeWarn){ _hardEmissionModeWarn = false; _hardEmissionMode+=2; throw Exception() << error << "Unmatched events requested for POWHEG shower " << "approximation. Changing Evolver:HardEmissionMode from " << _hardEmissionMode-2 << " to " << _hardEmissionMode << Exception::warning; } } if ( isPowhegSEvent || isPowhegHEvent) { if (theShowerApproximation->needsTruncatedShower() && !ShowerHandler::currentHandler()->canHandleMatchboxTrunc() ) throw Exception() << error << "Current shower handler cannot generate truncated shower. " << "Set Generator:EventHandler:CascadeHandler to " << "'/Herwig/Shower/PowhegShowerHandler'." << Exception::runerror; } else if ( dipme && _missingTruncWarn){ _missingTruncWarn=false; throw Exception() << "Warning: POWHEG shower approximation used without " << "truncated shower. Set Generator:EventHandler:" << "CascadeHandler to '/Herwig/Shower/PowhegShowerHandler' and " << "'MEMatching:TruncatedShower Yes'." << Exception::warning; } else if ( !dipme && _hardEmissionMode > 1 && ShowerHandler::currentHandler()->firstInteraction()) throw Exception() << error << "POWHEG matching requested for LO events. Include " << "'set Factory:ShowerApproximation MEMatching' in input file." << Exception::runerror; _hardme = HwMEBasePtr(); // extract the matrix element tStdXCombPtr lastXC = dynamic_ptr_cast<tStdXCombPtr>(xcomb); if(lastXC) { _hardme = dynamic_ptr_cast<HwMEBasePtr>(lastXC->matrixElement()); } _decayme = HwDecayerBasePtr(); // set the current tree currentTree(hard); hardTree(HardTreePtr()); // number of attempts if more than one interaction switched on unsigned int interactionTry=0; do { try { // generate the showering doShowering(true,xcomb); // if no vetos return return; } catch (InteractionVeto) { currentTree()->clear(); ++interactionTry; } } while(interactionTry<=5); throw Exception() << "Too many tries for shower in " << "Evolver::showerHardProcess()" << Exception::eventerror; } void Evolver::hardMatrixElementCorrection(bool hard) { // set the initial enhancement factors for the soft correction _initialenhance = 1.; _finalenhance = 1.; // if hard matrix element switched off return if(!MECOn(hard)) return; // see if we can get the correction from the matrix element // or decayer if(hard) { if(_hardme&&_hardme->hasMECorrection()) { _hardme->initializeMECorrection(_currenttree, _initialenhance,_finalenhance); if(hardMEC(hard)) _hardme->applyHardMatrixElementCorrection(_currenttree); } } else { if(_decayme&&_decayme->hasMECorrection()) { _decayme->initializeMECorrection(_currenttree, _initialenhance,_finalenhance); if(hardMEC(hard)) _decayme->applyHardMatrixElementCorrection(_currenttree); } } } ShowerParticleVector Evolver::createTimeLikeChildren(tShowerParticlePtr particle, IdList ids) { // Create the ShowerParticle objects for the two children of // the emitting particle; set the parent/child relationship // if same as definition create particles, otherwise create cc tcPDPtr pdata[2]; for(unsigned int ix=0;ix<2;++ix) pdata[ix]=getParticleData(ids[ix+1]); if(particle->id()!=ids[0]) { for(unsigned int ix=0;ix<2;++ix) { tPDPtr cc(pdata[ix]->CC()); if(cc) pdata[ix]=cc; } } ShowerParticleVector children; for(unsigned int ix=0;ix<2;++ix) { children.push_back(new_ptr(ShowerParticle(pdata[ix],true))); if(children[ix]->id()==_progenitor->id()&&!pdata[ix]->stable()) children[ix]->set5Momentum(Lorentz5Momentum(_progenitor->progenitor()->mass())); else children[ix]->set5Momentum(Lorentz5Momentum(pdata[ix]->mass())); } return children; } bool Evolver::timeLikeShower(tShowerParticlePtr particle, ShowerInteraction::Type type, Branching fb, bool first) { // don't do anything if not needed if(_limitEmissions == 1 || hardOnly() || ( _limitEmissions == 2 && _nfs != 0) || ( _limitEmissions == 4 && _nfs + _nis != 0) ) { if(particle->spinInfo()) particle->spinInfo()->develop(); return false; } // too many tries if(_nFSR>=_maxTryFSR) { ++_nFailedFSR; // too many failed events if(_nFailedFSR>=_maxFailFSR) throw Exception() << "Too many events have failed due to too many shower emissions, in\n" << "Evolver::timeLikeShower(). Terminating run\n" << Exception::runerror; throw Exception() << "Too many attempted emissions in Evolver::timeLikeShower()\n" << Exception::eventerror; } // generate the emission ShowerParticleVector children; int ntry=0; // generate the emission if(!fb.kinematics) fb = selectTimeLikeBranching(particle,type,HardBranchingPtr()); // no emission, return if(!fb.kinematics) { if(particle->spinInfo()) particle->spinInfo()->develop(); return false; } Branching fc[2]; bool setupChildren = true; while (ntry<50) { fc[0] = Branching(); fc[1] = Branching(); ++ntry; assert(fb.kinematics); // has emitted // Assign the shower kinematics to the emitting particle. if(setupChildren) { ++_nFSR; particle->showerKinematics(fb.kinematics); // generate phi fb.kinematics->phi(fb.sudakov->generatePhiForward(*particle,fb.ids,fb.kinematics)); // check highest pT if(fb.kinematics->pT()>progenitor()->highestpT()) progenitor()->highestpT(fb.kinematics->pT()); // create the children children = createTimeLikeChildren(particle,fb.ids); // update the children particle->showerKinematics()-> updateChildren(particle, children,fb.type,_reconOpt>=3); // update number of emissions ++_nfs; if(_limitEmissions!=0) { if(children[0]->spinInfo()) children[0]->spinInfo()->develop(); if(children[1]->spinInfo()) children[1]->spinInfo()->develop(); if(particle->spinInfo()) particle->spinInfo()->develop(); return true; } setupChildren = false; } // select branchings for children fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr()); fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr()); // old default if(_reconOpt==0) { // shower the first particle if(fc[0].kinematics) timeLikeShower(children[0],type,fc[0],false); if(children[0]->spinInfo()) children[0]->spinInfo()->develop(); // shower the second particle if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],false); if(children[1]->spinInfo()) children[1]->spinInfo()->develop(); break; } // Herwig default else if(_reconOpt==1) { // shower the first particle if(fc[0].kinematics) timeLikeShower(children[0],type,fc[0],false); if(children[0]->spinInfo()) children[0]->spinInfo()->develop(); // shower the second particle if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],false); if(children[1]->spinInfo()) children[1]->spinInfo()->develop(); // branching has happened particle->showerKinematics()->updateParent(particle, children,fb.type); // clean up the vetoed emission if(particle->virtualMass()==ZERO) { particle->showerKinematics(ShoKinPtr()); for(unsigned int ix=0;ix<children.size();++ix) particle->abandonChild(children[ix]); children.clear(); if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr()); particle->vetoEmission(fb.type,fb.kinematics->scale()); // generate the new emission fb = selectTimeLikeBranching(particle,type,HardBranchingPtr()); // no emission, return if(!fb.kinematics) { if(particle->spinInfo()) particle->spinInfo()->develop(); return false; } setupChildren = true; continue; } else break; } // veto children else if(_reconOpt>=2) { // cut-off masses for the branching const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids); // compute the masses of the children Energy masses[3]; for(unsigned int ix=0;ix<2;++ix) { if(fc[ix].kinematics) { const vector<Energy> & vm = fc[ix].sudakov->virtualMasses(fc[ix].ids); Energy2 q2 = fc[ix].kinematics->z()*(1.-fc[ix].kinematics->z())*sqr(fc[ix].kinematics->scale()); if(fc[ix].ids[0]!=ParticleID::g) q2 += sqr(vm[0]); masses[ix+1] = sqrt(q2); } else { masses[ix+1] = virtualMasses[ix+1]; } } masses[0] = fb.ids[0]!=ParticleID::g ? virtualMasses[0] : ZERO; double z = fb.kinematics->z(); Energy2 pt2 = z*(1.-z)*(z*(1.-z)*sqr(fb.kinematics->scale()) + sqr(masses[0])) - sqr(masses[1])*(1.-z) - sqr(masses[2])*z; if(pt2>=ZERO) { break; } else { // reset the scales for the children for(unsigned int ix=0;ix<2;++ix) { if(fc[ix].kinematics) children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale()); else children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO); children[ix]->virtualMass(ZERO); } } } }; if(_reconOpt>=2) { // shower the first particle if(fc[0].kinematics) timeLikeShower(children[0],type,fc[0],false); if(children[0]->spinInfo()) children[0]->spinInfo()->develop(); // shower the second particle if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],false); if(children[1]->spinInfo()) children[1]->spinInfo()->develop(); // branching has happened particle->showerKinematics()->updateParent(particle, children,fb.type); } if(first&&!children.empty()) particle->showerKinematics()->resetChildren(particle,children); if(particle->spinInfo()) particle->spinInfo()->develop(); return true; } bool Evolver::spaceLikeShower(tShowerParticlePtr particle, PPtr beam, ShowerInteraction::Type type) { //using the pdf's associated with the ShowerHandler assures, that //modified pdf's are used for the secondary interactions via //CascadeHandler::resetPDFs(...) tcPDFPtr pdf; if(ShowerHandler::currentHandler()->firstPDF().particle() == _beam) pdf = ShowerHandler::currentHandler()->firstPDF().pdf(); if(ShowerHandler::currentHandler()->secondPDF().particle() == _beam) pdf = ShowerHandler::currentHandler()->secondPDF().pdf(); Energy freeze = ShowerHandler::currentHandler()->pdfFreezingScale(); // don't do anything if not needed if(_limitEmissions == 2 || hardOnly() || ( _limitEmissions == 1 && _nis != 0 ) || ( _limitEmissions == 4 && _nis + _nfs != 0 ) ) { if(particle->spinInfo()) particle->spinInfo()->develop(); return false; } Branching bb; // generate branching while (true) { bb=_splittingGenerator->chooseBackwardBranching(*particle,beam, _initialenhance, _beam,type, pdf,freeze); // return if no emission if(!bb.kinematics) { if(particle->spinInfo()) particle->spinInfo()->develop(); return false; } // if not vetoed break if(!spaceLikeVetoed(bb,particle)) break; // otherwise reset scale and continue particle->vetoEmission(bb.type,bb.kinematics->scale()); if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr()); } // assign the splitting function and shower kinematics particle->showerKinematics(bb.kinematics); if(bb.kinematics->pT()>progenitor()->highestpT()) progenitor()->highestpT(bb.kinematics->pT()); // For the time being we are considering only 1->2 branching // particles as in Sudakov form factor tcPDPtr part[2]={getParticleData(bb.ids[0]), getParticleData(bb.ids[2])}; if(particle->id()!=bb.ids[1]) { if(part[0]->CC()) part[0]=part[0]->CC(); if(part[1]->CC()) part[1]=part[1]->CC(); } // Now create the actual particles, make the otherChild a final state // particle, while the newParent is not ShowerParticlePtr newParent=new_ptr(ShowerParticle(part[0],false)); ShowerParticlePtr otherChild = new_ptr(ShowerParticle(part[1],true,true)); ShowerParticleVector theChildren; theChildren.push_back(particle); theChildren.push_back(otherChild); //this updates the evolution scale particle->showerKinematics()-> updateParent(newParent, theChildren,bb.type); // update the history if needed _currenttree->updateInitialStateShowerProduct(_progenitor,newParent); _currenttree->addInitialStateBranching(particle,newParent,otherChild); // for the reconstruction of kinematics, parent/child // relationships are according to the branching process: // now continue the shower ++_nis; bool emitted = _limitEmissions==0 ? spaceLikeShower(newParent,beam,type) : false; if(newParent->spinInfo()) newParent->spinInfo()->develop(); // now reconstruct the momentum if(!emitted) { if(_intrinsic.find(_progenitor)==_intrinsic.end()) { bb.kinematics->updateLast(newParent,ZERO,ZERO); } else { pair<Energy,double> kt=_intrinsic[_progenitor]; bb.kinematics->updateLast(newParent, kt.first*cos(kt.second), kt.first*sin(kt.second)); } } particle->showerKinematics()-> updateChildren(newParent, theChildren,bb.type,false); if(_limitEmissions!=0) { if(particle->spinInfo()) particle->spinInfo()->develop(); return true; } // perform the shower of the final-state particle timeLikeShower(otherChild,type,Branching(),true); updateHistory(otherChild); if(theChildren[1]->spinInfo()) theChildren[1]->spinInfo()->develop(); // return the emitted if(particle->spinInfo()) particle->spinInfo()->develop(); return true; } void Evolver::showerDecay(ShowerTreePtr decay) { _decayme = HwDecayerBasePtr(); _hardme = HwMEBasePtr(); // find the decayer // try the normal way if possible tDMPtr dm = decay->incomingLines().begin()->first->original() ->decayMode(); if(!dm) dm = decay->incomingLines().begin()->first->copy() ->decayMode(); if(!dm) dm = decay->incomingLines().begin()->first->progenitor()->decayMode(); // otherwise make a string and look it up if(!dm) { string tag = decay->incomingLines().begin()->first->original()->dataPtr()->name() + "->"; OrderedParticles outgoing; for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator it=decay->outgoingLines().begin();it!=decay->outgoingLines().end();++it) { if(abs(decay->incomingLines().begin()->first->original()->id()) == ParticleID::t && abs(it->first->original()->id())==ParticleID::Wplus && decay->treelinks().size() == 1) { ShowerTreePtr Wtree = decay->treelinks().begin()->first; for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator it2=Wtree->outgoingLines().begin();it2!=Wtree->outgoingLines().end();++it2) { outgoing.insert(it2->first->original()->dataPtr()); } } else { outgoing.insert(it->first->original()->dataPtr()); } } for(OrderedParticles::const_iterator it=outgoing.begin(); it!=outgoing.end();++it) { if(it!=outgoing.begin()) tag += ","; tag +=(**it).name(); } tag += ";"; dm = findDecayMode(tag); } if(dm) _decayme = dynamic_ptr_cast<HwDecayerBasePtr>(dm->decayer()); // set the ShowerTree to be showered currentTree(decay); decay->applyTransforms(); hardTree(HardTreePtr()); unsigned int interactionTry=0; do { try { // generate the showering doShowering(false,XCPtr()); // if no vetos // force calculation of spin correlations SpinPtr spInfo = decay->incomingLines().begin()->first->progenitor()->spinInfo(); if(spInfo) { if(!spInfo->developed()) spInfo->needsUpdate(); spInfo->develop(); } // and then return return; } catch (InteractionVeto) { currentTree()->clear(); ++interactionTry; } } while(interactionTry<=5); throw Exception() << "Too many tries for QED shower in Evolver::showerDecay()" << Exception::eventerror; } bool Evolver::spaceLikeDecayShower(tShowerParticlePtr particle, const ShowerParticle::EvolutionScales & maxScales, Energy minmass,ShowerInteraction::Type type, Branching fb) { // too many tries if(_nFSR>=_maxTryFSR) { ++_nFailedFSR; // too many failed events if(_nFailedFSR>=_maxFailFSR) throw Exception() << "Too many events have failed due to too many shower emissions, in\n" << "Evolver::timeLikeShower(). Terminating run\n" << Exception::runerror; throw Exception() << "Too many attempted emissions in Evolver::timeLikeShower()\n" << Exception::eventerror; } // generate the emission ShowerParticleVector children; int ntry=0; // generate the emission if(!fb.kinematics) fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type, HardBranchingPtr()); // no emission, return if(!fb.kinematics) return false; Branching fc[2]; bool setupChildren = true; while (ntry<50) { if(particle->virtualMass()==ZERO) particle->virtualMass(_progenitor->progenitor()->mass()); fc[0] = Branching(); fc[1] = Branching(); ++ntry; assert(fb.kinematics); // has emitted // Assign the shower kinematics to the emitting particle. if(setupChildren) { ++_nFSR; // Assign the shower kinematics to the emitting particle. particle->showerKinematics(fb.kinematics); if(fb.kinematics->pT()>progenitor()->highestpT()) progenitor()->highestpT(fb.kinematics->pT()); // create the ShowerParticle objects for the two children children = createTimeLikeChildren(particle,fb.ids); // updateChildren the children particle->showerKinematics()-> updateChildren(particle, children, fb.type,_reconOpt>=3); setupChildren = false; } // select branchings for children fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass, type,HardBranchingPtr()); fc[1] = selectTimeLikeBranching (children[1],type,HardBranchingPtr()); // old default if(_reconOpt==0) { // shower the first particle _currenttree->updateInitialStateShowerProduct(_progenitor,children[0]); _currenttree->addInitialStateBranching(particle,children[0],children[1]); if(fc[0].kinematics) spaceLikeDecayShower(children[0],maxScales,minmass,type,Branching()); // shower the second particle if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],true); updateHistory(children[1]); // branching has happened break; } // Herwig default else if(_reconOpt==1) { // shower the first particle _currenttree->updateInitialStateShowerProduct(_progenitor,children[0]); _currenttree->addInitialStateBranching(particle,children[0],children[1]); if(fc[0].kinematics) spaceLikeDecayShower(children[0],maxScales,minmass,type,Branching()); // shower the second particle if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],true); updateHistory(children[1]); // branching has happened particle->showerKinematics()->updateParent(particle, children,fb.type); // clean up the vetoed emission if(particle->virtualMass()==ZERO) { particle->showerKinematics(ShoKinPtr()); for(unsigned int ix=0;ix<children.size();++ix) particle->abandonChild(children[ix]); children.clear(); particle->vetoEmission(fb.type,fb.kinematics->scale()); // generate the new emission fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type, HardBranchingPtr()); // no emission, return if(!fb.kinematics) { return false; } setupChildren = true; continue; } else break; } else if(_reconOpt>=2) { // cut-off masses for the branching const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids); // compute the masses of the children Energy masses[3]; // space-like children masses[1] = children[0]->virtualMass(); // time-like child if(fc[1].kinematics) { const vector<Energy> & vm = fc[1].sudakov->virtualMasses(fc[1].ids); Energy2 q2 = fc[1].kinematics->z()*(1.-fc[1].kinematics->z())*sqr(fc[1].kinematics->scale()); if(fc[1].ids[0]!=ParticleID::g) q2 += sqr(vm[0]); masses[2] = sqrt(q2); } else { masses[2] = virtualMasses[2]; } masses[0]=particle->virtualMass(); double z = fb.kinematics->z(); Energy2 pt2 = (1.-z)*(z*sqr(masses[0])-sqr(masses[1])-z/(1.-z)*sqr(masses[2])); if(pt2>=ZERO) { break; } else { // reset the scales for the children for(unsigned int ix=0;ix<2;++ix) { if(fc[ix].kinematics) children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale()); else { if(ix==0) children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,Constants::MaxEnergy); else children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO); } } children[0]->virtualMass(_progenitor->progenitor()->mass()); children[1]->virtualMass(ZERO); } } }; if(_reconOpt>=2) { // In the case of splittings which involves coloured particles, // set properly the colour flow of the branching. // update the history if needed _currenttree->updateInitialStateShowerProduct(_progenitor,children[0]); _currenttree->addInitialStateBranching(particle,children[0],children[1]); // shower the first particle if(fc[0].kinematics) spaceLikeDecayShower(children[0],maxScales,minmass,type,Branching()); // shower the second particle if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],true); updateHistory(children[1]); // branching has happened particle->showerKinematics()->updateParent(particle, children,fb.type); } // branching has happened return true; } vector<ShowerProgenitorPtr> Evolver::setupShower(bool hard) { // generate POWHEG hard emission if needed if(_hardEmissionMode>0) hardestEmission(hard); ShowerInteraction::Type inter = interactions_[0]; if(_hardtree&&inter!=ShowerInteraction::Both) { inter = _hardtree->interaction(); } // set the initial colour partners setEvolutionPartners(hard,inter,false); // generate hard me if needed if(_hardEmissionMode==0 || (!hard && _hardEmissionMode==-1)) hardMatrixElementCorrection(hard); // get the particles to be showered vector<ShowerProgenitorPtr> particlesToShower = currentTree()->extractProgenitors(); // remake the colour partners if needed if(_currenttree->hardMatrixElementCorrection()) { setEvolutionPartners(hard,interactions_[0],true); _currenttree->resetShowerProducts(); } // return the answer return particlesToShower; } void Evolver::setEvolutionPartners(bool hard,ShowerInteraction::Type type, bool clear) { // match the particles in the ShowerTree and hardTree if(hardTree() && !hardTree()->connect(currentTree())) throw Exception() << "Can't match trees in " << "Evolver::setEvolutionPartners()" << Exception::eventerror; // extract the progenitors vector<ShowerParticlePtr> particles = currentTree()->extractProgenitorParticles(); // clear the partners if needed if(clear) { for(unsigned int ix=0;ix<particles.size();++ix) { particles[ix]->partner(ShowerParticlePtr()); particles[ix]->clearPartners(); } } // sort out the colour partners if(hardTree()) { // find the partner for(unsigned int ix=0;ix<particles.size();++ix) { tHardBranchingPtr partner = hardTree()->particles()[particles[ix]]->colourPartner(); if(!partner) continue; for(map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator it=hardTree()->particles().begin(); it!=hardTree()->particles().end();++it) { if(it->second==partner) particles[ix]->partner(it->first); } if(!particles[ix]->partner()) throw Exception() << "Can't match partners in " << "Evolver::setEvolutionPartners()" << Exception::eventerror; } } // Set the initial evolution scales showerModel()->partnerFinder()-> setInitialEvolutionScales(particles,!hard,type,!_hardtree); if(hardTree() && _hardPOWHEG) { bool tooHard=false; map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator eit=hardTree()->particles().end(); for(unsigned int ix=0;ix<particles.size();++ix) { map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator mit = hardTree()->particles().find(particles[ix]); Energy hardScale(ZERO); ShowerPartnerType::Type type(ShowerPartnerType::Undefined); // final-state if(particles[ix]->isFinalState()) { if(mit!= eit && !mit->second->children().empty()) { hardScale = mit->second->scale(); type = mit->second->type(); } } // initial-state else { if(mit!= eit && mit->second->parent()) { hardScale = mit->second->parent()->scale(); type = mit->second->parent()->type(); } } if(type!=ShowerPartnerType::Undefined) { if(type==ShowerPartnerType::QED) { tooHard |= particles[ix]->scales().QED_noAO<hardScale; } else if(type==ShowerPartnerType::QCDColourLine) { tooHard |= particles[ix]->scales().QCD_c_noAO<hardScale; } else if(type==ShowerPartnerType::QCDAntiColourLine) { tooHard |= particles[ix]->scales().QCD_ac_noAO<hardScale; } } } if(tooHard) convertHardTree(hard,type); } } void Evolver::updateHistory(tShowerParticlePtr particle) { if(!particle->children().empty()) { ShowerParticleVector theChildren; for(unsigned int ix=0;ix<particle->children().size();++ix) { ShowerParticlePtr part = dynamic_ptr_cast<ShowerParticlePtr> (particle->children()[ix]); theChildren.push_back(part); } // update the history if needed if(particle==_currenttree->getFinalStateShowerProduct(_progenitor)) _currenttree->updateFinalStateShowerProduct(_progenitor, particle,theChildren); _currenttree->addFinalStateBranching(particle,theChildren); for(unsigned int ix=0;ix<theChildren.size();++ix) updateHistory(theChildren[ix]); } } bool Evolver::startTimeLikeShower(ShowerInteraction::Type type) { _nFSR = 0; if(hardTree()) { map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator eit=hardTree()->particles().end(), mit = hardTree()->particles().find(progenitor()->progenitor()); if( mit != eit && !mit->second->children().empty() ) { bool output=truncatedTimeLikeShower(progenitor()->progenitor(), mit->second ,type,Branching(),true); if(output) updateHistory(progenitor()->progenitor()); return output; } } bool output = hardOnly() ? false : timeLikeShower(progenitor()->progenitor() ,type,Branching(),true) ; if(output) updateHistory(progenitor()->progenitor()); return output; } bool Evolver::startSpaceLikeShower(PPtr parent, ShowerInteraction::Type type) { if(hardTree()) { map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator eit =hardTree()->particles().end(), mit = hardTree()->particles().find(progenitor()->progenitor()); if( mit != eit && mit->second->parent() ) { return truncatedSpaceLikeShower( progenitor()->progenitor(), parent, mit->second->parent(), type ); } } return hardOnly() ? false : spaceLikeShower(progenitor()->progenitor(),parent,type); } bool Evolver:: startSpaceLikeDecayShower(const ShowerParticle::EvolutionScales & maxScales, Energy minimumMass,ShowerInteraction::Type type) { _nFSR = 0; if(hardTree()) { map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator eit =hardTree()->particles().end(), mit = hardTree()->particles().find(progenitor()->progenitor()); if( mit != eit && mit->second->parent() ) { HardBranchingPtr branch=mit->second; while(branch->parent()) branch=branch->parent(); return truncatedSpaceLikeDecayShower(progenitor()->progenitor(),maxScales, minimumMass, branch ,type, Branching()); } } return hardOnly() ? false : spaceLikeDecayShower(progenitor()->progenitor(),maxScales,minimumMass,type,Branching()); } bool Evolver::timeLikeVetoed(const Branching & fb, ShowerParticlePtr particle) { // work out type of interaction ShowerInteraction::Type type = fb.type==ShowerPartnerType::QED ? ShowerInteraction::QED : ShowerInteraction::QCD; // check whether emission was harder than largest pt of hard subprocess if ( hardVetoFS() && fb.kinematics->pT() > _progenitor->maxHardPt() ) return true; // soft matrix element correction veto if( softMEC()) { if(_hardme && _hardme->hasMECorrection()) { if(_hardme->softMatrixElementVeto(_progenitor,particle,fb)) return true; } else if(_decayme && _decayme->hasMECorrection()) { if(_decayme->softMatrixElementVeto(_progenitor,particle,fb)) return true; } } // veto on maximum pt if(fb.kinematics->pT()>_progenitor->maximumpT(type)) return true; // general vetos if (fb.kinematics && !_vetoes.empty()) { bool vetoed=false; for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin(); v != _vetoes.end(); ++v) { bool test = (**v).vetoTimeLike(_progenitor,particle,fb); switch((**v).vetoType()) { case ShowerVeto::Emission: vetoed |= test; break; case ShowerVeto::Shower: if(test) throw VetoShower(); break; case ShowerVeto::Event: if(test) throw Veto(); break; } } if(vetoed) return true; } if ( ShowerHandler::currentHandler()->firstInteraction() && ShowerHandler::currentHandler()->profileScales() ) { double weight = ShowerHandler::currentHandler()->profileScales()-> hardScaleProfile(_progenitor->hardScale(),fb.kinematics->pT()); if ( UseRandom::rnd() > weight ) return true; } return false; } bool Evolver::spaceLikeVetoed(const Branching & bb, ShowerParticlePtr particle) { // work out type of interaction ShowerInteraction::Type type = bb.type==ShowerPartnerType::QED ? ShowerInteraction::QED : ShowerInteraction::QCD; // check whether emission was harder than largest pt of hard subprocess if (hardVetoIS() && bb.kinematics->pT() > _progenitor->maxHardPt()) return true; // apply the soft correction if( softMEC() && _hardme && _hardme->hasMECorrection() ) { if(_hardme->softMatrixElementVeto(_progenitor,particle,bb)) return true; } // the more general vetos // check vs max pt for the shower if(bb.kinematics->pT()>_progenitor->maximumpT(type)) return true; if (!_vetoes.empty()) { bool vetoed=false; for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin(); v != _vetoes.end(); ++v) { bool test = (**v).vetoSpaceLike(_progenitor,particle,bb); switch ((**v).vetoType()) { case ShowerVeto::Emission: vetoed |= test; break; case ShowerVeto::Shower: if(test) throw VetoShower(); break; case ShowerVeto::Event: if(test) throw Veto(); break; } } if (vetoed) return true; } if ( ShowerHandler::currentHandler()->firstInteraction() && ShowerHandler::currentHandler()->profileScales() ) { double weight = ShowerHandler::currentHandler()->profileScales()-> hardScaleProfile(_progenitor->hardScale(),bb.kinematics->pT()); if ( UseRandom::rnd() > weight ) return true; } return false; } bool Evolver::spaceLikeDecayVetoed( const Branching & fb, ShowerParticlePtr particle) { // work out type of interaction ShowerInteraction::Type type = fb.type==ShowerPartnerType::QED ? ShowerInteraction::QED : ShowerInteraction::QCD; // apply the soft correction if( softMEC() && _decayme && _decayme->hasMECorrection() ) { if(_decayme->softMatrixElementVeto(_progenitor,particle,fb)) return true; } // veto on hardest pt in the shower if(fb.kinematics->pT()> _progenitor->maximumpT(type)) return true; // general vetos if (!_vetoes.empty()) { bool vetoed=false; for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin(); v != _vetoes.end(); ++v) { bool test = (**v).vetoSpaceLike(_progenitor,particle,fb); switch((**v).vetoType()) { case ShowerVeto::Emission: vetoed |= test; break; case ShowerVeto::Shower: if(test) throw VetoShower(); break; case ShowerVeto::Event: if(test) throw Veto(); break; } if (vetoed) return true; } } return false; } void Evolver::hardestEmission(bool hard) { HardTreePtr ISRTree; if( ( _hardme && _hardme->hasPOWHEGCorrection()!=0 && _hardEmissionMode< 2) || ( _decayme && _decayme->hasPOWHEGCorrection()!=0 && _hardEmissionMode!=2) ) { if(_hardme) { assert(hard); if(interaction_==4) { vector<ShowerInteraction::Type> inter(2); inter[0] = ShowerInteraction::QCD; inter[1] = ShowerInteraction::QED; _hardtree = _hardme->generateHardest( currentTree(),inter ); } else { _hardtree = _hardme->generateHardest( currentTree(),interactions_ ); } } else { assert(!hard); _hardtree = _decayme->generateHardest( currentTree() ); } // store initial state POWHEG radiation if(_hardtree && _hardme && _hardme->hasPOWHEGCorrection()==1) ISRTree=_hardtree; } else if (_hardEmissionMode>1 && hard) { // Get minimum pT cutoff used in shower approximation Energy maxpt = 1.*GeV; int colouredIn = 0; int colouredOut = 0; for( map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it = currentTree()->outgoingLines().begin(); it != currentTree()->outgoingLines().end(); ++it ) { if( it->second->coloured() ) colouredOut+=1; } for( map< ShowerProgenitorPtr, ShowerParticlePtr >::iterator it = currentTree()->incomingLines().begin(); it != currentTree()->incomingLines().end(); ++it ) { if( ! it->second->coloured() ) colouredIn+=1; } if ( theShowerApproximation ){ if ( theShowerApproximation->ffPtCut() == theShowerApproximation->fiPtCut() && theShowerApproximation->ffPtCut() == theShowerApproximation->iiPtCut() ) maxpt = theShowerApproximation->ffPtCut(); else if ( colouredIn == 2 && colouredOut == 0 ) maxpt = theShowerApproximation->iiPtCut(); else if ( colouredIn == 0 && colouredOut > 1 ) maxpt = theShowerApproximation->ffPtCut(); else if ( colouredIn == 2 && colouredOut == 1 ) maxpt = min(theShowerApproximation->iiPtCut(), theShowerApproximation->fiPtCut()); else if ( colouredIn == 1 && colouredOut > 1 ) maxpt = min(theShowerApproximation->ffPtCut(), theShowerApproximation->fiPtCut()); else maxpt = min(min(theShowerApproximation->iiPtCut(), theShowerApproximation->fiPtCut()), theShowerApproximation->ffPtCut()); } // Generate hardtree from born and real emission subprocesses _hardtree = ShowerHandler::currentHandler()->generateCKKW(currentTree()); // Find transverse momentum of hardest emission if (_hardtree){ for(set<HardBranchingPtr>::iterator it=_hardtree->branchings().begin(); it!=_hardtree->branchings().end();++it) { if ((*it)->parent() && (*it)->status()==HardBranching::Incoming) maxpt=(*it)->branchingParticle()->momentum().perp(); if ((*it)->children().size()==2 && (*it)->status()==HardBranching::Outgoing){ if ((*it)->branchingParticle()->id()!=21 && abs((*it)->branchingParticle()->id())>5 ){ if ((*it)->children()[0]->branchingParticle()->id()==21 || abs((*it)->children()[0]->branchingParticle()->id())<6) maxpt=(*it)->children()[0]->branchingParticle()->momentum().perp(); else if ((*it)->children()[1]->branchingParticle()->id()==21 || abs((*it)->children()[1]->branchingParticle()->id())<6) maxpt=(*it)->children()[1]->branchingParticle()->momentum().perp(); } else { if ( abs((*it)->branchingParticle()->id())<6){ if (abs((*it)->children()[0]->branchingParticle()->id())<6) maxpt = (*it)->children()[1]->branchingParticle()->momentum().perp(); else maxpt = (*it)->children()[0]->branchingParticle()->momentum().perp(); } else maxpt = (*it)->children()[1]->branchingParticle()->momentum().perp(); } } } } // Hardest (pt) emission should be the first powheg emission. - maxpt=min(sqrt(ShowerHandler::currentHandler()->lastXCombPtr()->lastCentralScale()),maxpt); + maxpt=min(sqrt(ShowerHandler::currentHandler()->lastXCombPtr()->lastShowerScale()),maxpt); // Set maxpt to pT of emission when showering POWHEG real-emission subprocesses if (!isPowhegSEvent && !isPowhegHEvent){ vector<int> outGluon; vector<int> outQuark; map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it; for( it = currentTree()->outgoingLines().begin(); it != currentTree()->outgoingLines().end(); ++it ) { if ( abs(it->second->id())< 6) outQuark.push_back(it->second->id()); if ( it->second->id()==21 ) outGluon.push_back(it->second->id()); } if (outGluon.size() + outQuark.size() == 1){ for( it = currentTree()->outgoingLines().begin(); it != currentTree()->outgoingLines().end(); ++it ) { if ( abs(it->second->id())< 6 || it->second->id()==21 ) maxpt = it->second->momentum().perp(); } } else if (outGluon.size() + outQuark.size() > 1){ // assume qqbar pair from a Z/gamma if (outGluon.size()==1 && outQuark.size() == 2 && outQuark[0]==-outQuark[1]){ for( it = currentTree()->outgoingLines().begin(); it != currentTree()->outgoingLines().end(); ++it ) { if ( it->second->id()==21 ) maxpt = it->second->momentum().perp(); } } // otherwise take the lowest pT avoiding born DY events else { maxpt = generator()->maximumCMEnergy(); for( it = currentTree()->outgoingLines().begin(); it != currentTree()->outgoingLines().end(); ++it ) { if ( abs(it->second->id())< 6 || it->second->id()==21 ) maxpt = min(maxpt,it->second->momentum().perp()); } } } } // set maximum pT for subsequent emissions from S events if ( isPowhegSEvent || (!isPowhegSEvent && !isPowhegHEvent)){ for( map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it = currentTree()->outgoingLines().begin(); it != currentTree()->outgoingLines().end(); ++it ) { if( ! it->second->coloured() ) continue; it->first->maximumpT(maxpt, ShowerInteraction::QCD ); } for( map< ShowerProgenitorPtr, ShowerParticlePtr >::iterator it = currentTree()->incomingLines().begin(); it != currentTree()->incomingLines().end(); ++it ) { if( ! it->second->coloured() ) continue; it->first->maximumpT(maxpt, ShowerInteraction::QCD ); } } } else _hardtree = ShowerHandler::currentHandler()->generateCKKW(currentTree()); // if hard me doesn't have a FSR powheg // correction use decay powheg correction if (_hardme && _hardme->hasPOWHEGCorrection()<2) { // check for intermediate colour singlet resonance const ParticleVector inter = _hardme->subProcess()->intermediates(); if (inter.size()!=1 || inter[0]->momentum().m2()/GeV2 < 0 || inter[0]->dataPtr()->iColour()!=PDT::Colour0){ if(_hardtree) connectTrees(currentTree(),_hardtree,hard); return; } map<ShowerProgenitorPtr, tShowerParticlePtr > out = currentTree()->outgoingLines(); // ignore cases where outgoing particles are not coloured if (out.size()!=2 || out. begin()->second->dataPtr()->iColour()==PDT::Colour0 || out.rbegin()->second->dataPtr()->iColour()==PDT::Colour0) { if(_hardtree) connectTrees(currentTree(),_hardtree,hard); return; } // look up decay mode tDMPtr dm; string tag; string inParticle = inter[0]->dataPtr()->name() + "->"; vector<string> outParticles; outParticles.push_back(out.begin ()->first->progenitor()->dataPtr()->name()); outParticles.push_back(out.rbegin()->first->progenitor()->dataPtr()->name()); for (int it=0; it<2; ++it){ tag = inParticle + outParticles[it] + "," + outParticles[(it+1)%2] + ";"; dm = generator()->findDecayMode(tag); if(dm) break; } // get the decayer HwDecayerBasePtr decayer; if(dm) decayer = dynamic_ptr_cast<HwDecayerBasePtr>(dm->decayer()); // check if decayer has a FSR POWHEG correction if (!decayer || decayer->hasPOWHEGCorrection()<2){ if(_hardtree) connectTrees(currentTree(),_hardtree,hard); return; } // generate the hardest emission ShowerDecayMap decay; PPtr in = new_ptr(*inter[0]); ShowerTreePtr decayTree = new_ptr(ShowerTree(in, decay)); HardTreePtr FSRTree = decayer->generateHardest(decayTree); if (!FSRTree) { if(_hardtree) connectTrees(currentTree(),_hardtree,hard); return; } // if there is no ISRTree make _hardtree from FSRTree if (!ISRTree){ vector<HardBranchingPtr> inBranch,hardBranch; for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit =currentTree()->incomingLines().begin(); cit!=currentTree()->incomingLines().end();++cit ) { inBranch.push_back(new_ptr(HardBranching(cit->second,SudakovPtr(), HardBranchingPtr(), HardBranching::Incoming))); inBranch.back()->beam(cit->first->original()->parents()[0]); hardBranch.push_back(inBranch.back()); } if(inBranch[0]->branchingParticle()->dataPtr()->coloured()) { inBranch[0]->colourPartner(inBranch[1]); inBranch[1]->colourPartner(inBranch[0]); } for(set<HardBranchingPtr>::iterator it=FSRTree->branchings().begin(); it!=FSRTree->branchings().end();++it) { if((**it).branchingParticle()->id()!=in->id()) hardBranch.push_back(*it); } hardBranch[2]->colourPartner(hardBranch[3]); hardBranch[3]->colourPartner(hardBranch[2]); HardTreePtr newTree = new_ptr(HardTree(hardBranch,inBranch, ShowerInteraction::QCD)); _hardtree = newTree; } // Otherwise modify the ISRTree to include the emission in FSRTree else { vector<tShowerParticlePtr> FSROut, ISROut; set<HardBranchingPtr>::iterator itFSR, itISR; // get outgoing particles for(itFSR =FSRTree->branchings().begin(); itFSR!=FSRTree->branchings().end();++itFSR){ if ((**itFSR).status()==HardBranching::Outgoing) FSROut.push_back((*itFSR)->branchingParticle()); } for(itISR =ISRTree->branchings().begin(); itISR!=ISRTree->branchings().end();++itISR){ if ((**itISR).status()==HardBranching::Outgoing) ISROut.push_back((*itISR)->branchingParticle()); } // find COM frame formed by outgoing particles LorentzRotation eventFrameFSR, eventFrameISR; eventFrameFSR = ((FSROut[0]->momentum()+FSROut[1]->momentum()).findBoostToCM()); eventFrameISR = ((ISROut[0]->momentum()+ISROut[1]->momentum()).findBoostToCM()); // find rotation between ISR and FSR frames int j=0; if (ISROut[0]->id()!=FSROut[0]->id()) j=1; eventFrameISR.rotateZ( (eventFrameFSR*FSROut[0]->momentum()).phi()- (eventFrameISR*ISROut[j]->momentum()).phi() ); eventFrameISR.rotateY( (eventFrameFSR*FSROut[0]->momentum()).theta()- (eventFrameISR*ISROut[j]->momentum()).theta() ); eventFrameISR.invert(); for (itFSR=FSRTree->branchings().begin(); itFSR!=FSRTree->branchings().end();++itFSR){ if ((**itFSR).branchingParticle()->id()==in->id()) continue; for (itISR =ISRTree->branchings().begin(); itISR!=ISRTree->branchings().end();++itISR){ if ((**itISR).status()==HardBranching::Incoming) continue; if ((**itFSR).branchingParticle()->id()== (**itISR).branchingParticle()->id()){ // rotate FSRTree particle to ISRTree event frame (**itISR).branchingParticle()->setMomentum(eventFrameISR* eventFrameFSR* (**itFSR).branchingParticle()->momentum()); (**itISR).branchingParticle()->rescaleMass(); // add the children of the FSRTree particles to the ISRTree if(!(**itFSR).children().empty()){ (**itISR).addChild((**itFSR).children()[0]); (**itISR).addChild((**itFSR).children()[1]); // rotate momenta to ISRTree event frame (**itISR).children()[0]->branchingParticle()->setMomentum(eventFrameISR* eventFrameFSR* (**itFSR).children()[0]->branchingParticle()->momentum()); (**itISR).children()[1]->branchingParticle()->setMomentum(eventFrameISR* eventFrameFSR* (**itFSR).children()[1]->branchingParticle()->momentum()); } } } } _hardtree = ISRTree; } } if(_hardtree){ connectTrees(currentTree(),_hardtree,hard); } } bool Evolver::truncatedTimeLikeShower(tShowerParticlePtr particle, HardBranchingPtr branch, ShowerInteraction::Type type, Branching fb, bool first) { // select a branching if we don't have one if(!fb.kinematics) fb = selectTimeLikeBranching(particle,type,branch); // must be an emission, the forced one it not a truncated one assert(fb.kinematics); ShowerParticleVector children; int ntry=0; Branching fc[2]; bool setupChildren = true; while (ntry<50) { if(!fc[0].hard) fc[0] = Branching(); if(!fc[1].hard) fc[1] = Branching(); ++ntry; // Assign the shower kinematics to the emitting particle. if(setupChildren) { ++_nFSR; // Assign the shower kinematics to the emitting particle. particle->showerKinematics(fb.kinematics); if(fb.kinematics->pT()>progenitor()->highestpT()) progenitor()->highestpT(fb.kinematics->pT()); // if not hard generate phi if(!fb.hard) fb.kinematics->phi(fb.sudakov->generatePhiForward(*particle,fb.ids,fb.kinematics)); // create the children children = createTimeLikeChildren(particle,fb.ids); // update the children particle->showerKinematics()-> updateChildren(particle, children,fb.type,_reconOpt>=3); setupChildren = false; } // select branchings for children if(!fc[0].kinematics) { // select branching for first particle if(!fb.hard && fb.iout ==1 ) fc[0] = selectTimeLikeBranching(children[0],type,branch); else if(fb.hard && !branch->children()[0]->children().empty() ) fc[0] = selectTimeLikeBranching(children[0],type,branch->children()[0]); else fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr()); } // select branching for the second particle if(!fc[1].kinematics) { // select branching for first particle if(!fb.hard && fb.iout ==2 ) fc[1] = selectTimeLikeBranching(children[1],type,branch); else if(fb.hard && !branch->children()[1]->children().empty() ) fc[1] = selectTimeLikeBranching(children[1],type,branch->children()[1]); else fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr()); } // old default if(_reconOpt==0 || (_reconOpt==1 && fb.hard) ) { // shower the first particle if(fc[0].kinematics) { // the parent has truncated emission and following line if(!fb.hard && fb.iout == 1) truncatedTimeLikeShower(children[0],branch,type,fc[0],false); // hard emission and subsquent hard emissions else if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false); // normal shower else timeLikeShower(children[0],type,fc[0],false); } if(children[0]->spinInfo()) children[0]->spinInfo()->develop(); // shower the second particle if(fc[1].kinematics) { // the parent has truncated emission and following line if(!fb.hard && fb.iout == 2) truncatedTimeLikeShower(children[1],branch,type,fc[1],false); // hard emission and subsquent hard emissions else if(fb.hard && !branch->children()[1]->children().empty() ) truncatedTimeLikeShower(children[1],branch->children()[1],type,fc[1],false); else timeLikeShower(children[1],type,fc[1],false); } if(children[1]->spinInfo()) children[1]->spinInfo()->develop(); // branching has happened particle->showerKinematics()->updateParent(particle, children,fb.type); break; } // H7 default else if(_reconOpt==1) { // shower the first particle if(fc[0].kinematics) { // the parent has truncated emission and following line if(!fb.hard && fb.iout == 1) truncatedTimeLikeShower(children[0],branch,type,fc[0],false); else timeLikeShower(children[0],type,fc[0],false); } if(children[0]->spinInfo()) children[0]->spinInfo()->develop(); // shower the second particle if(fc[1].kinematics) { // the parent has truncated emission and following line if(!fb.hard && fb.iout == 2) truncatedTimeLikeShower(children[1],branch,type,fc[1],false); else timeLikeShower(children[1],type,fc[1],false); } if(children[1]->spinInfo()) children[1]->spinInfo()->develop(); // branching has happened particle->showerKinematics()->updateParent(particle, children,fb.type); // clean up the vetoed emission if(particle->virtualMass()==ZERO) { particle->showerKinematics(ShoKinPtr()); for(unsigned int ix=0;ix<children.size();++ix) particle->abandonChild(children[ix]); children.clear(); if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr()); particle->vetoEmission(fb.type,fb.kinematics->scale()); // generate the new emission fb = selectTimeLikeBranching(particle,type,branch); // must be at least hard emission assert(fb.kinematics); setupChildren = true; continue; } else break; } else if(_reconOpt>=2) { // cut-off masses for the branching const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids); // compute the masses of the children Energy masses[3]; for(unsigned int ix=0;ix<2;++ix) { if(fc[ix].kinematics) { const vector<Energy> & vm = fc[ix].sudakov->virtualMasses(fc[ix].ids); Energy2 q2 = fc[ix].kinematics->z()*(1.-fc[ix].kinematics->z())*sqr(fc[ix].kinematics->scale()); if(fc[ix].ids[0]!=ParticleID::g) q2 += sqr(vm[0]); masses[ix+1] = sqrt(q2); } else { masses[ix+1] = virtualMasses[ix+1]; } } masses[0] = fb.ids[0]!=ParticleID::g ? virtualMasses[0] : ZERO; double z = fb.kinematics->z(); Energy2 pt2 = z*(1.-z)*(z*(1.-z)*sqr(fb.kinematics->scale()) + sqr(masses[0])) - sqr(masses[1])*(1.-z) - sqr(masses[2])*z; if(pt2>=ZERO) { break; } // if only the hard emission have to accept it else if ((fc[0].hard && !fc[1].kinematics) || (fc[1].hard && !fc[0].kinematics) ) { break; } else { // reset the scales for the children for(unsigned int ix=0;ix<2;++ix) { if(fc[ix].hard) continue; if(fc[ix].kinematics && ! fc[ix].hard ) children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale()); else children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO); children[ix]->virtualMass(ZERO); } } } }; if(_reconOpt>=2) { // shower the first particle if(fc[0].kinematics) { // the parent has truncated emission and following line if(!fb.hard && fb.iout == 1) truncatedTimeLikeShower(children[0],branch,type,fc[0],false); // hard emission and subsquent hard emissions else if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false); // normal shower else timeLikeShower(children[0],type,fc[0],false); } if(children[0]->spinInfo()) children[0]->spinInfo()->develop(); // shower the second particle if(fc[1].kinematics) { // the parent has truncated emission and following line if(!fb.hard && fb.iout == 2) truncatedTimeLikeShower(children[1],branch,type,fc[1],false); // hard emission and subsquent hard emissions else if(fb.hard && !branch->children()[1]->children().empty() ) truncatedTimeLikeShower(children[1],branch->children()[1],type,fc[1],false); else timeLikeShower(children[1],type,fc[1],false); } if(children[1]->spinInfo()) children[1]->spinInfo()->develop(); // branching has happened particle->showerKinematics()->updateParent(particle, children,fb.type); } if(first&&!children.empty()) particle->showerKinematics()->resetChildren(particle,children); if(particle->spinInfo()) particle->spinInfo()->develop(); return true; } bool Evolver::truncatedSpaceLikeShower(tShowerParticlePtr particle, PPtr beam, HardBranchingPtr branch, ShowerInteraction::Type type) { tcPDFPtr pdf; if(ShowerHandler::currentHandler()->firstPDF().particle() == beamParticle()) pdf = ShowerHandler::currentHandler()->firstPDF().pdf(); if(ShowerHandler::currentHandler()->secondPDF().particle() == beamParticle()) pdf = ShowerHandler::currentHandler()->secondPDF().pdf(); Energy freeze = ShowerHandler::currentHandler()->pdfFreezingScale(); Branching bb; // parameters of the force branching double z(0.); HardBranchingPtr timelike; for( unsigned int ix = 0; ix < branch->children().size(); ++ix ) { if( branch->children()[ix]->status() ==HardBranching::Outgoing) { timelike = branch->children()[ix]; } if( branch->children()[ix]->status() ==HardBranching::Incoming ) z = branch->children()[ix]->z(); } // generate truncated branching tcPDPtr part[2]; if(z>=0.&&z<=1.) { while (true) { if( !isTruncatedShowerON() || hardOnly() ) break; bb = splittingGenerator()->chooseBackwardBranching( *particle, beam, 1., beamParticle(), type , pdf,freeze); if( !bb.kinematics || bb.kinematics->scale() < branch->scale() ) { bb = Branching(); break; } // particles as in Sudakov form factor part[0] = getParticleData( bb.ids[0] ); part[1] = getParticleData( bb.ids[2] ); //is emitter anti-particle if( particle->id() != bb.ids[1]) { if( part[0]->CC() ) part[0] = part[0]->CC(); if( part[1]->CC() ) part[1] = part[1]->CC(); } double zsplit = bb.kinematics->z(); // apply the vetos for the truncated shower // if doesn't carry most of momentum ShowerInteraction::Type type2 = bb.type==ShowerPartnerType::QED ? ShowerInteraction::QED : ShowerInteraction::QCD; if(type2==branch->sudakov()->interactionType() && zsplit < 0.5) { particle->vetoEmission(bb.type,bb.kinematics->scale()); continue; } // others if( part[0]->id() != particle->id() || // if particle changes type bb.kinematics->pT() > progenitor()->maximumpT(type2) || // pt veto bb.kinematics->scale() < branch->scale()) { // angular ordering veto particle->vetoEmission(bb.type,bb.kinematics->scale()); continue; } // and those from the base class if(spaceLikeVetoed(bb,particle)) { particle->vetoEmission(bb.type,bb.kinematics->scale()); continue; } break; } } if( !bb.kinematics ) { //do the hard emission ShoKinPtr kinematics = branch->sudakov()->createInitialStateBranching( branch->scale(), z, branch->phi(), branch->children()[0]->pT() ); kinematics->initialize( *particle, beam ); // assign the splitting function and shower kinematics particle->showerKinematics( kinematics ); if(kinematics->pT()>progenitor()->highestpT()) progenitor()->highestpT(kinematics->pT()); // For the time being we are considering only 1->2 branching // Now create the actual particles, make the otherChild a final state // particle, while the newParent is not ShowerParticlePtr newParent = new_ptr( ShowerParticle( branch->branchingParticle()->dataPtr(), false ) ); ShowerParticlePtr otherChild = new_ptr( ShowerParticle( timelike->branchingParticle()->dataPtr(), true, true ) ); ShowerParticleVector theChildren; theChildren.push_back( particle ); theChildren.push_back( otherChild ); particle->showerKinematics()-> updateParent( newParent, theChildren, branch->type()); // update the history if needed currentTree()->updateInitialStateShowerProduct( progenitor(), newParent ); currentTree()->addInitialStateBranching( particle, newParent, otherChild ); // for the reconstruction of kinematics, parent/child // relationships are according to the branching process: // now continue the shower bool emitted=false; if(!hardOnly()) { if( branch->parent() ) { emitted = truncatedSpaceLikeShower( newParent, beam, branch->parent() , type); } else { emitted = spaceLikeShower( newParent, beam , type); } } if( !emitted ) { if( intrinsicpT().find( progenitor() ) == intrinsicpT().end() ) { kinematics->updateLast( newParent, ZERO, ZERO ); } else { pair<Energy,double> kt = intrinsicpT()[progenitor()]; kinematics->updateLast( newParent, kt.first*cos( kt.second ), kt.first*sin( kt.second ) ); } } particle->showerKinematics()-> updateChildren( newParent, theChildren,bb.type,false); if(hardOnly()) return true; // perform the shower of the final-state particle if( timelike->children().empty() ) { timeLikeShower( otherChild , type,Branching(),true); } else { truncatedTimeLikeShower( otherChild, timelike , type,Branching(), true); } updateHistory(otherChild); // return the emitted return true; } // assign the splitting function and shower kinematics particle->showerKinematics( bb.kinematics ); if(bb.kinematics->pT()>progenitor()->highestpT()) progenitor()->highestpT(bb.kinematics->pT()); // For the time being we are considering only 1->2 branching // Now create the actual particles, make the otherChild a final state // particle, while the newParent is not ShowerParticlePtr newParent = new_ptr( ShowerParticle( part[0], false ) ); ShowerParticlePtr otherChild = new_ptr( ShowerParticle( part[1], true, true ) ); ShowerParticleVector theChildren; theChildren.push_back( particle ); theChildren.push_back( otherChild ); particle->showerKinematics()-> updateParent( newParent, theChildren, bb.type); // update the history if needed currentTree()->updateInitialStateShowerProduct( progenitor(), newParent ); currentTree()->addInitialStateBranching( particle, newParent, otherChild ); // for the reconstruction of kinematics, parent/child // relationships are according to the branching process: // now continue the shower bool emitted = truncatedSpaceLikeShower( newParent, beam, branch,type); // now reconstruct the momentum if( !emitted ) { if( intrinsicpT().find( progenitor() ) == intrinsicpT().end() ) { bb.kinematics->updateLast( newParent, ZERO, ZERO ); } else { pair<Energy,double> kt = intrinsicpT()[ progenitor() ]; bb.kinematics->updateLast( newParent, kt.first*cos( kt.second ), kt.first*sin( kt.second ) ); } } particle->showerKinematics()-> updateChildren( newParent, theChildren, bb.type,false); // perform the shower of the final-state particle timeLikeShower( otherChild , type,Branching(),true); updateHistory(otherChild); // return the emitted return true; } bool Evolver:: truncatedSpaceLikeDecayShower(tShowerParticlePtr particle, const ShowerParticle::EvolutionScales & maxScales, Energy minmass, HardBranchingPtr branch, ShowerInteraction::Type type, Branching fb) { // select a branching if we don't have one if(!fb.kinematics) fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,branch); // must be an emission, the forced one it not a truncated one assert(fb.kinematics); ShowerParticleVector children; int ntry=0; Branching fc[2]; bool setupChildren = true; while (ntry<50) { if(!fc[0].hard) fc[0] = Branching(); if(!fc[1].hard) fc[1] = Branching(); ++ntry; if(setupChildren) { ++_nFSR; // Assign the shower kinematics to the emitting particle. particle->showerKinematics(fb.kinematics); if(fb.kinematics->pT()>progenitor()->highestpT()) progenitor()->highestpT(fb.kinematics->pT()); // create the ShowerParticle objects for the two children children = createTimeLikeChildren(particle,fb.ids); // updateChildren the children particle->showerKinematics()-> updateChildren(particle, children, fb.type,_reconOpt>=3); setupChildren = false; } // select branchings for children if(!fc[0].kinematics) { if(children[0]->id()==particle->id()) { // select branching for first particle if(!fb.hard) fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type,branch); else if(fb.hard && ! branch->children()[0]->children().empty() ) fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type, branch->children()[0]); else fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type, HardBranchingPtr()); } else { // select branching for first particle if(fb.hard && !branch->children()[0]->children().empty() ) fc[0] = selectTimeLikeBranching(children[0],type,branch->children()[0]); else fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr()); } } // select branching for the second particle if(!fc[1].kinematics) { if(children[1]->id()==particle->id()) { // select branching for first particle if(!fb.hard) fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type,branch); else if(fb.hard && ! branch->children()[1]->children().empty() ) fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type, branch->children()[1]); else fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type, HardBranchingPtr()); } else { if(fb.hard && !branch->children()[1]->children().empty() ) fc[1] = selectTimeLikeBranching(children[1],type,branch->children()[1]); else fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr()); } } // old default if(_reconOpt==0 || (_reconOpt==1 && fb.hard) ) { // update the history if needed currentTree()->updateInitialStateShowerProduct(progenitor(),children[0]); currentTree()->addInitialStateBranching(particle,children[0],children[1]); // shower the first particle if(fc[0].kinematics) { if(children[0]->id()==particle->id()) { if(!fb.hard) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch,type,fc[0]); else if(fb.hard && ! branch->children()[0]->children().empty() ) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch->children()[0],type,fc[0]); else spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[0]); } else { if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false); // normal shower else timeLikeShower(children[0],type,fc[0],false); } } // shower the second particle if(fc[1].kinematics) { if(children[0]->id()==particle->id()) { if(!fb.hard) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch,type,fc[1]); else if(fb.hard && ! branch->children()[0]->children().empty() ) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch->children()[0],type,fc[1]); else spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[1]); } else { if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[1],false); // normal shower else timeLikeShower(children[0],type,fc[1],false); } } updateHistory(children[1]); // branching has happened break; } // H7 default else if(_reconOpt==1) { // update the history if needed currentTree()->updateInitialStateShowerProduct(progenitor(),children[0]); currentTree()->addInitialStateBranching(particle,children[0],children[1]); // shower the first particle if(fc[0].kinematics) { if(children[0]->id()==particle->id()) { if(!fb.hard) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch,type,fc[0]); else if(fb.hard && ! branch->children()[0]->children().empty() ) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch->children()[0],type,fc[0]); else spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[0]); } else { if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false); // normal shower else timeLikeShower(children[0],type,fc[0],false); } } // shower the second particle if(fc[1].kinematics) { if(children[0]->id()==particle->id()) { if(!fb.hard) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch,type,fc[1]); else if(fb.hard && ! branch->children()[0]->children().empty() ) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch->children()[0],type,fc[1]); else spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[1]); } else { if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[1],false); // normal shower else timeLikeShower(children[0],type,fc[1],false); } } // clean up the vetoed emission if(particle->virtualMass()==ZERO) { particle->showerKinematics(ShoKinPtr()); for(unsigned int ix=0;ix<children.size();++ix) particle->abandonChild(children[ix]); children.clear(); particle->vetoEmission(fb.type,fb.kinematics->scale()); // generate the new emission fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,branch); // must be at least hard emission assert(fb.kinematics); setupChildren = true; continue; } else { updateHistory(children[1]); break; } } else if(_reconOpt>=2) { // cut-off masses for the branching const vector<Energy> & virtualMasses = fb.sudakov->virtualMasses(fb.ids); // compute the masses of the children Energy masses[3]; // space-like children masses[1] = children[0]->virtualMass(); // time-like child if(fc[1].kinematics) { const vector<Energy> & vm = fc[1].sudakov->virtualMasses(fc[1].ids); Energy2 q2 = fc[1].kinematics->z()*(1.-fc[1].kinematics->z())*sqr(fc[1].kinematics->scale()); if(fc[1].ids[0]!=ParticleID::g) q2 += sqr(vm[0]); masses[2] = sqrt(q2); } else { masses[2] = virtualMasses[2]; } masses[0]=particle->virtualMass(); double z = fb.kinematics->z(); Energy2 pt2 = (1.-z)*(z*sqr(masses[0])-sqr(masses[1])-z/(1.-z)*sqr(masses[2])); if(pt2>=ZERO) { break; } else { // reset the scales for the children for(unsigned int ix=0;ix<2;++ix) { if(fc[ix].kinematics) children[ix]->vetoEmission(fc[ix].type,fc[ix].kinematics->scale()); else { if(ix==0) children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,Constants::MaxEnergy); else children[ix]->vetoEmission(ShowerPartnerType::QCDColourLine,ZERO); } } children[0]->virtualMass(_progenitor->progenitor()->mass()); children[1]->virtualMass(ZERO); } } }; if(_reconOpt>=2) { // update the history if needed currentTree()->updateInitialStateShowerProduct(progenitor(),children[0]); currentTree()->addInitialStateBranching(particle,children[0],children[1]); // shower the first particle if(fc[0].kinematics) { if(children[0]->id()==particle->id()) { if(!fb.hard) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch,type,fc[0]); else if(fb.hard && ! branch->children()[0]->children().empty() ) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch->children()[0],type,fc[0]); else spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[0]); } else { if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false); // normal shower else timeLikeShower(children[0],type,fc[0],false); } } // shower the second particle if(fc[1].kinematics) { if(children[0]->id()==particle->id()) { if(!fb.hard) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch,type,fc[1]); else if(fb.hard && ! branch->children()[0]->children().empty() ) truncatedSpaceLikeDecayShower( children[0],maxScales,minmass, branch->children()[0],type,fc[1]); else spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[1]); } else { if(fb.hard && !branch->children()[0]->children().empty() ) truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[1],false); // normal shower else timeLikeShower(children[0],type,fc[1],false); } } updateHistory(children[1]); } return true; } bool Evolver::constructDecayTree(vector<ShowerProgenitorPtr> & particlesToShower, ShowerInteraction::Type inter) { Energy ptmax(-GeV); // get the maximum pt is all ready a hard tree if(hardTree()) { for(unsigned int ix=0;ix<particlesToShower.size();++ix) { if(particlesToShower[ix]->maximumpT(inter)>ptmax&& particlesToShower[ix]->progenitor()->isFinalState()) ptmax = particlesToShower[ix]->maximumpT(inter); } } vector<HardBranchingPtr> spaceBranchings,allBranchings; for(unsigned int ix=0;ix<particlesToShower.size();++ix) { if(particlesToShower[ix]->progenitor()->isFinalState()) { HardBranchingPtr newBranch; if(particlesToShower[ix]->hasEmitted()) { newBranch = new_ptr(HardBranching(particlesToShower[ix]->progenitor(), particlesToShower[ix]->progenitor()-> showerKinematics()->SudakovFormFactor(), HardBranchingPtr(),HardBranching::Outgoing)); constructTimeLikeLine(newBranch,particlesToShower[ix]->progenitor()); } else { newBranch = new_ptr(HardBranching(particlesToShower[ix]->progenitor(), SudakovPtr(),HardBranchingPtr(), HardBranching::Outgoing)); } allBranchings.push_back(newBranch); } else { HardBranchingPtr newBranch; if(particlesToShower[ix]->hasEmitted()) { newBranch = new_ptr(HardBranching(particlesToShower[ix]->progenitor(), particlesToShower[ix]->progenitor()-> showerKinematics()->SudakovFormFactor(), HardBranchingPtr(),HardBranching::Decay)); constructTimeLikeLine(newBranch,particlesToShower[ix]->progenitor()); HardBranchingPtr last=newBranch; do { for(unsigned int ix=0;ix<last->children().size();++ix) { if(last->children()[ix]->branchingParticle()->id()== particlesToShower[ix]->id()) { last = last->children()[ix]; continue; } } } while(!last->children().empty()); last->status(HardBranching::Incoming); spaceBranchings.push_back(newBranch); allBranchings .push_back(last); } else { newBranch = new_ptr(HardBranching(particlesToShower[ix]->progenitor(), SudakovPtr(),HardBranchingPtr(), HardBranching::Incoming)); spaceBranchings.push_back(newBranch); allBranchings .push_back(newBranch); } } } HardTreePtr QCDTree = new_ptr(HardTree(allBranchings,spaceBranchings,inter)); // set the charge partners ShowerParticleVector particles; particles.push_back(spaceBranchings.back()->branchingParticle()); for(set<HardBranchingPtr>::iterator cit=QCDTree->branchings().begin(); cit!=QCDTree->branchings().end();++cit) { if((*cit)->status()==HardBranching::Outgoing) particles.push_back((*cit)->branchingParticle()); } // get the partners showerModel()->partnerFinder()->setInitialEvolutionScales(particles,true,inter,true); // do the inverse recon if(!showerModel()->kinematicsReconstructor()-> deconstructDecayJets(QCDTree,this,inter)) { return false; } // clear the old shower currentTree()->clear(); // set the hard tree hardTree(QCDTree); // set the charge partners setEvolutionPartners(false,inter,false); // get the particles to be showered map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit; map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator cjt; particlesToShower.clear(); // incoming particles for(cit=currentTree()->incomingLines().begin(); cit!=currentTree()->incomingLines().end();++cit) particlesToShower.push_back(((*cit).first)); assert(particlesToShower.size()==1); // outgoing particles for(cjt=currentTree()->outgoingLines().begin(); cjt!=currentTree()->outgoingLines().end();++cjt) { particlesToShower.push_back(((*cjt).first)); if(ptmax>ZERO) particlesToShower.back()->maximumpT(ptmax,inter); } for(unsigned int ix=0;ix<particlesToShower.size();++ix) { map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator eit=hardTree()->particles().end(), mit = hardTree()->particles().find(particlesToShower[ix]->progenitor()); if( mit != eit) { if(mit->second->status()==HardBranching::Outgoing) particlesToShower[ix]->progenitor()->set5Momentum(mit->second->pVector()); } } return true; } bool Evolver::constructHardTree(vector<ShowerProgenitorPtr> & particlesToShower, ShowerInteraction::Type inter) { bool noEmission = true; vector<HardBranchingPtr> spaceBranchings,allBranchings; for(unsigned int ix=0;ix<particlesToShower.size();++ix) { if(particlesToShower[ix]->progenitor()->isFinalState()) { HardBranchingPtr newBranch; if(particlesToShower[ix]->hasEmitted()) { noEmission = false; newBranch = new_ptr(HardBranching(particlesToShower[ix]->progenitor(), particlesToShower[ix]->progenitor()-> showerKinematics()->SudakovFormFactor(), HardBranchingPtr(),HardBranching::Outgoing)); constructTimeLikeLine(newBranch,particlesToShower[ix]->progenitor()); } else { newBranch = new_ptr(HardBranching(particlesToShower[ix]->progenitor(), SudakovPtr(),HardBranchingPtr(), HardBranching::Outgoing)); } allBranchings.push_back(newBranch); } else { HardBranchingPtr first,last; if(!particlesToShower[ix]->progenitor()->parents().empty()) { noEmission = false; constructSpaceLikeLine(particlesToShower[ix]->progenitor(), first,last,SudakovPtr(), particlesToShower[ix]->original()->parents()[0]); } else { first = new_ptr(HardBranching(particlesToShower[ix]->progenitor(), SudakovPtr(),HardBranchingPtr(), HardBranching::Incoming)); if(particlesToShower[ix]->original()->parents().empty()) first->beam(particlesToShower[ix]->original()); else first->beam(particlesToShower[ix]->original()->parents()[0]); last = first; } spaceBranchings.push_back(first); allBranchings.push_back(last); } } if(!noEmission) { HardTreePtr QCDTree = new_ptr(HardTree(allBranchings,spaceBranchings, inter)); // set the charge partners ShowerParticleVector particles; for(set<HardBranchingPtr>::iterator cit=QCDTree->branchings().begin(); cit!=QCDTree->branchings().end();++cit) { particles.push_back((*cit)->branchingParticle()); } // get the partners showerModel()->partnerFinder()->setInitialEvolutionScales(particles,false, inter,true); // do the inverse recon if(!showerModel()->kinematicsReconstructor()-> deconstructHardJets(QCDTree,this,inter)) throw Exception() << "Can't to shower deconstruction for QED shower in" << "QEDEvolver::showerHard" << Exception::eventerror; // set the hard tree hardTree(QCDTree); } // clear the old shower currentTree()->clear(); // set the charge partners setEvolutionPartners(true,inter,false); // get the particles to be showered particlesToShower = currentTree()->extractProgenitors(); // reset momenta if(hardTree()) { for(unsigned int ix=0;ix<particlesToShower.size();++ix) { map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator eit=hardTree()->particles().end(), mit = hardTree()->particles().find(particlesToShower[ix]->progenitor()); if( mit != eit) { particlesToShower[ix]->progenitor()->set5Momentum(mit->second->showerMomentum()); } } } return true; } void Evolver::constructTimeLikeLine(tHardBranchingPtr branch, tShowerParticlePtr particle) { for(unsigned int ix=0;ix<particle->children().size();++ix) { HardBranching::Status status = branch->status(); tShowerParticlePtr child = dynamic_ptr_cast<ShowerParticlePtr>(particle->children()[ix]); if(child->children().empty()) { HardBranchingPtr newBranch = new_ptr(HardBranching(child,SudakovPtr(),branch,status)); branch->addChild(newBranch); } else { HardBranchingPtr newBranch = new_ptr(HardBranching(child,child->showerKinematics()->SudakovFormFactor(), branch,status)); constructTimeLikeLine(newBranch,child); branch->addChild(newBranch); } } // sort out the type of interaction if(!branch->children().empty()) { if(branch->branchingParticle()->id()==ParticleID::gamma || branch->children()[0]->branchingParticle()->id()==ParticleID::gamma || branch->children()[1]->branchingParticle()->id()==ParticleID::gamma) branch->type(ShowerPartnerType::QED); else { if(branch->branchingParticle()->id()== branch->children()[0]->branchingParticle()->id()) { if(branch->branchingParticle()->dataPtr()->iColour()==PDT::Colour8) { tShowerParticlePtr emittor = branch->branchingParticle()->showerKinematics()->z()>0.5 ? branch->children()[0]->branchingParticle() : branch->children()[1]->branchingParticle(); if(branch->branchingParticle()->colourLine()==emittor->colourLine()) branch->type(ShowerPartnerType::QCDAntiColourLine); else if(branch->branchingParticle()->antiColourLine()==emittor->antiColourLine()) branch->type(ShowerPartnerType::QCDColourLine); else assert(false); } else if(branch->branchingParticle()->colourLine()) { branch->type(ShowerPartnerType::QCDColourLine); } else if(branch->branchingParticle()->antiColourLine()) { branch->type(ShowerPartnerType::QCDAntiColourLine); } else assert(false); } else if(branch->branchingParticle()->id()==ParticleID::g && branch->children()[0]->branchingParticle()->id()== -branch->children()[1]->branchingParticle()->id()) { if(branch->branchingParticle()->showerKinematics()->z()>0.5) branch->type(ShowerPartnerType::QCDAntiColourLine); else branch->type(ShowerPartnerType::QCDColourLine); } else assert(false); } } } void Evolver::constructSpaceLikeLine(tShowerParticlePtr particle, HardBranchingPtr & first, HardBranchingPtr & last, SudakovPtr sud,PPtr beam) { if(!particle) return; if(!particle->parents().empty()) { tShowerParticlePtr parent = dynamic_ptr_cast<ShowerParticlePtr>(particle->parents()[0]); SudakovPtr newSud=particle->showerKinematics()->SudakovFormFactor(); constructSpaceLikeLine(parent,first,last,newSud,beam); } HardBranchingPtr newBranch = new_ptr(HardBranching(particle,sud,last,HardBranching::Incoming)); newBranch->beam(beam); if(!first) { first=newBranch; last =newBranch; return; } last->addChild(newBranch); tShowerParticlePtr timeChild = dynamic_ptr_cast<ShowerParticlePtr>(particle->parents()[0]->children()[1]); HardBranchingPtr timeBranch; if(!timeChild->children().empty()) { timeBranch = new_ptr(HardBranching(timeChild, timeChild->showerKinematics()->SudakovFormFactor(), last,HardBranching::Outgoing)); constructTimeLikeLine(timeBranch,timeChild); } else { timeBranch = new_ptr(HardBranching(timeChild,SudakovPtr(),last,HardBranching::Outgoing)); } last->addChild(timeBranch); // sort out the type if(last->branchingParticle() ->id() == ParticleID::gamma || newBranch->branchingParticle() ->id() == ParticleID::gamma || timeBranch->branchingParticle()->id() == ParticleID::gamma) { last->type(ShowerPartnerType::QED); } else if(last->branchingParticle()->id()==newBranch->branchingParticle()->id()) { if(last->branchingParticle()->id()==ParticleID::g) { if(last->branchingParticle()->colourLine()== newBranch->branchingParticle()->colourLine()) { last->type(ShowerPartnerType::QCDAntiColourLine); } else { last->type(ShowerPartnerType::QCDColourLine); } } else if(last->branchingParticle()->hasColour()) { last->type(ShowerPartnerType::QCDColourLine); } else if(last->branchingParticle()->hasAntiColour()) { last->type(ShowerPartnerType::QCDAntiColourLine); } else assert(false); } else if(newBranch->branchingParticle()->id()==ParticleID::g) { if(last->branchingParticle()->hasColour()) { last->type(ShowerPartnerType::QCDAntiColourLine); } else if(last->branchingParticle()->hasAntiColour()) { last->type(ShowerPartnerType::QCDColourLine); } else assert(false); } else if(newBranch->branchingParticle()->hasColour()) { last->type(ShowerPartnerType::QCDColourLine); } else if(newBranch->branchingParticle()->hasAntiColour()) { last->type(ShowerPartnerType::QCDAntiColourLine); } else { assert(false); } last=newBranch; } void Evolver::connectTrees(ShowerTreePtr showerTree, HardTreePtr hardTree, bool hard ) { ShowerParticleVector particles; // find the Sudakovs for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin(); cit!=hardTree->branchings().end();++cit) { // Sudakovs for ISR if((**cit).parent()&&(**cit).status()==HardBranching::Incoming) { ++_nis; IdList br(3); br[0] = (**cit).parent()->branchingParticle()->id(); br[1] = (**cit). branchingParticle()->id(); br[2] = (**cit).parent()->children()[0]==*cit ? (**cit).parent()->children()[1]->branchingParticle()->id() : (**cit).parent()->children()[0]->branchingParticle()->id(); BranchingList branchings = splittingGenerator()->initialStateBranchings(); if(br[1]<0&&br[0]==br[1]) { br[0] = abs(br[0]); br[1] = abs(br[1]); } else if(br[1]<0) { br[1] = -br[1]; br[2] = -br[2]; } long index = abs(br[1]); SudakovPtr sudakov; for(BranchingList::const_iterator cjt = branchings.lower_bound(index); cjt != branchings.upper_bound(index); ++cjt ) { IdList ids = cjt->second.second; if(ids[0]==br[0]&&ids[1]==br[1]&&ids[2]==br[2]) { sudakov=cjt->second.first; break; } } if(!sudakov) throw Exception() << "Can't find Sudakov for the hard emission in " << "Evolver::connectTrees() for ISR" << Exception::runerror; (**cit).parent()->sudakov(sudakov); } // Sudakovs for FSR else if(!(**cit).children().empty()) { ++_nfs; IdList br(3); br[0] = (**cit) .branchingParticle()->id(); br[1] = (**cit).children()[0]->branchingParticle()->id(); br[2] = (**cit).children()[1]->branchingParticle()->id(); BranchingList branchings = splittingGenerator()->finalStateBranchings(); if(br[0]<0) { br[0] = abs(br[0]); br[1] = abs(br[1]); br[2] = abs(br[2]); } long index = br[0]; SudakovPtr sudakov; for(BranchingList::const_iterator cjt = branchings.lower_bound(index); cjt != branchings.upper_bound(index); ++cjt ) { IdList ids = cjt->second.second; if(ids[0]==br[0]&&ids[1]==br[1]&&ids[2]==br[2]) { sudakov=cjt->second.first; break; } } if(!sudakov) throw Exception() << "Can't find Sudakov for the hard emission in " << "Evolver::connectTrees()" << Exception::runerror; (**cit).sudakov(sudakov); } } // calculate the evolution scale for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin(); cit!=hardTree->branchings().end();++cit) { particles.push_back((*cit)->branchingParticle()); } showerModel()->partnerFinder()-> setInitialEvolutionScales(particles,!hard,hardTree->interaction(), !hardTree->partnersSet()); hardTree->partnersSet(true); // inverse reconstruction if(hard) { showerModel()->kinematicsReconstructor()-> deconstructHardJets(hardTree,ShowerHandler::currentHandler()->evolver(), hardTree->interaction()); } else showerModel()->kinematicsReconstructor()-> deconstructDecayJets(hardTree,ShowerHandler::currentHandler()->evolver(), hardTree->interaction()); // now reset the momenta of the showering particles vector<ShowerProgenitorPtr> particlesToShower; for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit=showerTree->incomingLines().begin(); cit!=showerTree->incomingLines().end();++cit ) particlesToShower.push_back(cit->first); // extract the showering particles for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator cit=showerTree->outgoingLines().begin(); cit!=showerTree->outgoingLines().end();++cit ) particlesToShower.push_back(cit->first); // match them map<ShowerProgenitorPtr,HardBranchingPtr> partners; for(set<HardBranchingPtr>::const_iterator bit=hardTree->branchings().begin(); bit!=hardTree->branchings().end();++bit) { Energy2 dmin( 1e30*GeV2 ); ShowerProgenitorPtr partner; for(vector<ShowerProgenitorPtr>::const_iterator pit=particlesToShower.begin(); pit!=particlesToShower.end();++pit) { if(partners.find(*pit)!=partners.end()) continue; if( (**bit).branchingParticle()->id() != (**pit).progenitor()->id() ) continue; if( (**bit).branchingParticle()->isFinalState() != (**pit).progenitor()->isFinalState() ) continue; if( (**pit).progenitor()->isFinalState() ) { Energy2 dtest = sqr( (**pit).progenitor()->momentum().x() - (**bit).showerMomentum().x() ) + sqr( (**pit).progenitor()->momentum().y() - (**bit).showerMomentum().y() ) + sqr( (**pit).progenitor()->momentum().z() - (**bit).showerMomentum().z() ) + sqr( (**pit).progenitor()->momentum().t() - (**bit).showerMomentum().t() ); // add mass difference for identical particles (e.g. Z0 Z0 production) dtest += 1e10*sqr((**pit).progenitor()->momentum().m()-(**bit).showerMomentum().m()); if( dtest < dmin ) { partner = *pit; dmin = dtest; } } else { // ensure directions are right if((**pit).progenitor()->momentum().z()/(**bit).showerMomentum().z()>ZERO) { partner = *pit; break; } } } if(!partner) throw Exception() << "Failed to match shower and hard trees in Evolver::hardestEmission" << Exception::eventerror; partners[partner] = *bit; } for(vector<ShowerProgenitorPtr>::const_iterator pit=particlesToShower.begin(); pit!=particlesToShower.end();++pit) { HardBranchingPtr partner = partners[*pit]; if((**pit).progenitor()->dataPtr()->stable()) { (**pit).progenitor()->set5Momentum(partner->showerMomentum()); (**pit).copy()->set5Momentum(partner->showerMomentum()); } else { Lorentz5Momentum oldMomentum = (**pit).progenitor()->momentum(); Lorentz5Momentum newMomentum = partner->showerMomentum(); LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass()); (**pit).progenitor()->transform(boost); (**pit).copy() ->transform(boost); boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass()); (**pit).progenitor()->transform(boost); (**pit).copy() ->transform(boost); } } // correction boosts for daughter trees for(map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator tit = showerTree->treelinks().begin(); tit != showerTree->treelinks().end();++tit) { ShowerTreePtr decayTree = tit->first; map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit = decayTree->incomingLines().begin(); // reset the momentum of the decay particle Lorentz5Momentum oldMomentum = cit->first->progenitor()->momentum(); Lorentz5Momentum newMomentum = tit->second.second->momentum(); LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass()); decayTree->transform(boost,true); boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass()); decayTree->transform(boost,true); } } void Evolver::doShowering(bool hard,XCPtr xcomb) { // order of the interactions bool showerOrder(true); // zero number of emissions _nis = _nfs = 0; // if MC@NLO H event and limited emissions // indicate both final and initial state emission if ( isMCatNLOHEvent && _limitEmissions != 0 ) { _nis = _nfs = 1; } // extract particles to shower vector<ShowerProgenitorPtr> particlesToShower(setupShower(hard)); // setup the maximum scales for the shower if (hardVetoOn()) setupMaximumScales(particlesToShower,xcomb); // set the hard scales for the profiles setupHardScales(particlesToShower,xcomb); // specific stuff for hard processes and decays Energy minmass(ZERO), mIn(ZERO); // hard process generate the intrinsic p_T once and for all if(hard) { generateIntrinsicpT(particlesToShower); } // decay compute the minimum mass of the final-state else { for(unsigned int ix=0;ix<particlesToShower.size();++ix) { if(particlesToShower[ix]->progenitor()->isFinalState()) { if(particlesToShower[ix]->progenitor()->dataPtr()->stable()) minmass += particlesToShower[ix]->progenitor()->dataPtr()->constituentMass(); else minmass += particlesToShower[ix]->progenitor()->mass(); } else { mIn = particlesToShower[ix]->progenitor()->mass(); } } // throw exception if decay can't happen if ( minmass > mIn ) { throw Exception() << "Evolver.cc: Mass of decaying particle is " << "below constituent masses of decay products." << Exception::eventerror; } } // check if interactions in right order if(hardTree() && interaction_!=4 && hardTree()->interaction()!=interactions_[0]) { assert(interactions_.size()==2); showerOrder = false; swap(interactions_[0],interactions_[1]); } // loop over possible interactions for(unsigned int inter=0;inter<interactions_.size();++inter) { // set up for second pass if required if(inter!=0) { // zero intrinsic pt so only added first time round intrinsicpT().clear(); // construct the tree and throw veto if not possible if(!(hard ? constructHardTree (particlesToShower,interactions_[inter]) : constructDecayTree(particlesToShower,interactions_[inter]))) throw InteractionVeto(); } // create random particle vector (only need to do once) vector<ShowerProgenitorPtr> tmp; unsigned int nColouredIncoming = 0; while(particlesToShower.size()>0){ unsigned int xx=UseRandom::irnd(particlesToShower.size()); tmp.push_back(particlesToShower[xx]); particlesToShower.erase(particlesToShower.begin()+xx); } particlesToShower=tmp; for(unsigned int ix=0;ix<particlesToShower.size();++ix) { if(!particlesToShower[ix]->progenitor()->isFinalState() && particlesToShower[ix]->progenitor()->coloured()) ++nColouredIncoming; } bool switchRecon = hard && nColouredIncoming !=1; // main shower loop unsigned int ntry(0); bool reconstructed = false; do { // clear results of last attempt if needed if(ntry!=0) { currentTree()->clear(); setEvolutionPartners(hard,interactions_[inter],true); _nis = _nfs = 0; // if MC@NLO H event and limited emissions // indicate both final and initial state emission if ( isMCatNLOHEvent && _limitEmissions != 0 ) { _nis = _nfs = 1; } for(unsigned int ix=0; ix<particlesToShower.size();++ix) { SpinPtr spin = particlesToShower[ix]->progenitor()->spinInfo(); if(spin && spin->decayVertex() && dynamic_ptr_cast<tcSVertexPtr>(spin->decayVertex())) { spin->decayVertex(VertexPtr()); } } } // loop over particles for(unsigned int ix=0;ix<particlesToShower.size();++ix) { // extract the progenitor progenitor(particlesToShower[ix]); // final-state radiation if(progenitor()->progenitor()->isFinalState()) { if(!isFSRadiationON()) continue; // perform shower progenitor()->hasEmitted(startTimeLikeShower(interactions_[inter])); } // initial-state radiation else { if(!isISRadiationON()) continue; // hard process if(hard) { // get the PDF setBeamParticle(_progenitor->beam()); assert(beamParticle()); // perform the shower // set the beam particle tPPtr beamparticle=progenitor()->original(); if(!beamparticle->parents().empty()) beamparticle=beamparticle->parents()[0]; // generate the shower progenitor()->hasEmitted(startSpaceLikeShower(beamparticle, interactions_[inter])); } // decay else { // skip colour and electrically neutral particles if(!progenitor()->progenitor()->dataPtr()->coloured() && !progenitor()->progenitor()->dataPtr()->charged()) { progenitor()->hasEmitted(false); continue; } // perform shower // set the scales correctly. The current scale is the maximum scale for // emission not the starting scale ShowerParticle::EvolutionScales maxScales(progenitor()->progenitor()->scales()); progenitor()->progenitor()->scales() = ShowerParticle::EvolutionScales(); if(progenitor()->progenitor()->dataPtr()->charged()) { progenitor()->progenitor()->scales().QED = progenitor()->progenitor()->mass(); progenitor()->progenitor()->scales().QED_noAO = progenitor()->progenitor()->mass(); } if(progenitor()->progenitor()->hasColour()) { progenitor()->progenitor()->scales().QCD_c = progenitor()->progenitor()->mass(); progenitor()->progenitor()->scales().QCD_c_noAO = progenitor()->progenitor()->mass(); } if(progenitor()->progenitor()->hasAntiColour()) { progenitor()->progenitor()->scales().QCD_ac = progenitor()->progenitor()->mass(); progenitor()->progenitor()->scales().QCD_ac_noAO = progenitor()->progenitor()->mass(); } // perform the shower progenitor()->hasEmitted(startSpaceLikeDecayShower(maxScales,minmass, interactions_[inter])); } } } // do the kinematic reconstruction, checking if it worked reconstructed = hard ? showerModel()->kinematicsReconstructor()-> reconstructHardJets (currentTree(),intrinsicpT(),interactions_[inter], switchRecon && ntry>maximumTries()/2) : showerModel()->kinematicsReconstructor()-> reconstructDecayJets(currentTree(),interactions_[inter]); } while(!reconstructed&&maximumTries()>++ntry); // check if failed to generate the shower if(ntry==maximumTries()) { if(hard) throw ShowerHandler::ShowerTriesVeto(ntry); else throw Exception() << "Failed to generate the shower after " << ntry << " attempts in Evolver::showerDecay()" << Exception::eventerror; } } // tree has now showered _currenttree->hasShowered(true); if(!showerOrder) swap(interactions_[0],interactions_[1]); hardTree(HardTreePtr()); } void Evolver:: convertHardTree(bool hard,ShowerInteraction::Type type) { map<ColinePtr,ColinePtr> cmap; // incoming particles for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator cit=currentTree()->incomingLines().begin();cit!=currentTree()->incomingLines().end();++cit) { map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator mit = hardTree()->particles().find(cit->first->progenitor()); // put the colour lines in the map ShowerParticlePtr oldParticle = cit->first->progenitor(); ShowerParticlePtr newParticle = mit->second->branchingParticle(); ColinePtr cLine = oldParticle-> colourLine(); ColinePtr aLine = oldParticle->antiColourLine(); if(newParticle->colourLine() && cmap.find(newParticle-> colourLine())==cmap.end()) cmap[newParticle-> colourLine()] = cLine; if(newParticle->antiColourLine() && cmap.find(newParticle->antiColourLine())==cmap.end()) cmap[newParticle->antiColourLine()] = aLine; // check whether or not particle emits bool emission = mit->second->parent(); if(emission) { if(newParticle->colourLine()) { ColinePtr ctemp = newParticle-> colourLine(); ctemp->removeColoured(newParticle); } if(newParticle->antiColourLine()) { ColinePtr ctemp = newParticle->antiColourLine(); ctemp->removeAntiColoured(newParticle); } newParticle = mit->second->parent()->branchingParticle(); } // get the new colour lines ColinePtr newCLine,newALine; // sort out colour lines if(newParticle->colourLine()) { ColinePtr ctemp = newParticle-> colourLine(); ctemp->removeColoured(newParticle); if(cmap.find(ctemp)!=cmap.end()) { newCLine = cmap[ctemp]; } else { newCLine = new_ptr(ColourLine()); cmap[ctemp] = newCLine; } } // and anticolour lines if(newParticle->antiColourLine()) { ColinePtr ctemp = newParticle->antiColourLine(); ctemp->removeAntiColoured(newParticle); if(cmap.find(ctemp)!=cmap.end()) { newALine = cmap[ctemp]; } else { newALine = new_ptr(ColourLine()); cmap[ctemp] = newALine; } } // remove colour lines from old particle if(aLine) { aLine->removeAntiColoured(cit->first->copy()); aLine->removeAntiColoured(cit->first->progenitor()); } if(cLine) { cLine->removeColoured(cit->first->copy()); cLine->removeColoured(cit->first->progenitor()); } // add particle to colour lines if(newCLine) newCLine->addColoured (newParticle); if(newALine) newALine->addAntiColoured(newParticle); // insert new particles cit->first->copy(newParticle); ShowerParticlePtr sp(new_ptr(ShowerParticle(*newParticle,1,false))); cit->first->progenitor(sp); currentTree()->incomingLines()[cit->first]=sp; cit->first->perturbative(!emission); // and the emitted particle if needed if(emission) { ShowerParticlePtr newOut = mit->second->parent()->children()[1]->branchingParticle(); if(newOut->colourLine()) { ColinePtr ctemp = newOut-> colourLine(); ctemp->removeColoured(newOut); assert(cmap.find(ctemp)!=cmap.end()); cmap[ctemp]->addColoured (newOut); } if(newOut->antiColourLine()) { ColinePtr ctemp = newOut->antiColourLine(); ctemp->removeAntiColoured(newOut); assert(cmap.find(ctemp)!=cmap.end()); cmap[ctemp]->addAntiColoured(newOut); } ShowerParticlePtr sout=new_ptr(ShowerParticle(*newOut,1,true)); ShowerProgenitorPtr out=new_ptr(ShowerProgenitor(cit->first->original(),newOut,sout)); out->perturbative(false); currentTree()->outgoingLines().insert(make_pair(out,sout)); } if(hard) { // sort out the value of x if(mit->second->beam()->momentum().z()>ZERO) { sp->x(newParticle->momentum(). plus()/mit->second->beam()->momentum(). plus()); } else { sp->x(newParticle->momentum().minus()/mit->second->beam()->momentum().minus()); } } } // outgoing particles for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator cit=currentTree()->outgoingLines().begin();cit!=currentTree()->outgoingLines().end();++cit) { map<tShowerTreePtr,pair<tShowerProgenitorPtr, tShowerParticlePtr> >::const_iterator tit; for(tit = currentTree()->treelinks().begin(); tit != currentTree()->treelinks().end();++tit) { if(tit->second.first && tit->second.second==cit->first->progenitor()) break; } map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator mit = hardTree()->particles().find(cit->first->progenitor()); if(mit==hardTree()->particles().end()) continue; // put the colour lines in the map ShowerParticlePtr oldParticle = cit->first->progenitor(); ShowerParticlePtr newParticle = mit->second->branchingParticle(); ShowerParticlePtr newOut; ColinePtr cLine = oldParticle-> colourLine(); ColinePtr aLine = oldParticle->antiColourLine(); if(newParticle->colourLine() && cmap.find(newParticle-> colourLine())==cmap.end()) cmap[newParticle-> colourLine()] = cLine; if(newParticle->antiColourLine() && cmap.find(newParticle->antiColourLine())==cmap.end()) cmap[newParticle->antiColourLine()] = aLine; // check whether or not particle emits bool emission = !mit->second->children().empty(); if(emission) { if(newParticle->colourLine()) { ColinePtr ctemp = newParticle-> colourLine(); ctemp->removeColoured(newParticle); } if(newParticle->antiColourLine()) { ColinePtr ctemp = newParticle->antiColourLine(); ctemp->removeAntiColoured(newParticle); } newParticle = mit->second->children()[0]->branchingParticle(); newOut = mit->second->children()[1]->branchingParticle(); if(newParticle->id()!=oldParticle->id()&&newParticle->id()==newOut->id()) swap(newParticle,newOut); } // get the new colour lines ColinePtr newCLine,newALine; // sort out colour lines if(newParticle->colourLine()) { ColinePtr ctemp = newParticle-> colourLine(); ctemp->removeColoured(newParticle); if(cmap.find(ctemp)!=cmap.end()) { newCLine = cmap[ctemp]; } else { newCLine = new_ptr(ColourLine()); cmap[ctemp] = newCLine; } } // and anticolour lines if(newParticle->antiColourLine()) { ColinePtr ctemp = newParticle->antiColourLine(); ctemp->removeAntiColoured(newParticle); if(cmap.find(ctemp)!=cmap.end()) { newALine = cmap[ctemp]; } else { newALine = new_ptr(ColourLine()); cmap[ctemp] = newALine; } } // remove colour lines from old particle if(aLine) { aLine->removeAntiColoured(cit->first->copy()); aLine->removeAntiColoured(cit->first->progenitor()); } if(cLine) { cLine->removeColoured(cit->first->copy()); cLine->removeColoured(cit->first->progenitor()); } // special for unstable particles if(newParticle->id()==oldParticle->id() && (tit!=currentTree()->treelinks().end()||!oldParticle->dataPtr()->stable())) { Lorentz5Momentum oldMomentum = oldParticle->momentum(); Lorentz5Momentum newMomentum = newParticle->momentum(); LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass()); if(tit!=currentTree()->treelinks().end()) tit->first->transform(boost,false); oldParticle->transform(boost); boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass()); oldParticle->transform(boost); if(tit!=currentTree()->treelinks().end()) tit->first->transform(boost,false); newParticle=oldParticle; } // add particle to colour lines if(newCLine) newCLine->addColoured (newParticle); if(newALine) newALine->addAntiColoured(newParticle); // insert new particles cit->first->copy(newParticle); ShowerParticlePtr sp(new_ptr(ShowerParticle(*newParticle,1,true))); cit->first->progenitor(sp); currentTree()->outgoingLines()[cit->first]=sp; cit->first->perturbative(!emission); // and the emitted particle if needed if(emission) { if(newOut->colourLine()) { ColinePtr ctemp = newOut-> colourLine(); ctemp->removeColoured(newOut); assert(cmap.find(ctemp)!=cmap.end()); cmap[ctemp]->addColoured (newOut); } if(newOut->antiColourLine()) { ColinePtr ctemp = newOut->antiColourLine(); ctemp->removeAntiColoured(newOut); assert(cmap.find(ctemp)!=cmap.end()); cmap[ctemp]->addAntiColoured(newOut); } ShowerParticlePtr sout=new_ptr(ShowerParticle(*newOut,1,true)); ShowerProgenitorPtr out=new_ptr(ShowerProgenitor(cit->first->original(),newOut,sout)); out->perturbative(false); currentTree()->outgoingLines().insert(make_pair(out,sout)); } // update any decay products if(tit!=currentTree()->treelinks().end()) currentTree()->updateLink(tit->first,make_pair(cit->first,sp)); } // reset the tree currentTree()->resetShowerProducts(); // reextract the particles and set the colour partners vector<ShowerParticlePtr> particles = currentTree()->extractProgenitorParticles(); // clear the partners for(unsigned int ix=0;ix<particles.size();++ix) { particles[ix]->partner(ShowerParticlePtr()); particles[ix]->clearPartners(); } // clear the tree hardTree(HardTreePtr()); // Set the initial evolution scales showerModel()->partnerFinder()-> setInitialEvolutionScales(particles,!hard,type,!_hardtree); } Branching Evolver::selectTimeLikeBranching(tShowerParticlePtr particle, ShowerInteraction::Type type, HardBranchingPtr branch) { Branching fb; unsigned int iout=0; tcPDPtr pdata[2]; while (true) { // break if doing truncated shower and no truncated shower needed if(branch && (!isTruncatedShowerON()||hardOnly())) break; fb=_splittingGenerator->chooseForwardBranching(*particle,_finalenhance,type); // no emission break if(!fb.kinematics) break; // special for truncated shower if(branch) { // check haven't evolved too far if(fb.kinematics->scale() < branch->scale()) { fb=Branching(); break; } // get the particle data objects for(unsigned int ix=0;ix<2;++ix) pdata[ix]=getParticleData(fb.ids[ix+1]); if(particle->id()!=fb.ids[0]) { for(unsigned int ix=0;ix<2;++ix) { tPDPtr cc(pdata[ix]->CC()); if(cc) pdata[ix]=cc; } } // find the truncated line iout=0; if(pdata[0]->id()!=pdata[1]->id()) { if(pdata[0]->id()==particle->id()) iout=1; else if (pdata[1]->id()==particle->id()) iout=2; } else if(pdata[0]->id()==particle->id()) { if(fb.kinematics->z()>0.5) iout=1; else iout=2; } // apply the vetos for the truncated shower // no flavour changing branchings if(iout==0) { particle->vetoEmission(fb.type,fb.kinematics->scale()); continue; } double zsplit = iout==1 ? fb.kinematics->z() : 1-fb.kinematics->z(); // only if same interaction for forced branching ShowerInteraction::Type type2 = fb.type==ShowerPartnerType::QED ? ShowerInteraction::QED : ShowerInteraction::QCD; // and evolution if(type2==branch->sudakov()->interactionType()) { if(zsplit < 0.5 || // hardest line veto fb.kinematics->scale()*zsplit < branch->scale() ) { // angular ordering veto particle->vetoEmission(fb.type,fb.kinematics->scale()); continue; } } // pt veto if(fb.kinematics->pT() > progenitor()->maximumpT(type2)) { particle->vetoEmission(fb.type,fb.kinematics->scale()); continue; } } // standard vetos for all emissions if(timeLikeVetoed(fb,particle)) { particle->vetoEmission(fb.type,fb.kinematics->scale()); if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr()); continue; } break; } // normal case if(!branch) { if(fb.kinematics) fb.hard = false; return fb; } // truncated emission if(fb.kinematics) { fb.hard = false; fb.iout = iout; return fb; } // otherwise need to return the hard emission // construct the kinematics for the hard emission ShoKinPtr showerKin= branch->sudakov()->createFinalStateBranching(branch->scale(), branch->children()[0]->z(), branch->phi(), branch->children()[0]->pT()); showerKin->initialize( *particle,PPtr() ); IdList idlist(3); idlist[0] = particle->id(); idlist[1] = branch->children()[0]->branchingParticle()->id(); idlist[2] = branch->children()[1]->branchingParticle()->id(); fb = Branching( showerKin, idlist, branch->sudakov(),branch->type() ); fb.hard = true; fb.iout=0; // return it return fb; } Branching Evolver::selectSpaceLikeDecayBranching(tShowerParticlePtr particle, const ShowerParticle::EvolutionScales & maxScales, Energy minmass,ShowerInteraction::Type type, HardBranchingPtr branch) { Branching fb; unsigned int iout=0; tcPDPtr pdata[2]; while (true) { // break if doing truncated shower and no truncated shower needed if(branch && (!isTruncatedShowerON()||hardOnly())) break; // select branching fb=_splittingGenerator->chooseDecayBranching(*particle,maxScales,minmass, _initialenhance,type); // return if no radiation if(!fb.kinematics) break; // special for truncated shower if(branch) { // check haven't evolved too far if(fb.kinematics->scale() < branch->scale()) { fb=Branching(); break; } // get the particle data objects for(unsigned int ix=0;ix<2;++ix) pdata[ix]=getParticleData(fb.ids[ix+1]); if(particle->id()!=fb.ids[0]) { for(unsigned int ix=0;ix<2;++ix) { tPDPtr cc(pdata[ix]->CC()); if(cc) pdata[ix]=cc; } } // find the truncated line iout=0; if(pdata[0]->id()!=pdata[1]->id()) { if(pdata[0]->id()==particle->id()) iout=1; else if (pdata[1]->id()==particle->id()) iout=2; } else if(pdata[0]->id()==particle->id()) { if(fb.kinematics->z()>0.5) iout=1; else iout=2; } // apply the vetos for the truncated shower // no flavour changing branchings if(iout==0) { particle->vetoEmission(fb.type,fb.kinematics->scale()); continue; } ShowerInteraction::Type type2 = fb.type==ShowerPartnerType::QED ? ShowerInteraction::QED : ShowerInteraction::QCD; double zsplit = iout==1 ? fb.kinematics->z() : 1-fb.kinematics->z(); if(type2==branch->sudakov()->interactionType()) { if(zsplit < 0.5 || // hardest line veto fb.kinematics->scale()*zsplit < branch->scale() ) { // angular ordering veto particle->vetoEmission(fb.type,fb.kinematics->scale()); continue; } } // pt veto if(fb.kinematics->pT() > progenitor()->maximumpT(type2)) { particle->vetoEmission(fb.type,fb.kinematics->scale()); continue; } } // if not vetoed break if(spaceLikeDecayVetoed(fb,particle)) { // otherwise reset scale and continue particle->vetoEmission(fb.type,fb.kinematics->scale()); continue; } break; } // normal case if(!branch) { if(fb.kinematics) fb.hard = false; return fb; } // truncated emission if(fb.kinematics) { fb.hard = false; fb.iout = iout; return fb; } // otherwise need to return the hard emission // construct the kinematics for the hard emission ShoKinPtr showerKin= branch->sudakov()->createDecayBranching(branch->scale(), branch->children()[0]->z(), branch->phi(), branch->children()[0]->pT()); showerKin->initialize( *particle,PPtr() ); IdList idlist(3); idlist[0] = particle->id(); idlist[1] = branch->children()[0]->branchingParticle()->id(); idlist[2] = branch->children()[1]->branchingParticle()->id(); // create the branching fb = Branching( showerKin, idlist, branch->sudakov(),ShowerPartnerType::QCDColourLine ); fb.hard=true; fb.iout=0; // return it return fb; } diff --git a/Tests/Makefile.am b/Tests/Makefile.am --- a/Tests/Makefile.am +++ b/Tests/Makefile.am @@ -1,357 +1,360 @@ AUTOMAKE_OPTIONS = -Wno-portability AM_LDFLAGS += -module -avoid-version -rpath /dummy/path/not/used EXTRA_DIST = Inputs python Rivet dist-hook: rm -rf $(distdir)/Inputs/.svn rm -rf $(distdir)/python/.svn rm -rf $(distdir)/Rivet/.svn EXTRA_LTLIBRARIES = LeptonTest.la GammaTest.la HadronTest.la DISTest.la if WANT_LIBFASTJET EXTRA_LTLIBRARIES += HadronJetTest.la LeptonJetTest.la HadronJetTest_la_SOURCES = \ Hadron/VHTest.h Hadron/VHTest.cc\ Hadron/VTest.h Hadron/VTest.cc\ Hadron/HTest.h Hadron/HTest.cc HadronJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \ -I$(FASTJETPATH) HadronJetTest_la_LIBADD = $(FASTJETLIBS) LeptonJetTest_la_SOURCES = \ Lepton/TopDecay.h Lepton/TopDecay.cc LeptonJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \ -I$(FASTJETPATH) LeptonJetTest_la_LIBADD = $(FASTJETLIBS) endif LeptonTest_la_SOURCES = \ Lepton/VVTest.h Lepton/VVTest.cc \ Lepton/VBFTest.h Lepton/VBFTest.cc \ Lepton/VHTest.h Lepton/VHTest.cc \ Lepton/FermionTest.h Lepton/FermionTest.cc GammaTest_la_SOURCES = \ Gamma/GammaMETest.h Gamma/GammaMETest.cc \ Gamma/GammaPMETest.h Gamma/GammaPMETest.cc DISTest_la_SOURCES = \ DIS/DISTest.h DIS/DISTest.cc HadronTest_la_SOURCES = \ Hadron/HadronVVTest.h Hadron/HadronVVTest.cc\ Hadron/HadronVBFTest.h Hadron/HadronVBFTest.cc\ Hadron/WHTest.h Hadron/WHTest.cc\ Hadron/ZHTest.h Hadron/ZHTest.cc\ Hadron/VGammaTest.h Hadron/VGammaTest.cc\ Hadron/ZJetTest.h Hadron/ZJetTest.cc\ Hadron/WJetTest.h Hadron/WJetTest.cc\ Hadron/QQHTest.h Hadron/QQHTest.cc REPO = $(top_builddir)/src/HerwigDefaults.rpo HERWIG = $(top_builddir)/src/Herwig HWREAD = $(HERWIG) read --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src HWRUN = $(HERWIG) run tests : tests-LEP tests-DIS tests-LHC tests-Gamma if WANT_LIBFASTJET tests-LEP : test-LEP-VV test-LEP-VH test-LEP-VBF test-LEP-BB test-LEP-Quarks test-LEP-Leptons \ test-LEP-default test-LEP-Powheg test-LEP-TopDecay else tests-LEP : test-LEP-VV test-LEP-VH test-LEP-VBF test-LEP-BB test-LEP-Quarks test-LEP-Leptons endif tests-DIS : test-DIS-Charged test-DIS-Neutral if WANT_LIBFASTJET tests-LHC : test-LHC-WW test-LHC-WZ test-LHC-ZZ test-LHC-ZGamma test-LHC-WGamma \ test-LHC-ZH test-LHC-WH test-LHC-ZJet test-LHC-WJet test-LHC-Z test-LHC-W test-LHC-ZZVBF test-LHC-VBF \ test-LHC-WWVBF test-LHC-bbH test-LHC-ttH test-LHC-GammaGamma test-LHC-GammaJet test-LHC-Higgs \ test-LHC-HiggsJet test-LHC-QCDFast test-LHC-QCD test-LHC-Top test-LHC-Bottom \ test-LHC-WHJet test-LHC-ZHJet test-LHC-HJet test-LHC-ZShower test-LHC-WShower\ test-LHC-WHJet-Powheg test-LHC-ZHJet-Powheg test-LHC-HJet-Powheg \ test-LHC-ZShower-Powheg test-LHC-WShower-Powheg else tests-LHC : test-LHC-WW test-LHC-WZ test-LHC-ZZ test-LHC-ZGamma test-LHC-WGamma \ test-LHC-ZH test-LHC-WH test-LHC-ZJet test-LHC-WJet test-LHC-Z test-LHC-W test-LHC-ZZVBF test-LHC-VBF \ test-LHC-WWVBF test-LHC-bbH test-LHC-ttH test-LHC-GammaGamma test-LHC-GammaJet test-LHC-Higgs \ test-LHC-HiggsJet test-LHC-QCDFast test-LHC-QCD test-LHC-Top endif tests-Gamma : test-Gamma-FF test-Gamma-WW test-Gamma-P if WANT_LIBFASTJET test-LEP-% : Inputs/LEP-%.in LeptonTest.la LeptonJetTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} else test-LEP-% : Inputs/LEP-%.in LeptonTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} endif Rivet-LHC-Matchbox-% : Rivet/LHC-Matchbox-%.in if [ ! -d Rivet-$(notdir $(subst .in,,$<)) ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi; cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \ ../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \ ../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \ mv $(notdir $(subst .in,.yoda,$<)) ..; \ cd .. Rivet-TVT-Matchbox-% : Rivet/TVT-Matchbox-%.in if [ ! -d Rivet-$(notdir $(subst .in,,$<)) ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi; cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \ ../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \ ../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \ mv $(notdir $(subst .in,.yoda,$<)) ..; \ cd .. Rivet-TVT-Dipole-% : Rivet/TVT-Dipole-%.in if [ ! -d Rivet-$(notdir $(subst .in,,$<)) ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi; cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \ ../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \ ../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \ mv $(notdir $(subst .in,.yoda,$<)) ..; \ cd .. Rivet-LHC-Dipole-% : Rivet/LHC-Dipole-%.in if [ ! -d Rivet-$(notdir $(subst .in,,$<)) ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi; cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \ ../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \ ../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \ mv $(notdir $(subst .in,.yoda,$<)) ..; \ cd .. Rivet/LEP-%.in : python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet/DIS-%.in : python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet/BFactory-%.in: python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet/TVT-%.in: python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet/LHC-%.in: python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet/Star-%.in: python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet/SppS-%.in: python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet/ISR-%.in: python/make_input_files.py $(notdir $(subst .in,,$@)) Rivet-LEP-Matchbox-% : Rivet/LEP-Matchbox-%.in if [ ! -d Rivet-$(notdir $(subst .in,,$<)) ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi; cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \ ../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \ ../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \ mv $(notdir $(subst .in,.yoda,$<)) ..; \ cd .. Rivet-LEP-Dipole-% : Rivet/LEP-Dipole-%.in if [ ! -d Rivet-$(notdir $(subst .in,,$<)) ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi; cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \ ../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \ ../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \ mv $(notdir $(subst .in,.yoda,$<)) ..; \ cd .. Rivet-BFactory-Matchbox-% : Rivet/BFactory-Matchbox-%.in if [ ! -d Rivet-$(notdir $(subst .in,,$<)) ]; then mkdir Rivet-$(notdir $(subst .in,,$<)); fi; cd Rivet-$(notdir $(subst .in,,$<)); echo `pwd`; \ ../$(HERWIG) read --repo ../$(REPO) -L ../$(top_builddir)/lib -i ../$(top_builddir)/src ../$<; \ ../$(HERWIG) run $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000}; \ mv $(notdir $(subst .in,.yoda,$<)) ..; \ cd .. Rivet-LEP-% : Rivet/LEP-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-BFactory-% : Rivet/BFactory-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-TVT-% : Rivet/TVT-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-DIS-% : Rivet/DIS-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-LHC-% : Rivet/LHC-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-Star-% : Rivet/Star-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-SppS-% : Rivet/SppS-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-ISR-% : Rivet/ISR-%.in $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} Rivet-inputfiles: $(shell echo Rivet/LEP{,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{10,14,22,35,44,91,130,133,136,161,172,177,183,189,192,196,197,200,202,206,91-nopi}.in) \ $(shell echo Rivet/BFactory{,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{10.52,10.52-sym,10.54,10.45,10.58}.in) \ $(shell echo Rivet/BFactory-{Upsilon,Upsilon2,Upsilon4,Tau}.in) \ $(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{e--LowQ2,e+-LowQ2,e+-HighQ2}.in) \ $(shell echo Rivet/TVT{,-Powheg,-Matchbox,-Dipole,-Matchbox-Powheg}-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-e,Run-II-Z-{,LowMass-,HighMass-}mu,Run-II-W}.in) \ - $(shell echo Rivet/TVT-Run-II-{DiPhoton,PromptPhoton}.in) \ + $(shell echo Rivet/TVT-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet,PromptPhoton}.in) \ + $(shell echo Rivet/TVT-Powheg-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \ $(shell echo Rivet/TVT{,-Dipole,-Matchbox,-Matchbox-Powheg}-{Run-II-Jets-{0..11},Run-I-Jets-{1..8}}.in ) \ $(shell echo Rivet/TVT{,-Dipole,-Matchbox,-Matchbox-Powheg}-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.in ) \ $(shell echo Rivet/TVT-{Run-I,Run-II,300,630,900}-UE.in) \ $(shell echo Rivet/LHC{,-Dipole,-Matchbox,-Matchbox-Powheg}-7-Jets-{0..15}.in ) \ $(shell echo Rivet/LHC-{900,2360,2760,7,8,13}-UE.in ) \ $(shell echo Rivet/LHC-{900,7}-UE-Long.in ) \ $(shell echo Rivet/LHC{,-Dipole,-Matchbox,-Matchbox-Powheg}-7-Charm-{1..5}.in) \ $(shell echo Rivet/LHC{,-Dipole,-Matchbox,-Matchbox-Powheg}-7-Bottom-{0..8}.in) \ $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg}-7-Top-{L,SL,All}.in) \ $(shell echo Rivet/Star-{UE,Jets-{1..4}}.in ) \ $(shell echo Rivet/ISR-{30,44,53,62}-UE.in ) \ $(shell echo Rivet/SppS-{53,63,200,500,900,546}-UE.in ) \ $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Powheg,-Dipole}-{W-{e,mu},13-Z-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,WZ,WW-{emu,ll},ZZ-{ll,lv},W-Z-{e,mu},8-Z-mu}.in) \ $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole}-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.in) \ $(shell echo Rivet/LHC{-Matchbox,-Matchbox-Powheg,-Dipole}-{Z-b,Z-bb,W-b,8-Z-jj}.in) \ - $(shell echo Rivet/LHC-7-PromptPhoton-{1..4}.in) \ - Rivet/LHC-7-DiPhoton.in Rivet/LHC-GammaGamma-7.in \ + $(shell echo Rivet/LHC-7-PromptPhoton-{1..4}.in) Rivet/LHC-GammaGamma-7.in \ + $(shell echo Rivet/LHC{,-Powheg}-7-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \ $(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole}-{ggH,VBF,WH,ZH}.in) \ $(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole}-8-{ggH,VBF,WH,ZH}{,-GammaGamma}.in) \ $(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole}-ggHJet.in) Rivet-LEP: $(shell echo Rivet-LEP{,-Powheg,-Matchbox,-Dipole}-{10,14,22,35,44,91,130,133,136,161,172,177,183,189,192,196,197,200,202,206,91-nopi}) rm -rf Rivet-LEP python/merge-LEP LEP python/merge-LEP LEP-Powheg python/merge-LEP LEP-Matchbox python/merge-LEP LEP-Dipole rivet-mkhtml -o Rivet-LEP LEP.yoda:Hw++ LEP-Powheg.yoda:Hw++-Powheg LEP-Matchbox.yoda:Hw++-Matchbox LEP-Dipole.yoda:Hw++-Dipole Rivet-BFactory: $(shell echo Rivet-BFactory{,-Powheg,-Matchbox,-Dipole}-{10.52,10.52-sym,10.54,10.45,10.58}) \ $(shell echo Rivet-BFactory-{Upsilon,Upsilon2,Upsilon4,Tau}) rm -rf Rivet-BFactory python/merge-BFactory BFactory python/merge-BFactory BFactory-Powheg python/merge-BFactory BFactory-Matchbox python/merge-BFactory BFactory-Dipole rivet-mkhtml -o Rivet-BFactory BFactory.yoda:Hw++ BFactory-Powheg.yoda:Hw++-Powheg BFactory-Matchbox.yoda:Hw++-Matchbox BFactory-Dipole.yoda:Hw++-Dipole Rivet-DIS: $(shell echo Rivet-DIS{,-NoME,-Powheg,-Matchbox,-Dipole}-{e--LowQ2,e+-LowQ2,e+-HighQ2}) rm -rf Rivet-DIS python/merge-DIS DIS python/merge-DIS DIS-Powheg python/merge-DIS DIS-NoME python/merge-DIS DIS-Matchbox python/merge-DIS DIS-Dipole rivet-mkhtml -o Rivet-DIS DIS.yoda:Hw++ DIS-Powheg.yoda:Hw++-Powheg DIS-NoME.yoda:Hw++-NoME DIS-Matchbox.yoda:Hw++-Matchbox DIS-Dipole.yoda:Hw++-Dipole Rivet-TVT-WZ: $(shell echo Rivet-TVT{,-Powheg,-Matchbox,-Dipole}-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-{e,{,LowMass-,HighMass-}mu},Run-II-W}) rm -rf Rivet-TVT-WZ python/merge-TVT-EW TVT-Run-II-W.yoda TVT-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\ TVT-Run-I-{W,Z,WZ}.yoda -o TVT-WZ.yoda python/merge-TVT-EW TVT-Powheg-Run-II-W.yoda TVT-Powheg-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\ TVT-Powheg-Run-I-{W,Z,WZ}.yoda -o TVT-Powheg-WZ.yoda python/merge-TVT-EW TVT-Matchbox-Run-II-W.yoda TVT-Matchbox-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\ TVT-Matchbox-Run-I-{W,Z,WZ}.yoda -o TVT-Matchbox-WZ.yoda python/merge-TVT-EW TVT-Dipole-Run-II-W.yoda TVT-Dipole-Run-II-Z-{e,{,LowMass-,HighMass-}mu}.yoda\ TVT-Dipole-Run-I-{W,Z,WZ}.yoda -o TVT-Dipole-WZ.yoda rivet-mkhtml -o Rivet-TVT-WZ TVT-WZ.yoda:Hw++ TVT-Powheg-WZ.yoda:Hw++-Powheg TVT-Matchbox-WZ.yoda:Hw++-Matchbox TVT-Dipole-WZ.yoda:Hw++-Dipole -Rivet-TVT-Photon: $(shell echo Rivet-TVT-Run-II-{DiPhoton,PromptPhoton}) -# Rivet-TVT-Run-I-PromptPhoton - rm -rf Rivet-TVT-Photon - cat TVT-Run-II-DiPhoton.yoda TVT-Run-II-PromptPhoton.yoda > TVT-Photon.yoda - rivet-mkhtml -o Rivet-TVT-Photon TVT-Photon.yoda:Hw++ +Rivet-TVT-Photon: $(shell echo Rivet-TVT-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet,PromptPhoton}) \ + $(shell echo Rivet-TVT-Powheg-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}) + rm -rf Rivet-TVT-Photon + python/merge-TVT-Photon TVT -o TVT-Photon.yoda + python/merge-TVT-Photon TVT-Powheg -o TVT-Powheg-Photon.yoda + rivet-mkhtml -o Rivet-TVT-Photon TVT-Photon.yoda:Hw TVT-Powheg-Photon.yoda:Hw-Powheg Rivet-TVT-Jets: $(shell echo Rivet-TVT-{Run-II-Jets-{0..11},Run-I-Jets-{1..8}} ) \ $(shell echo Rivet-TVT-{630-Jets-{1..3},300-Jets-1,900-Jets-1} ) \ $(shell echo Rivet-TVT-{Run-I,Run-II,300,630,900}-UE) python/merge-TVT-Energy TVT rivet-merge-CDF_2012_NOTE10874 TVT-300-Energy.yoda TVT-900-Energy.yoda TVT-1960-Energy.yoda flat2yoda RatioPlots.dat -o TVT-RatioPlots.yoda rm -rf Rivet-TVT-Jets python/merge-TVT-Jets TVT rivet-mkhtml -o Rivet-TVT-Jets TVT-Jets.yoda:Hw++ Rivet-LHC-Jets: $(shell echo Rivet-LHC-7-Jets-{0..15} ) \ $(shell echo Rivet-LHC-{900,2360,2760,7,8,13}-UE ) \ $(shell echo Rivet-LHC-{900,7}-UE-Long ) \ $(shell echo Rivet-LHC-7-Charm-{1..5}) \ $(shell echo Rivet-LHC-7-Bottom-{0..8}) \ $(shell echo Rivet-LHC-7-Top-{L,SL,All}) rm -rf Rivet-LHC-Jets python/merge-LHC-Jets rivet-mkhtml -o Rivet-LHC-Jets LHC-Jets.yoda:Hw++ Rivet-Star: $(shell echo Rivet-Star-{UE,Jets-{1..4}} ) rm -rf Rivet-Star python/merge-Star Star rivet-mkhtml -o Rivet-Star Star.yoda Rivet-SppS: $(shell echo Rivet-ISR-{30,44,53,62}-UE ) \ $(shell echo Rivet-SppS-{53,63,200,500,900,546}-UE ) rm -rf Rivet-SppS python/merge-SppS SppS rivet-mkhtml -o Rivet-SppS SppS.yoda Rivet-LHC-EW: $(shell echo Rivet-LHC{,-Matchbox,-Powheg,-Dipole}-{13-Z-{e,mu},W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,WZ,WW-{emu,ll},ZZ-{ll,lv},W-Z-{e,mu},8-Z-mu}) \ $(shell echo Rivet-LHC{,-Matchbox,-Dipole}-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}) \ $(shell echo Rivet-LHC{-Matchbox,-Dipole}-{Z-b,Z-bb,W-b,8-Z-jj}) rm -rf Rivet-LHC-EW; python/merge-LHC-EW LHC-{13-Z-{e,mu},W-{e,mu},Z-e,Z-mu,Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda LHC-7-{W,Z}-Jet-{1,2,3}-e.yoda -o LHC-EW.yoda; python/merge-LHC-EW LHC-Matchbox-{13-Z-{e,mu},W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda LHC-Matchbox-7-{W,Z}-Jet-{1,2,3}-e.yoda -o LHC-Matchbox-EW.yoda; python/merge-LHC-EW LHC-Dipole-{13-Z-{e,mu},W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda LHC-Dipole-7-{W,Z}-Jet-{1,2,3}-e.yoda -o LHC-Dipole-EW.yoda; python/merge-LHC-EW LHC-Powheg-{W-{e,mu},Z-{e,mu},Z-LowMass-{e,mu},Z-MedMass-e,W-Z-{e,mu},WW-{emu,ll},WZ,ZZ-{ll,lv}}.yoda -o LHC-Powheg-EW.yoda; rivet-mkhtml -o Rivet-LHC-EW LHC-EW.yoda:Hw++ LHC-Powheg-EW.yoda:Hw++-Powheg LHC-Matchbox-EW.yoda:Hw++-Matchbox LHC-Matchbox-Z-b.yoda:Hw++-Matchbox-Zb \ LHC-Matchbox-Z-bb.yoda:Hw++-Matchbox-Zbb LHC-Matchbox-W-b.yoda:Hw++-Matchbox-W-bb LHC-Dipole-EW.yoda:Hw++-Dipole \ LHC-Dipole-Z-b.yoda:Hw++-Dipole-Zb LHC-Dipole-Z-bb.yoda:Hw++-Dipole-Zbb LHC-Dipole-W-b.yoda:Hw++-Dipole-W-bb; -Rivet-LHC-Photon: $(shell echo Rivet-LHC-7-PromptPhoton-{1..4}) \ - Rivet-LHC-7-DiPhoton Rivet-LHC-GammaGamma-7 - rm -rf Rivet-LHC-Photon - python/merge-LHC-Photon -o LHC-Photon.yoda - rivet-mkhtml -o Rivet-LHC-Photon LHC-Photon.yoda:Hw++ +Rivet-LHC-Photon: $(shell echo Rivet-LHC-7-PromptPhoton-{1..4}) Rivet-LHC-GammaGamma-7 \ + $(shell echo Rivet-LHC{,-Powheg}-7-{DiPhoton-GammaGamma,DiPhoton-GammaJet}) + rm -rf Rivet-LHC-Photon + python/merge-LHC-Photon LHC -o LHC-Photon.yoda + python/merge-LHC-Photon LHC-Powheg -o LHC-Powheg-Photon.yoda + rivet-mkhtml -o Rivet-LHC-Photon LHC-Photon.yoda:Hw LHC-Powheg-Photon.yoda:Hw-Powheg Rivet-LHC-Higgs: $(shell echo Rivet-LHC{,-Powheg}-{ggH,VBF,WH,ZH})\ $(shell echo Rivet-LHC{,-Powheg}-8-{ggH,VBF,WH,ZH}{,-GammaGamma}) Rivet-LHC-ggHJet rm -rf Rivet-LHC-Higgs rivet-mkhtml -o Rivet-LHC-Higgs LHC-Powheg-ggH.yoda:gg-Powheg LHC-ggH.yoda:gg LHC-ggHJet.yoda:HJet \ LHC-Powheg-VBF.yoda:VBF-Powheg LHC-VBF.yoda:VBF LHC-WH.yoda:WH LHC-ZH.yoda:ZH \ LHC-Powheg-WH.yoda:WH-Powheg LHC-Powheg-ZH.yoda:ZH-Powheg tests-Rivet : Rivet-LEP Rivet-BFactory Rivet-DIS Rivet-TVT-WZ Rivet-TVT-Photon Rivet-TVT-Jets Rivet-LHC-Jets Rivet-Star Rivet-SppS Rivet-LHC-EW Rivet-LHC-Photon test-Gamma-% : Inputs/Gamma-%.in GammaTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} test-DIS-% : Inputs/DIS-%.in DISTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} if WANT_LIBFASTJET test-LHC-% : Inputs/LHC-%.in HadronTest.la GammaTest.la HadronJetTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} else test-LHC-% : Inputs/LHC-%.in HadronTest.la GammaTest.la $(HWREAD) $< $(HWRUN) $(notdir $(subst .in,.run,$<)) -N $${NUMEVENTS:-10000} endif clean-local: rm -f *.out *.log *.tex *.top *.run *.dump *.mult *.Bmult *.yoda diff --git a/Tests/python/make_input_files.py b/Tests/python/make_input_files.py --- a/Tests/python/make_input_files.py +++ b/Tests/python/make_input_files.py @@ -1,1318 +1,1356 @@ #! /usr/bin/env python import logging,sys,os from string import strip, Template import sys if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog name [...]") (opts, args) = parser.parse_args() ## Check args if len(args) != 1: logging.error("Must specify at least input file") sys.exit(1) name=args[0] collider="" # select the template to load # collider parameters = {} if(name.find("BFactory")==0) : collider="BFactory" elif(name.find("LEP")==0) : collider="LEP" elif(name.find("DIS")==0) : collider="DIS" elif(name.find("TVT")==0) : collider="TVT" elif(name.find("LHC-GammaGamma")==0) : collider="LHC-GammaGamma" elif(name.find("LHC")==0) : collider="LHC" elif(name.find("ISR")==0) : collider="ISR" elif(name.find("SppS")==0) : collider="SppS" elif(name.find("Star")==0) : collider="Star" simulation="" istart = 1 print name if(name.find("Matchbox-Powheg")>0) : istart = 3 simulation="Matchbox" parameters["shower"] = "read Matchbox/Powheg-DefaultShower.in\n" elif(name.find("Matchbox")>0) : istart = 2 simulation="Matchbox" parameters["shower"] = "read Matchbox/MCatNLO-DefaultShower.in\n" elif(name.find("Dipole")>0) : istart = 2 simulation="Matchbox" parameters["shower"] = "read Matchbox/MCatNLO-DipoleShower.in\n" elif(name.find("Powheg")>0) : istart = 2 simulation="Powheg" if(simulation=="Matchbox") : parameters["bscheme"] = "read Matchbox/FiveFlavourScheme.in\n" if(parameters["shower"].find("Dipole")>=0) : parameters["bscheme"] += "read Matchbox/FiveFlavourNoBMassScheme.in\n" if(collider.find("DIS")<0) : parameters["nlo"] = "read Matchbox/MadGraph-OpenLoops.in\n" if(collider=="") : logging.error("Can\'t find collider") sys.exit(1) # find the template if(simulation=="") : if(collider.find("LHC-GammaGamma") >=0) : istart += 1 templateName="Hadron-Gamma.in" elif(collider.find("TVT")>=0 or collider.find("LHC") >=0 or collider.find("ISR")>=0 or collider.find("SppS")>=0 or collider.find("Star")>=0) : templateName="Hadron.in" elif(collider.find("BFactory")<0) : templateName= "%s.in" % (collider) else : templateName= "LEP.in" else : if(collider.find("TVT")>=0 or collider.find("LHC") >=0 or collider.find("ISR")>=0 or collider.find("SppS")>=0 or collider.find("Star")>=0) : templateName= "Hadron-%s.in" % (simulation) elif(collider.find("BFactory")<0) : templateName= "%s-%s.in" % (collider,simulation) else : templateName= "LEP-%s.in" % (simulation) with open(os.path.join("Rivet/Templates",templateName), 'r') as f: templateText = f.read() template = Template( templateText ) # work out the name of the parameter file nameSplit=name.split("-") parameterName=nameSplit[istart] for i in range(istart+1,len(nameSplit)) : parameterName += "-%s" % nameSplit[i] # work out the process and parameters process="" # Bfactory if(collider=="BFactory") : if(simulation=="") : process = "set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 4" if(parameterName=="10.58") : process += "\ncreate Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so\nset /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)\nset /Herwig/MatrixElements/MEUpsilon:Coupling 0.0004151809\ninsert /Herwig/MatrixElements/SimpleEE:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon" elif(simulation=="Powheg") : process = "set /Herwig/MatrixElements/PowhegMEee2gZ2qq:MaximumFlavour 4" if(parameterName=="10.58") : process += "\ncreate Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so\nset /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)\nset /Herwig/MatrixElements/MEUpsilon:Coupling 0.0004151809\ninsert /Herwig/MatrixElements/SimpleEE:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon" elif(simulation=="Matchbox" ) : process = "do Factory:Process e- e+ -> u ubar\ndo Factory:Process e- e+ -> d dbar\ndo Factory:Process e- e+ -> c cbar\ndo Factory:Process e- e+ -> s sbar" if(parameterName=="10.58") : process += "\ninsert /Herwig/Generators/EventGenerator:EventHandler:SubProcessHandlers 0 /Herwig/MatrixElements/SimpleEE\ncreate Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so\nset /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)\nset /Herwig/MatrixElements/MEUpsilon:Coupling 0.0004151809\ninsert /Herwig/MatrixElements/SimpleEE:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon\n" # DIS elif(collider=="DIS") : if(simulation=="") : if(parameterName.find("NoME")>=0) : process = "set /Herwig/Shower/Evolver:MECorrMode 0" parameterName=parameterName.replace("NoME-","") else : process = "" elif(simulation=="Powheg") : process = "" elif(simulation=="Matchbox" ) : if(parameterName.find("e-")>=0) : process="do Factory:Process e- p -> e- j" else : process="do Factory:Process e+ p -> e+ j" # LEP elif(collider=="LEP") : if(simulation=="") : process="" if(parameterName=="10") : process="set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 4" elif(simulation=="Powheg") : process="" if(parameterName=="10") : process="set /Herwig/MatrixElements/PowhegMEee2gZ2qq:MaximumFlavour 4" elif(simulation=="Matchbox" ) : if(parameterName=="10") : process="do Factory:Process e- e+ -> u ubar\ndo Factory:Process e- e+ -> d dbar\ndo Factory:Process e- e+ -> c cbar\ndo Factory:Process e- e+ -> s sbar" else : process="do Factory:Process e- e+ -> j j" # TVT elif(collider=="TVT") : process="set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n" if(parameterName.find("Run-II")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 1960.0\n" elif(parameterName.find("Run-I")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 1800.0\n" elif(parameterName.find("900")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 900.0\n" elif(parameterName.find("630")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 630.0\n" elif(parameterName.find("300")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 300.0\n" if(simulation=="") : if(parameterName.find("PromptPhoton")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n" process+="set /Herwig/Cuts/PhotonKtCut:MinKT 15.\n" - elif(parameterName.find("DiPhoton")>=0) : + elif(parameterName.find("DiPhoton-GammaGamma")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n" process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaGamma","") + elif(parameterName.find("DiPhoton-GammaJet")>=0) : + process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n" + process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaJet","") elif(parameterName.find("UE")>=0) : process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n" process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n" process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n" process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n" process += "set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n" process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n" elif(parameterName.find("Jets")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEQCD2to2\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if(parameterName.find("Run-II-Jets-10")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 500.*GeV\n" elif(parameterName.find("Run-II-Jets-11")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 900.*GeV\n" elif(parameterName.find("Run-I-Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" elif(parameterName.find("Run-I-Jets-2")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n" elif(parameterName.find("Run-I-Jets-3")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 65.\n" elif(parameterName.find("Run-I-Jets-4")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 90.\n" elif(parameterName.find("Run-I-Jets-5")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 160.\n" elif(parameterName.find("Run-I-Jets-6")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 100.*GeV\n" elif(parameterName.find("Run-I-Jets-7")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 400.*GeV\n" elif(parameterName.find("Run-I-Jets-8")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 700.*GeV\n" elif(parameterName.find("Run-II-Jets-0")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 15.\n" elif(parameterName.find("Run-II-Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 25.\n" elif(parameterName.find("Run-II-Jets-2")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n" elif(parameterName.find("Run-II-Jets-3")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 60.\n" elif(parameterName.find("Run-II-Jets-4")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 85.\n" elif(parameterName.find("Run-II-Jets-5")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 110.\n" elif(parameterName.find("Run-II-Jets-6")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 160.\n" elif(parameterName.find("Run-II-Jets-7")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 250.\n" elif(parameterName.find("Run-II-Jets-8")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 100.*GeV\n" elif(parameterName.find("Run-II-Jets-9")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 300.*GeV\n" elif(parameterName.find("900-Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 10.\n" elif(parameterName.find("300-Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 6.\n" elif(parameterName.find("630-Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" elif(parameterName.find("630-Jets-2")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n" elif(parameterName.find("630-Jets-3")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 75.\n" elif(parameterName.find("900-Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 10.\n" elif(parameterName.find("Run-I-WZ")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\ninsert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n" elif(parameterName.find("Run-I-W")>=0 or parameterName.find("Run-II-W")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\n" elif(parameterName.find("Run-I-Z")>=0 or parameterName.find("Run-II-Z-e")>=0) : process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n" elif(parameterName.find("Run-II-Z-LowMass-mu")>=0) : process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 25*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n" elif(parameterName.find("Run-II-Z-HighMass-mu")>=0) : process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 150*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 600*GeV\n" elif(parameterName.find("Run-II-Z-mu")>=0) : process +="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n" elif(simulation=="Powheg") : if(parameterName.find("Run-I-WZ")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\ninsert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n" elif(parameterName.find("Run-I-W")>=0 or parameterName.find("Run-II-W")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\n" elif(parameterName.find("Run-I-Z")>=0 or parameterName.find("Run-II-Z-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n" elif(parameterName.find("Run-II-Z-LowMass-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 25*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n" elif(parameterName.find("Run-II-Z-HighMass-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 150*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 600*GeV\n" elif(parameterName.find("Run-II-Z-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n" + elif(parameterName.find("DiPhoton-GammaGamma")>=0) : + process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n" + process+="set MEGammaGammaPowheg:Process GammaGamma\n" + process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n" + process+="set MEGammaGamma:Process gg\n" + process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaGamma","") + elif(parameterName.find("DiPhoton-GammaJet")>=0) : + process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n" + process+="set MEGammaGammaPowheg:Process VJet\n" + process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaJet","") elif(simulation=="Matchbox" ) : if(parameterName.find("Jets")>=0) : process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n" process+="do Factory:Process p p j j\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if(parameterName.find("Run-II-Jets-10")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 500.*GeV\n" elif(parameterName.find("Run-II-Jets-11")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 900.*GeV\n" elif(parameterName.find("Run-II-Jets-12")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 300.*GeV\n" elif(parameterName.find("Run-I-Jets-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n" elif(parameterName.find("Run-I-Jets-2")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n" elif(parameterName.find("Run-I-Jets-3")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 65.\n" elif(parameterName.find("Run-I-Jets-4")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 90.\n" elif(parameterName.find("Run-I-Jets-5")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 160.\n" elif(parameterName.find("Run-I-Jets-6")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 100.*GeV\n" elif(parameterName.find("Run-I-Jets-7")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 400.*GeV\n" elif(parameterName.find("Run-I-Jets-8")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 700.*GeV\n" elif(parameterName.find("Run-II-Jets-0")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 15.\n" elif(parameterName.find("Run-II-Jets-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 25.\n" elif(parameterName.find("Run-II-Jets-2")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n" elif(parameterName.find("Run-II-Jets-3")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 60.\n" elif(parameterName.find("Run-II-Jets-4")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 85.\n" elif(parameterName.find("Run-II-Jets-5")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 110.\n" elif(parameterName.find("Run-II-Jets-6")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 160.\n" elif(parameterName.find("Run-II-Jets-7")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 250.\n" elif(parameterName.find("Run-II-Jets-8")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 100.*GeV\n" elif(parameterName.find("Run-II-Jets-9")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 300.*GeV\n" elif(parameterName.find("900-Jets-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 10.\n" elif(parameterName.find("300-Jets-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 6.\n" elif(parameterName.find("630-Jets-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n" elif(parameterName.find("630-Jets-2")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n" elif(parameterName.find("630-Jets-3")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 75.\n" elif(parameterName.find("900-Jets-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 10.\n" elif(parameterName.find("Run-I-WZ")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar e+ e-\ndo Factory:Process p pbar e+ nu\ndo Factory:Process p pbar e- nu\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Run-I-W")>=0 or parameterName.find("Run-II-W")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar e+ nu\ndo Factory:Process p pbar e- nu\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Run-I-Z")>=0 or parameterName.find("Run-II-Z-e")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Run-II-Z-LowMass-mu")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 25*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n" elif(parameterName.find("Run-II-Z-HighMass-mu")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 150.*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 600*GeV\n" elif(parameterName.find("Run-II-Z-mu")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p pbar mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" # Star elif(collider=="Star" ) : process = "set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n" process+= "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n" process+= "set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/p+\n" process+= "set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 200.0\n" process+= "set /Herwig/Cuts/QCDCuts:X2Min 0.01\n" if(simulation=="") : if(parameterName.find("UE")>=0) : process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n" process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n" process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n" process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n" else : process+="insert SimpleQCD:MatrixElements[0] MEQCD2to2\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if(parameterName.find("Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 2.\n" elif(parameterName.find("Jets-2")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n" elif(parameterName.find("Jets-3")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" elif(parameterName.find("Jets-4")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 25.\n" else : logging.error("Star not supported for %s " % simulation) sys.exit(1) # ISR and SppS elif(collider=="ISR" or collider =="SppS" ) : process="set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n" process+="set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n" if(collider=="SppS") : process ="set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n" if(parameterName.find("30")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 30.4\n" elif(parameterName.find("44")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 44.4\n" elif(parameterName.find("53")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 53.0\n" elif(parameterName.find("62")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 62.2\n" elif(parameterName.find("63")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 63.0\n" elif(parameterName.find("200")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 200.0\n" elif(parameterName.find("500")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 500.0\n" elif(parameterName.find("546")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 546.0\n" elif(parameterName.find("900")>=0) : process+="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 900.0\n" if(simulation=="") : process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n" process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n" process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n" process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n" else : logging.error(" SppS and ISR not supported for %s " % simulation) sys.exit(1) # LHC elif(collider=="LHC") : if(parameterName.find("7-")==0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n" elif(parameterName.find("8-")==0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 8000.0\n" elif(parameterName.find("13-")==0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 13000.0\n" elif(parameterName.find("900")==0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 900.0\n" elif(parameterName.find("2360")==0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 2360.0\n" elif(parameterName.find("2760")==0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 2760.0\n" else : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n" if(simulation=="") : if(parameterName.find("8-VBF")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2HiggsVBF\n" elif(parameterName.find("VBF")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" process+="insert SimpleQCD:MatrixElements[0] MEPP2HiggsVBF\n" elif(parameterName.find("ggHJet")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" process+="insert SimpleQCD:MatrixElements[0] MEHiggsJet\n" elif(parameterName.find("8-ggH")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEHiggs\n" process+="insert SimpleQCD:MatrixElements[0] MEHiggsJet\n" process+="set MEHiggsJet:Process qqbar\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("ggH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" process+="insert SimpleQCD:MatrixElements[0] MEHiggs\n" process+="insert SimpleQCD:MatrixElements[0] MEHiggsJet\n" process+="set MEHiggsJet:Process qqbar\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("PromptPhoton")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n" if(parameterName.find("PromptPhoton-1")>=0) : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" elif(parameterName.find("PromptPhoton-2")>=0) : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 25.\n" elif(parameterName.find("PromptPhoton-3")>=0) : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 80.\n" elif(parameterName.find("PromptPhoton-4")>=0) : process+="set /Herwig/Cuts/PhotonKtCut:MinKT 150.\n" - elif(parameterName.find("DiPhoton")>=0) : + elif(parameterName.find("DiPhoton-GammaGamma")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n" process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaGamma","") + elif(parameterName.find("DiPhoton-GammaJet")>=0) : + process+="insert SimpleQCD:MatrixElements[0] MEGammaJet\n" + process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaJet","") elif(parameterName.find("8-WH")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2WH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("8-ZH")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2ZH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("WH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n" process+="do /Herwig/Particles/W+:SelectDecayModes W+->nu_e,e+; W+->nu_mu,mu+;\n" process+="insert SimpleQCD:MatrixElements[0] MEPP2WH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("ZH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n" process+="do /Herwig/Particles/Z0:SelectDecayModes Z0->e-,e+; Z0->mu-,mu+;\n" process+="insert SimpleQCD:MatrixElements[0] MEPP2ZH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("UE")>=0) : process += "insert SimpleQCD:MatrixElements[0] MEMinBias\n" process += "set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" process += "set /Herwig/Generators/EventGenerator:EventHandler:Cuts /Herwig/Cuts/MinBiasCuts\n" process += "create Herwig::MPIXSecReweighter /Herwig/Generators/MPIXSecReweighter\n" process += "insert /Herwig/Generators/EventGenerator:EventHandler:PostSubProcessHandlers 0 /Herwig/Generators/MPIXSecReweighter\n" if(parameterName.find("Long")>=0) : process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 100*mm\n" elif(parameterName.find("7-Jets")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEQCD2to2\n" process+="set MEQCD2to2:MaximumFlavour 5\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if(parameterName.find("7-Jets-0")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n" elif(parameterName.find("7-Jets-10")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 200.*GeV\n" elif(parameterName.find("7-Jets-11")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 600.*GeV\n" elif(parameterName.find("7-Jets-12")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 1000.*GeV\n" elif(parameterName.find("7-Jets-13")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 1600.*GeV\n" elif(parameterName.find("7-Jets-14")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 2200.*GeV\n" elif(parameterName.find("7-Jets-15")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 2800.*GeV\n" elif(parameterName.find("7-Jets-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 10.\n" elif(parameterName.find("7-Jets-2")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" elif(parameterName.find("7-Jets-3")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 40.\n" elif(parameterName.find("7-Jets-4")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 70.\n" elif(parameterName.find("7-Jets-5")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 150.\n" elif(parameterName.find("7-Jets-6")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 200.\n" elif(parameterName.find("7-Jets-7")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 300.\n" elif(parameterName.find("7-Jets-8")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 500.\n" elif(parameterName.find("7-Jets-9")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 90.*GeV\n" elif(parameterName.find("7-Charm")>=0 or \ parameterName.find("7-Bottom")>=0) : if(parameterName.find("7-Bottom")>=0) : process+="cp MEHeavyQuark MEBottom\n" process+="set MEBottom:QuarkType Bottom\n" process+="insert SimpleQCD:MatrixElements[0] MEBottom\n" else : process+="cp MEHeavyQuark MECharm\n" process+="set MECharm:QuarkType Charm\n" process+="insert SimpleQCD:MatrixElements[0] MECharm\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if(parameterName.find("7-Heavy-0")>=0) : if(parameterName.find("7-Bottom")>=0) : process+="set MEBottom:Process Pair\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.\n" elif(parameterName.find("-1")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n" elif(parameterName.find("-2")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 20.\n" elif(parameterName.find("-3")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 50.\n" elif(parameterName.find("-4")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 80.\n" elif(parameterName.find("-5")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 110.\n" elif(parameterName.find("-6")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 90.*GeV\n" elif(parameterName.find("-7")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 340.*GeV\n" elif(parameterName.find("-8")>=0) : process+="set /Herwig/Cuts/JetKtCut:MinKT 30.\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 500.*GeV\n" elif(parameterName.find("7-Top-L")>=0) : process+="set MEHeavyQuark:QuarkType Top\n" process+="insert SimpleQCD:MatrixElements[0] MEHeavyQuark\n" process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("7-Top-SL")>=0) : process+="set MEHeavyQuark:QuarkType Top\n" process+="insert SimpleQCD:MatrixElements[0] MEHeavyQuark\n" process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n" process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n" process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n" process+="do /Herwig/Particles/tbar:SelectDecayModes tbar->b,bbar,cbar; tbar->bbar,cbar,d; tbar->bbar,cbar,s; tbar->bbar,s,ubar; tbar->bbar,ubar,d;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("7-Top-All")>=0) : process+="set MEHeavyQuark:QuarkType Top\n" process+="insert SimpleQCD:MatrixElements[0] MEHeavyQuark\n" elif(parameterName.find("WZ")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process WZ\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+;\n" process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_ebar,e-; /Herwig/Particles/W-/W-->nu_mubar,mu-;\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("WW-emu")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process WW\n" process+="set /Herwig/Particles/W+:Synchronized 0\n" process+="set /Herwig/Particles/W-:Synchronized 0\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+;\n" process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_mubar,mu-;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("WW-ll")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process WW\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+; /Herwig/Particles/W+/W+->nu_tau,tau+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("ZZ-ll")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process ZZ\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("ZZ-lv")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEPP2VV\nset MEPP2VV:Process ZZ\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+; /Herwig/Particles/Z0/Z0->nu_e,nu_ebar; /Herwig/Particles/Z0/Z0->nu_mu,nu_mubar; /Herwig/Particles/Z0/Z0->nu_tau,nu_taubar;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("W-Z-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n" process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\n" elif(parameterName.find("W-Z-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n" process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Muon\n" elif(parameterName.find("W-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Electron\n" elif(parameterName.find("W-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Muon\n" elif(parameterName.find("Z-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n" elif(parameterName.find("Z-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n" elif(parameterName.find("Z-LowMass-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 20.*GeV\nset /Herwig/Cuts/MassCut:MinM 20.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n" elif(parameterName.find("Z-MedMass-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Electron\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 40.*GeV\nset /Herwig/Cuts/MassCut:MinM 40.*GeV\nset /Herwig/Cuts/MassCut:MaxM 130.*GeV\n" elif(parameterName.find("Z-LowMass-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 10.*GeV\nset /Herwig/Cuts/MassCut:MinM 10.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n" elif(parameterName.find("W-Jet")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEWJet\nset MEWJet:WDecay Electron\n" if(parameterName.find("W-Jet-1-e")>=0) : process+="set /Herwig/Cuts/WBosonKtCut:MinKT 100.0*GeV\n" parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e") elif(parameterName.find("W-Jet-2-e")>=0) : process+="set /Herwig/Cuts/WBosonKtCut:MinKT 190.0*GeV\n" parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e") elif(parameterName.find("W-Jet-3-e")>=0) : process+="set /Herwig/Cuts/WBosonKtCut:MinKT 270.0*GeV\n" parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e") elif(parameterName.find("Z-Jet")>=0) : if(parameterName.find("-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEZJet\nset MEZJet:ZDecay Electron\n" if(parameterName.find("Z-Jet-0-e")>=0) : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n" parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e") elif(parameterName.find("Z-Jet-1-e")>=0) : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 100.0*GeV\n" parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e") elif(parameterName.find("Z-Jet-2-e")>=0) : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 190.0*GeV\n" parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e") elif(parameterName.find("Z-Jet-3-e")>=0) : process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 270.0*GeV\n" parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e") else : process+="insert SimpleQCD:MatrixElements[0] MEZJet\nset MEZJet:ZDecay Muon\n" process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n" parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu") else : logging.error(" Process %s not supported for internal matrix elements" % name) sys.exit(1) elif(simulation=="Powheg") : if(parameterName.find("8-VBF")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2HiggsVBF\n" elif(parameterName.find("VBF")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2HiggsVBF\n" elif(parameterName.find("ggHJet")>=0) : logging.error(" Process %s not supported for POWHEG matrix elements" % name) sys.exit(1) elif(parameterName.find("8-ggH")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEHiggs\n" elif(parameterName.find("ggH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEHiggs\n" elif(parameterName.find("8-WH")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2WH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("8-ZH")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2ZH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("WH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n" process+="do /Herwig/Particles/W+:SelectDecayModes W+->nu_e,e+; W+->nu_mu,mu+;\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2WH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("ZH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n" process+="do /Herwig/Particles/Z0:SelectDecayModes Z0->e-,e+; Z0->mu-,mu+;\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2ZH\n" process+="set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV\n" elif(parameterName.find("UE")>=0) : logging.error(" Process %s not supported for powheg matrix elements" % name) sys.exit(1) elif(parameterName.find("WZ")>=0) : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process WZ\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+;\n" process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_ebar,e-; /Herwig/Particles/W-/W-->nu_mubar,mu-;\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("WW-emu")>=0) : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process WW\n" process+="set /Herwig/Particles/W+:Synchronized 0\n" process+="set /Herwig/Particles/W-:Synchronized 0\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+;\n" process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_mubar,mu-;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("WW-ll")>=0) : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process WW\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+; /Herwig/Particles/W+/W+->nu_tau,tau+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("ZZ-ll")>=0) : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process ZZ\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("ZZ-lv")>=0) : process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n" process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n" process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEPP2VV\nset PowhegMEPP2VV:Process ZZ\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+; /Herwig/Particles/Z0/Z0->nu_e,nu_ebar; /Herwig/Particles/Z0/Z0->nu_mu,nu_mubar; /Herwig/Particles/Z0/Z0->nu_tau,nu_taubar;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("W-Z-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n" process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\n" elif(parameterName.find("W-Z-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] MEqq2gZ2ff\nset MEqq2gZ2ff:Process Muon\n" process+="insert SimpleQCD:MatrixElements[0] MEqq2W2ff\nset MEqq2W2ff:Process Muon\n" elif(parameterName.find("W-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Electron\n" elif(parameterName.find("W-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2W2ff\nset PowhegMEqq2W2ff:Process Muon\n" elif(parameterName.find("Z-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n" elif(parameterName.find("Z-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n" elif(parameterName.find("Z-LowMass-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 20.*GeV\nset /Herwig/Cuts/MassCut:MinM 20.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n" elif(parameterName.find("Z-MedMass-e")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Electron\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 40.*GeV\nset /Herwig/Cuts/MassCut:MinM 40.*GeV\nset /Herwig/Cuts/MassCut:MaxM 130.*GeV\n" elif(parameterName.find("Z-LowMass-mu")>=0) : process+="insert SimpleQCD:MatrixElements[0] PowhegMEqq2gZ2ff\nset PowhegMEqq2gZ2ff:Process Muon\n" process+="set /Herwig/Cuts/QCDCuts:MHatMin 10.*GeV\nset /Herwig/Cuts/MassCut:MinM 10.*GeV\nset /Herwig/Cuts/MassCut:MaxM 70.*GeV\n" + elif(parameterName.find("DiPhoton-GammaGamma")>=0) : + process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n" + process+="set MEGammaGammaPowheg:Process GammaGamma\n" + process+="insert SimpleQCD:MatrixElements[0] MEGammaGamma\n" + process+="set MEGammaGamma:Process gg\n" + process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaGamma","") + elif(parameterName.find("DiPhoton-GammaJet")>=0) : + process+="insert SimpleQCD:MatrixElements[0] MEGammaGammaPowheg\n" + process+="set MEGammaGammaPowheg:Process VJet\n" + process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n" + process+="set /Herwig/Cuts/JetKtCut:MinKT 5.\n" + parameterName=parameterName.replace("-GammaJet","") else : logging.error(" Process %s not supported for internal POWHEG matrix elements" % name) sys.exit(1) elif(simulation=="Matchbox" ) : if(parameterName.find("8-VBF")>=0) : parameters["nlo"] = "read Matchbox/VBFNLO.in\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/Z0\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W+\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W-\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/gamma\n" process+="do Factory:DiagramGenerator:TimeLikeRange 0 0\n" process+="do Factory:Process p p h0 j j\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif(parameterName.find("VBF")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" parameters["nlo"] = "read Matchbox/VBFNLO.in\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/Z0\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W+\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/W-\n" process+="insert Factory:DiagramGenerator:RestrictLines 0 /Herwig/Particles/gamma\n" process+="do Factory:DiagramGenerator:TimeLikeRange 0 0\n" process+="do Factory:Process p p h0 j j\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif(parameterName.find("ggHJet")>=0) : parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n" process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" process+="set Factory:OrderInAlphaS 3\nset Factory:OrderInAlphaEW 1\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="do Factory:Process p p h0 j\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif(parameterName.find("8-ggH")>=0) : parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n" process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 1\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="do Factory:Process p p h0\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif(parameterName.find("ggH")>=0) : parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n" process+="do /Herwig/Particles/h0:SelectDecayModes h0->tau-,tau+;\n" process+="set /Herwig/Particles/tau-:Stable Stable\n" process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 1\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="do Factory:Process p p h0\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif(parameterName.find("8-WH")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="do Factory:Process p p W+ h0\n" process+="do Factory:Process p p W- h0\n" process+="set /Herwig/Particles/W+:HardProcessWidth 0.\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif(parameterName.find("8-ZH")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="set /Herwig/Particles/Z0:HardProcessWidth 0.\n" process+="do Factory:Process p p Z0 h0\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n" elif(parameterName.find("WH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="do Factory:Process p p e+ nu h0\n" process+="do Factory:Process p p e- nu h0\n" process+="do Factory:Process p p mu+ nu h0\n" process+="do Factory:Process p p mu- nu h0\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("ZH")>=0) : process+="do /Herwig/Particles/h0:SelectDecayModes h0->b,bbar;\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 3\n" process+="set /Herwig/Particles/h0:HardProcessWidth 0.\n" process+="do Factory:Process p p e+ e- h0\n" process+="do Factory:Process p p mu+ mu- h0\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("UE")>=0) : logging.error(" Process %s not supported for Matchbox matrix elements" % name) sys.exit(1) elif(parameterName.find("7-Jets")>=0) : process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n" process+="do Factory:Process p p j j\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if(parameterName.find("7-Jets-0")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 5.\n" elif(parameterName.find("7-Jets-10")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 200.*GeV\n" elif(parameterName.find("7-Jets-11")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 600.*GeV\n" elif(parameterName.find("7-Jets-12")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 1000.*GeV\n" elif(parameterName.find("7-Jets-13")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 1600.*GeV\n" elif(parameterName.find("7-Jets-14")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 2200.*GeV\n" elif(parameterName.find("7-Jets-15")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 2800.*GeV\n" elif(parameterName.find("7-Jets-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 10.\n" elif(parameterName.find("7-Jets-2")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n" elif(parameterName.find("7-Jets-3")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 40.\n" elif(parameterName.find("7-Jets-4")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 70.\n" elif(parameterName.find("7-Jets-5")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 150.\n" elif(parameterName.find("7-Jets-6")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 200.\n" elif(parameterName.find("7-Jets-7")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 300.\n" elif(parameterName.find("7-Jets-8")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 500.\n" elif(parameterName.find("7-Jets-9")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 20.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 90.*GeV\n" elif(parameterName.find("7-Charm")>=0 or \ parameterName.find("7-Bottom")>=0) : parameters["bscheme"]="read Matchbox/FourFlavourScheme.in" process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\n" process+="set /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n" process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n" if(parameterName.find("7-Bottom")>=0) : process+="do Factory:Process p p b bbar\n" else: process+="do Factory:Process p p c cbar\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/MaxJetPtScale\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n" if(parameterName.find("-0")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 0.\n" elif(parameterName.find("-1")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 5.\n" elif(parameterName.find("-2")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 20.\n" elif(parameterName.find("-3")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 50.\n" elif(parameterName.find("-4")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 80.\n" elif(parameterName.find("-5")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 110.\n" elif(parameterName.find("-6")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 90.*GeV\n" elif(parameterName.find("-7")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 340.*GeV\n" elif(parameterName.find("-8")>=0) : process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.\n" process+="set /Herwig/Cuts/SecondJet:PtMin 25.\n" process+="create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so\n" process+="set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet\n" process+="insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass\n" process+="set /Herwig/Cuts/JetPairMass:MassMin 500.*GeV\n" elif(parameterName.find("7-Top-L")>=0) : process+="set /Herwig/Particles/t:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/tbar:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n" process+="do Factory:Process p p t tbar\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/TopPairMTScale\n" process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("7-Top-SL")>=0) : process+="set /Herwig/Particles/t:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/tbar:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n" process+="do Factory:Process p p t tbar\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/TopPairMTScale\n" process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n" process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n" process+="do /Herwig/Particles/t:SelectDecayModes t->nu_e,e+,b; t->nu_mu,mu+,b;\n" process+="do /Herwig/Particles/tbar:SelectDecayModes tbar->b,bbar,cbar; tbar->bbar,cbar,d; tbar->bbar,cbar,s; tbar->bbar,s,ubar; tbar->bbar,ubar,d;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" elif(parameterName.find("7-Top-All")>=0) : process+="set /Herwig/Particles/t:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/tbar:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 0\n" process+="do Factory:Process p p t tbar\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/TopPairMTScale\n" elif(parameterName.find("WZ")>=0) : process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p W+ Z0\ndo Factory:Process p p W- Z0\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 171.6*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+;\n" process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_ebar,e-; /Herwig/Particles/W-/W-->nu_mubar,mu-;\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("WW-emu")>=0) : process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p W+ W-\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/Particles/W+:Synchronized 0\n" process+="set /Herwig/Particles/W-:Synchronized 0\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+;\n" process+="do /Herwig/Particles/W-:SelectDecayModes /Herwig/Particles/W-/W-->nu_mubar,mu-;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("WW-ll")>=0) : process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p W+ W-\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="do /Herwig/Particles/W+:SelectDecayModes /Herwig/Particles/W+/W+->nu_e,e+; /Herwig/Particles/W+/W+->nu_mu,mu+; /Herwig/Particles/W+/W+->nu_tau,tau+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("ZZ-ll")>=0) : process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p Z0 Z0\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("ZZ-lv")>=0) : process+="set /Herwig/Particles/W+:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/W-:HardProcessWidth 0.*GeV\n" process+="set /Herwig/Particles/Z0:HardProcessWidth 0.*GeV\n" process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p Z0 Z0\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="do /Herwig/Particles/Z0:SelectDecayModes /Herwig/Particles/Z0/Z0->e-,e+; /Herwig/Particles/Z0/Z0->mu-,mu+; /Herwig/Particles/Z0/Z0->tau-,tau+; /Herwig/Particles/Z0/Z0->nu_e,nu_ebar; /Herwig/Particles/Z0/Z0->nu_mu,nu_mubar; /Herwig/Particles/Z0/Z0->nu_tau,nu_taubar;\n" process+="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n" process+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("W-Z-e")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n" process+="do Factory:Process p p e+ e-\ndo Factory:Process p p e+ nu\ndo Factory:Process p p e- nu\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("W-Z-mu")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\n" process+="do Factory:Process p p mu+ mu-\ndo Factory:Process p p mu+ nu\ndo Factory:Process p p mu- nu\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("W-e")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ nu\ndo Factory:Process p p e- nu\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("W-mu")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p mu+ nu\ndo Factory:Process p p mu- nu\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Z-e")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Z-mu")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Z-jj")>=0) : process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 2\n" process+="do Factory:Process p p e+ e- j j\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 40.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Z-LowMass-e")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 20*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n" elif(parameterName.find("Z-MedMass-e")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 40*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 130*GeV\n" elif(parameterName.find("Z-LowMass-mu")>=0) : process+="set Factory:OrderInAlphaS 0\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p mu+ mu-\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/LeptonPairMassScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 10*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 70*GeV\n" elif(parameterName.find("W-Jet")>=0) : process+="set Factory:OrderInAlphaS 1\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ nu j\ndo Factory:Process p p e- nu j\n\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/HTScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" if(parameterName.find("W-Jet-1-e")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 100.*GeV\n" parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e") elif(parameterName.find("W-Jet-2-e")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 190.0*GeV\n" parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e") elif(parameterName.find("W-Jet-3-e")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 270.0*GeV\n" parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e") elif(parameterName.find("Z-Jet")>=0) : process+="set Factory:OrderInAlphaS 1\nset Factory:OrderInAlphaEW 2\n" if(parameterName.find("-e")>=0) : process+="do Factory:Process p p e+ e- j\n" if(parameterName.find("Z-Jet-0-e")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 35.*GeV\n" parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e") elif(parameterName.find("Z-Jet-1-e")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 100.*GeV\n" parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e") elif(parameterName.find("Z-Jet-2-e")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 190.0*GeV\n" parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e") elif(parameterName.find("Z-Jet-3-e")>=0) : process+="set /Herwig/Cuts/FirstJet:PtMin 270.0*GeV\n" parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e") else : process+="do Factory:Process p p mu+ mu- j\n" process+="set /Herwig/Cuts/FirstJet:PtMin 35.*GeV\n" parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu") process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" process+="set Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/HTScale\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" elif(parameterName.find("Z-bb")>=0) : parameters["bscheme"]="read Matchbox/FourFlavourScheme.in" process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n" process+="set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e- b bbar\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 91.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 66*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 116*GeV\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 18.*GeV\n" process+="set /Herwig/Cuts/SecondJet:PtMin 15.*GeV\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" elif(parameterName.find("Z-b")>=0) : process+="do Factory:StartParticleGroup bjet\n" process+="insert Factory:ParticleGroup 0 /Herwig/Particles/b\n" process+="insert Factory:ParticleGroup 0 /Herwig/Particles/bbar\n" process+="do Factory:EndParticleGroup\n" process+="set Factory:OrderInAlphaS 1\nset Factory:OrderInAlphaEW 2\ndo Factory:Process p p e+ e- bjet\n" process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 91.2*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 15.*GeV\n" elif(parameterName.find("W-b")>=0) : parameters["bscheme"]="read Matchbox/FourFlavourScheme.in" process += "set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n" process += "set Factory:OrderInAlphaS 2\nset Factory:OrderInAlphaEW 2\n" process += "do Factory:Process p p e+ nu b bbar\ndo Factory:Process p p e- nu b bbar\n" process += "do Factory:Process p p mu+ nu b bbar\ndo Factory:Process p p mu- nu b bbar\n" process += "set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 80.4*GeV\nset Factory:ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n" process+="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n" process+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n" process+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n" process+="set /Herwig/Cuts/FirstJet:PtMin 30.*GeV\n" process+="set /Herwig/Cuts/LeptonPairMassCut:MinMass 60*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass 120*GeV\n" else : logging.error(" Process %s not supported for Matchbox matrix elements" % name) sys.exit(1) # Star elif(collider=="LHC-GammaGamma" ) : if(parameterName.find("-7-")>=0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n" elif(parameterName.find("-8-")>=0) : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 8000.0\n" else : process="set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 7000.0\n" if(simulation=="") : if(parameterName.find("7")>=0) : process += "insert SimpleQCD:MatrixElements 0 /Herwig/MatrixElements/MEgg2ff\n" process += "set /Herwig/MatrixElements/MEgg2ff:Process Muon\n" else : logging.error(" Process %s not supported for default matrix elements" % name) sys.exit(1) else : logging.error("LHC-GammaGamma not supported for %s " % simulation) sys.exit(1) parameters['parameterFile'] = os.path.join(collider,collider+"-"+parameterName+".in") parameters['runname'] = name parameters['process'] = process # write the file if(simulation=="Matchbox" ) : with open(os.path.join("Rivet",name+".in") ,'w') as f: f.write( template.substitute(parameters)) else : with open(os.path.join("Rivet",name+".in") ,'w') as f: f.write( template.substitute(parameters)) diff --git a/Tests/python/merge-LHC-Photon b/Tests/python/merge-LHC-Photon --- a/Tests/python/merge-LHC-Photon +++ b/Tests/python/merge-LHC-Photon @@ -1,252 +1,265 @@ #! /usr/bin/env python import logging import sys import os, yoda """%prog Script for merging aida files """ def fillAbove(scale,desthisto, sourcehistosbyptmin): pthigh= 1e100 ptlow =-1e100 for pt, h in sorted(sourcehistosbyptmin.iteritems(),reverse=True): ptlow=pt if(type(desthisto)==yoda.core.Scatter2D) : for i in range(0,h.numPoints) : xMin = h.points[i].x-h.points[i].xErrs.minus if( xMin*scale >= ptlow and xMin*scale < pthigh ) : desthisto.addPoint(h.points[i]) elif(type(desthisto)==yoda.core.Profile1D) : for i in range(0,h.numBins) : if(h.bins[i].xMin*scale >= ptlow and h.bins[i].xMin*scale < pthigh ) : desthisto.bins[i] += h.bins[i] elif(type(desthisto)==yoda.core.Histo1D) : for i in range(0,h.numBins) : if(h.bins[i].xMin*scale >= ptlow and h.bins[i].xMin*scale < pthigh ) : desthisto.bins[i] += h.bins[i] else : logging.error("Can't merge %s, unknown type" % desthisto.path) sys.exit(1) pthigh=pt def mergeByPt(hpath, scale=1.): global inhistos global outhistos try: fillAbove(scale,outhistos[hpath], inhistos[hpath]) except: pass def useOnePt(hpath, ptmin): global inhistos global outhistos try: ## Find best pT_min match ptmins = inhistos[hpath].keys() closest_ptmin = None for ptm in ptmins: if closest_ptmin is None or \ abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)): closest_ptmin = ptm if closest_ptmin != float(ptmin): logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \ "using pTmin=%e instead" % closest_ptmin) outhistos[hpath] = inhistos[hpath][closest_ptmin] except: pass if sys.version_info[:3] < (2,4,0): print "rivet scripts require Python version >= 2.4.0... exiting" sys.exit(1) if __name__ == "__main__": import logging from optparse import OptionParser, OptionGroup parser = OptionParser(usage="%prog aidafile aidafile2 [...]") parser.add_option("-o", "--out", dest="OUTFILE", default="-") verbgroup = OptionGroup(parser, "Verbosity control") verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", default=logging.INFO, help="print debug (very verbose) messages") verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", default=logging.INFO, help="be very quiet") parser.add_option_group(verbgroup) (opts, args) = parser.parse_args() logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") + ## Check args + if len(args) < 1: + logging.error("Must specify at least the name of the files") + sys.exit(1) + files=["-7-PromptPhoton-1.yoda","-7-PromptPhoton-2.yoda", "-7-PromptPhoton-3.yoda","-7-PromptPhoton-4.yoda", - "-7-DiPhoton.yoda","-GammaGamma-7.yoda"] + "-7-DiPhoton-GammaGamma.yoda","-7-DiPhoton-GammaJet.yoda","-GammaGamma-7.yoda"] ## Get histos inhistos = {} outhistos={} for f in files: - file="LHC"+f + file=args[0]+f if not os.access(file, os.R_OK): logging.error("%s can not be read" % file) - break + continue try: aos = yoda.read(file) except: logging.error("%s can not be parsed as XML" % file) break if(file.find("PromptPhoton")>=0) : if(file.find("-7-PromptPhoton-1")>0) : ptmin=0. elif(file.find("-7-PromptPhoton-2")>0) : ptmin=35. elif(file.find("-7-PromptPhoton-3")>0) : ptmin=90. elif(file.find("-7-PromptPhoton-4")>0) : ptmin=170. ## Get histos from this YODA file for aopath, ao in aos.iteritems() : if not inhistos.has_key(aopath): inhistos[aopath] = {} if (aopath.find("CMS_2013_I1258128")>0) : if(aopath.find("d05")>0 or aopath.find("d06")>0 or aopath.find("d07")>0 or aopath.find("d08")>0) : inhistos[aopath][ptmin] = ao else : inhistos[aopath][ptmin] = ao else : ## Get histos from this YODA file for aopath, ao in aos.iteritems() : - outhistos[aopath] = ao - + if(aopath.find("XSEC")>=0 or aopath.find("EVTCOUNT")>=0) : continue + print aopath + if ( aopath in outhistos ) : + aotype = type(ao) + if aotype in (yoda.Counter, yoda.Histo1D, yoda.Histo2D, yoda.Profile1D, yoda.Profile2D): + outhistos[aopath] += ao + else : + quit() + else: + outhistos[aopath] = ao for hpath,hsets in inhistos.iteritems(): if( hpath.find("1263495")>0 or hpath.find("1093738")>0 or hpath.find("921594")>0 or hpath.find("8914702")>0 or hpath.find("1244522")>0 ) : if(type(hsets.values()[0])==yoda.core.Scatter2D) : outhistos[hpath] = yoda.core.Scatter2D(hsets.values()[0].path, hsets.values()[0].title) elif(type(hsets.values()[0])==yoda.core.Profile1D) : outhistos[hpath] = yoda.core.Profile1D(hsets.values()[0].path, hsets.values()[0].title) for i in range(0,hsets.values()[0].numBins) : outhistos[hpath].addBin(hsets.values()[0].bins[i].xMin, hsets.values()[0].bins[i].xMax) elif(type(hsets.values()[0])==yoda.core.Histo1D) : outhistos[hpath] = yoda.core.Histo1D(hsets.values()[0].path, hsets.values()[0].title) for i in range(0,hsets.values()[0].numBins) : outhistos[hpath].addBin(hsets.values()[0].bins[i].xMin, hsets.values()[0].bins[i].xMax) else : logging.error("Histogram %s is of unknown type" % hpath) print hpath,type(hsets.values()[0]) sys.exit(1) logging.info("Processing ATLAS_2013_I1263495") mergeByPt("/ATLAS_2013_I1263495/d01-x01-y01") mergeByPt("/ATLAS_2013_I1263495/d01-x01-y03") useOnePt("/ATLAS_2013_I1263495/d01-x02-y01", "90" ) logging.info("Processing ATLAS_2012_I1093738") mergeByPt("/ATLAS_2012_I1093738/d01-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d02-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d03-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d04-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d05-x01-y01") mergeByPt("/ATLAS_2012_I1093738/d06-x01-y01") logging.info("Processing ATLAS_2011_I921594") mergeByPt("/ATLAS_2011_I921594/d01-x01-y01") mergeByPt("/ATLAS_2011_I921594/d01-x01-y02") mergeByPt("/ATLAS_2011_I921594/d01-x01-y04") mergeByPt("/ATLAS_2011_I921594/d01-x01-y05") logging.info("Processing ATLAS_2010_S8914702") mergeByPt("/ATLAS_2010_S8914702/d01-x01-y01") mergeByPt("/ATLAS_2010_S8914702/d01-x01-y02") mergeByPt("/ATLAS_2010_S8914702/d01-x01-y03") logging.info("Processing CMS_2013_I1258128") useOnePt("/CMS_2013_I1258128/d05-x01-y01", "35" ) useOnePt("/CMS_2013_I1258128/d06-x01-y01", "35" ) useOnePt("/CMS_2013_I1258128/d07-x01-y01", "35" ) useOnePt("/CMS_2013_I1258128/d08-x01-y01", "35" ) logging.info("Processing ATLAS_2013_I1244522") mergeByPt("/ATLAS_2013_I1244522/d01-x01-y01") mergeByPt("/ATLAS_2013_I1244522/d02-x01-y01") useOnePt("/ATLAS_2013_I1244522/d03-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d04-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d05-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d06-x01-y01", "35" ) useOnePt("/ATLAS_2013_I1244522/d07-x01-y01", "35" ) logging.info("Processing /MC_PHOTONJETS") useOnePt("/MC_PHOTONJETS/jet_HT","0") useOnePt("/MC_PHOTONJETS/jet_eta_1","0") useOnePt("/MC_PHOTONJETS/jet_eta_2","0") useOnePt("/MC_PHOTONJETS/jet_eta_3","0") useOnePt("/MC_PHOTONJETS/jet_eta_4","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_1","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_2","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_3","0") useOnePt("/MC_PHOTONJETS/jet_eta_pmratio_4","0") useOnePt("/MC_PHOTONJETS/jet_mass_1","0") useOnePt("/MC_PHOTONJETS/jet_mass_2","0") useOnePt("/MC_PHOTONJETS/jet_mass_3","0") useOnePt("/MC_PHOTONJETS/jet_mass_4","0") useOnePt("/MC_PHOTONJETS/jet_multi_exclusive","0") useOnePt("/MC_PHOTONJETS/jet_multi_inclusive","0") useOnePt("/MC_PHOTONJETS/jet_multi_ratio","0") useOnePt("/MC_PHOTONJETS/jet_pT_1","0") useOnePt("/MC_PHOTONJETS/jet_pT_2","0") useOnePt("/MC_PHOTONJETS/jet_pT_3","0") useOnePt("/MC_PHOTONJETS/jet_pT_4","0") useOnePt("/MC_PHOTONJETS/jet_y_1","0") useOnePt("/MC_PHOTONJETS/jet_y_2","0") useOnePt("/MC_PHOTONJETS/jet_y_3","0") useOnePt("/MC_PHOTONJETS/jet_y_4","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_1","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_2","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_3","0") useOnePt("/MC_PHOTONJETS/jet_y_pmratio_4","0") useOnePt("/MC_PHOTONJETS/jets_dR_12","0") useOnePt("/MC_PHOTONJETS/jets_dR_13","0") useOnePt("/MC_PHOTONJETS/jets_dR_23","0") useOnePt("/MC_PHOTONJETS/jets_deta_12","0") useOnePt("/MC_PHOTONJETS/jets_deta_13","0") useOnePt("/MC_PHOTONJETS/jets_deta_23","0") useOnePt("/MC_PHOTONJETS/jets_dphi_12","0") useOnePt("/MC_PHOTONJETS/jets_dphi_13","0") useOnePt("/MC_PHOTONJETS/jets_dphi_23","0") useOnePt("/MC_PHOTONJETS/photon_jet1_dR","0") useOnePt("/MC_PHOTONJETS/photon_jet1_deta","0") useOnePt("/MC_PHOTONJETS/photon_jet1_dphi","0") useOnePt("/MC_PHOTONJETUE/gammajet-dR","0") useOnePt("/MC_PHOTONJETUE/gammajet-dphi","0") useOnePt("/MC_PHOTONJETUE/trans-maxnchg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-maxnchg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-maxptsum-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-maxptsum-jet","0") useOnePt("/MC_PHOTONJETUE/trans-minnchg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-minnchg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-minptsum-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-minptsum-jet","0") useOnePt("/MC_PHOTONJETUE/trans-nchg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-nchg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-ptavg-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-ptavg-jet","0") useOnePt("/MC_PHOTONJETUE/trans-ptsum-gamma","0") useOnePt("/MC_PHOTONJETUE/trans-ptsum-jet","0") # Choose output file yoda.writeYODA(outhistos,opts.OUTFILE) sys.exit(0) diff --git a/Tests/python/merge-TVT-Photon b/Tests/python/merge-TVT-Photon new file mode 100644 --- /dev/null +++ b/Tests/python/merge-TVT-Photon @@ -0,0 +1,65 @@ +#! /usr/bin/env python +import logging +import sys +import os, yoda + +"""%prog + +Script for merging aida files + +""" + +if sys.version_info[:3] < (2,4,0): + print "rivet scripts require Python version >= 2.4.0... exiting" + sys.exit(1) + +if __name__ == "__main__": + import logging + from optparse import OptionParser, OptionGroup + parser = OptionParser(usage="%prog aidafile aidafile2 [...]") + parser.add_option("-o", "--out", dest="OUTFILE", default="-") + verbgroup = OptionGroup(parser, "Verbosity control") + verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL", + default=logging.INFO, help="print debug (very verbose) messages") + verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL", + default=logging.INFO, help="be very quiet") + parser.add_option_group(verbgroup) + (opts, args) = parser.parse_args() + logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s") + + ## Check args + if len(args) < 1: + logging.error("Must specify at least the name of the files") + sys.exit(1) + +files=["-Run-II-PromptPhoton.yoda", + "-Run-II-DiPhoton-GammaGamma.yoda","-Run-II-DiPhoton-GammaJet.yoda"] + +## Get histos +inhistos = {} +outhistos={} +for f in files: + file=args[0]+f + if not os.access(file, os.R_OK): + logging.error("%s can not be read" % file) + continue + try: + aos = yoda.read(file) + except: + logging.error("%s can not be parsed as XML" % file) + break + ## Get histos from this YODA file + for aopath, ao in aos.iteritems() : + if(aopath.find("XSEC")>=0 or aopath.find("EVTCOUNT")>=0) : continue + if ( aopath in outhistos ) : + aotype = type(ao) + if aotype in (yoda.Counter, yoda.Histo1D, yoda.Histo2D, yoda.Profile1D, yoda.Profile2D): + outhistos[aopath] += ao + else : + quit() + else: + outhistos[aopath] = ao + +# Choose output file +yoda.writeYODA(outhistos,opts.OUTFILE) +sys.exit(0) diff --git a/src/defaults/MatrixElements.in b/src/defaults/MatrixElements.in --- a/src/defaults/MatrixElements.in +++ b/src/defaults/MatrixElements.in @@ -1,254 +1,261 @@ # -*- ThePEG-repository -*- ############################################################################## # Setup of default matrix elements. # # Only one ME is activated by default, but this file lists # some alternatives. All available MEs can be found in the # 'include/Herwig/MatrixElements' subdirectory of your Herwig # installation. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Instead of editing this file directly, you should reset # the matrix elements in your own input files: # # - create your custom SubProcessHandler # - insert the MEs you need # - set your SubProcessHandler instead of the default (see HerwigDefaults.in) ############################################################################## mkdir /Herwig/MatrixElements cd /Herwig/MatrixElements library HwMELepton.so library HwMEHadron.so library HwMEDIS.so ############################################################ # e+e- matrix elements ############################################################ # e+e- > q qbar create Herwig::MEee2gZ2qq MEee2gZ2qq newdef MEee2gZ2qq:MinimumFlavour 1 newdef MEee2gZ2qq:MaximumFlavour 5 newdef MEee2gZ2qq:AlphaQCD /Herwig/Shower/AlphaQCD newdef MEee2gZ2qq:AlphaQED /Herwig/Shower/AlphaQED # e+e- -> l+l- create Herwig::MEee2gZ2ll MEee2gZ2ll newdef MEee2gZ2ll:Allowed Charged set MEee2gZ2ll:AlphaQED /Herwig/Shower/AlphaQED # e+e- -> W+W- ZZ create Herwig::MEee2VV MEee2VV # e+e- -> ZH create Herwig::MEee2ZH MEee2ZH newdef MEee2ZH:Coupling /Herwig/Shower/AlphaQCD # e+e- -> e+e-H/nu_enu_ebarH create Herwig::MEee2HiggsVBF MEee2HiggsVBF ############################################################ # NLO (POWHEG e+e- matrix elements ############################################################ library HwPowhegMELepton.so create Herwig::MEee2gZ2qqPowheg PowhegMEee2gZ2qq newdef PowhegMEee2gZ2qq:MinimumFlavour 1 newdef PowhegMEee2gZ2qq:MaximumFlavour 5 newdef PowhegMEee2gZ2qq:AlphaQCD /Herwig/Shower/AlphaQCD newdef PowhegMEee2gZ2qq:AlphaQED /Herwig/Shower/AlphaQED create Herwig::MEee2gZ2llPowheg PowhegMEee2gZ2ll newdef PowhegMEee2gZ2ll:Allowed Charged set PowhegMEee2gZ2ll:AlphaQED /Herwig/Shower/AlphaQED ############################################################ # hadron-hadron matrix elements ############################################################ ################################### # Electroweak processes ################################### # q qbar -> gamma/Z -> l+l- create Herwig::MEqq2gZ2ff MEqq2gZ2ff newdef MEqq2gZ2ff:Process 3 newdef MEqq2gZ2ff:Coupling /Herwig/Shower/AlphaQCD # q qbar to W -> l nu create Herwig::MEqq2W2ff MEqq2W2ff newdef MEqq2W2ff:Process 2 newdef MEqq2W2ff:Coupling /Herwig/Shower/AlphaQCD # W+jet create Herwig::MEPP2WJet MEWJet newdef MEWJet:WDecay Leptons # Z+jet create Herwig::MEPP2ZJet MEZJet newdef MEZJet:ZDecay ChargedLeptons # PP->WW/WZ/ZZ create Herwig::MEPP2VV MEPP2VV # PP->WZ gamma create Herwig::MEPP2VGamma MEPP2VGamma ################################### # Photon and jet processes ################################### # qqbar/gg -> gamma gamma create Herwig::MEPP2GammaGamma MEGammaGamma # hadron-hadron to gamma+jet create Herwig::MEPP2GammaJet MEGammaJet # QCD 2-to-2 create Herwig::MEQCD2to2 MEQCD2to2 # MinBias create Herwig::MEMinBias MEMinBias ################################### # Heavy Quark ################################### # qqbar/gg -> t tbar create Herwig::MEPP2QQ MEHeavyQuark create Herwig::MEPP2SingleTop MESingleTopTChannel set MESingleTopTChannel:Process tChannel create Herwig::MEPP2SingleTop MESingleTopSChannel set MESingleTopSChannel:Process sChannel create Herwig::MEPP2SingleTop MESingleTopTW set MESingleTopTW:Process tW ################################### # Higgs processes ################################### # hadron-hadron to higgs create Herwig::MEPP2Higgs MEHiggs newdef MEHiggs:ShapeScheme MassGenerator newdef MEHiggs:Process gg newdef MEHiggs:Coupling /Herwig/Shower/AlphaQCD # hadron-hadron to higgs+jet create Herwig::MEPP2HiggsJet MEHiggsJet # PP->ZH create Herwig::MEPP2ZH MEPP2ZH newdef MEPP2ZH:Coupling /Herwig/Shower/AlphaQCD # PP->WH create Herwig::MEPP2WH MEPP2WH newdef MEPP2WH:Coupling /Herwig/Shower/AlphaQCD # PP -> Higgs via VBF create Herwig::MEPP2HiggsVBF MEPP2HiggsVBF newdef MEPP2HiggsVBF:ShowerAlphaQCD /Herwig/Shower/AlphaQCD # PP -> t tbar Higgs create Herwig::MEPP2QQHiggs MEPP2ttbarH newdef MEPP2ttbarH:QuarkType Top # PP -> b bbar Higgs create Herwig::MEPP2QQHiggs MEPP2bbbarH newdef MEPP2bbbarH:QuarkType Bottom ########################################################## # Hadron-Hadron NLO matrix elements in the Powheg scheme ########################################################## library HwPowhegMEHadron.so # q qbar -> gamma/Z -> l+l- create Herwig::MEqq2gZ2ffPowheg PowhegMEqq2gZ2ff newdef PowhegMEqq2gZ2ff:Process 3 newdef PowhegMEqq2gZ2ff:Coupling /Herwig/Shower/AlphaQCD # q qbar to W -> l nu create Herwig::MEqq2W2ffPowheg PowhegMEqq2W2ff newdef PowhegMEqq2W2ff:Process 2 newdef PowhegMEqq2W2ff:Coupling /Herwig/Shower/AlphaQCD # PP->ZH create Herwig::MEPP2ZHPowheg PowhegMEPP2ZH newdef PowhegMEPP2ZH:Coupling /Herwig/Shower/AlphaQCD # PP->WH create Herwig::MEPP2WHPowheg PowhegMEPP2WH newdef PowhegMEPP2WH:Coupling /Herwig/Shower/AlphaQCD # hadron-hadron to higgs create Herwig::MEPP2HiggsPowheg PowhegMEHiggs newdef PowhegMEHiggs:ShapeScheme MassGenerator newdef PowhegMEHiggs:Process gg newdef PowhegMEHiggs:Coupling /Herwig/Shower/AlphaQCD # PP->VV create Herwig::MEPP2VVPowheg PowhegMEPP2VV newdef PowhegMEPP2VV:Coupling /Herwig/Shower/AlphaQCD # PP -> Higgs via VBF create Herwig::MEPP2HiggsVBFPowheg PowhegMEPP2HiggsVBF newdef PowhegMEPP2HiggsVBF:ShowerAlphaQCD /Herwig/Shower/AlphaQCD +# PP -> diphoton NLO +create Herwig::MEPP2GammaGammaPowheg MEGammaGammaPowheg +set MEGammaGammaPowheg:Process 0 +set MEGammaGammaPowheg:Contribution 1 +set MEGammaGammaPowheg:ShowerAlphaQCD /Herwig/Shower/AlphaQCD +set MEGammaGammaPowheg:ShowerAlphaQED /Herwig/Shower/AlphaQED + ########################################################## # DIS matrix elements ########################################################## # neutral current create Herwig::MENeutralCurrentDIS MEDISNC newdef MEDISNC:Coupling /Herwig/Shower/AlphaQCD newdef MEDISNC:Contribution 0 # charged current create Herwig::MEChargedCurrentDIS MEDISCC newdef MEDISCC:Coupling /Herwig/Shower/AlphaQCD newdef MEDISCC:Contribution 0 # neutral current (POWHEG) create Herwig::MENeutralCurrentDIS PowhegMEDISNC newdef PowhegMEDISNC:Coupling /Herwig/Shower/AlphaQCD newdef PowhegMEDISNC:Contribution 1 # charged current (POWHEG) create Herwig::MEChargedCurrentDIS PowhegMEDISCC newdef PowhegMEDISCC:Coupling /Herwig/Shower/AlphaQCD newdef PowhegMEDISCC:Contribution 1 ########################################################## # Gamma-Gamma matrix elements ########################################################## # fermion-antiferimon create Herwig::MEGammaGamma2ff MEgg2ff HwMEGammaGamma.so # W+ W- create Herwig::MEGammaGamma2WW MEgg2WW HwMEGammaGamma.so ########################################################## # Gamma-Hadron matrix elements ########################################################## # gamma parton -> 2 jets create Herwig::MEGammaP2Jets MEGammaP2Jets HwMEGammaHadron.so ########################################################## # Set up the Subprocesses # # For e+e- ########################################################## create ThePEG::SubProcessHandler SimpleEE newdef SimpleEE:PartonExtractor /Herwig/Partons/EEExtractor ########################################################## # For hadron-hadron ########################################################## create ThePEG::SubProcessHandler SimpleQCD newdef SimpleQCD:PartonExtractor /Herwig/Partons/QCDExtractor ########################################################## # For DIS ########################################################## create ThePEG::SubProcessHandler SimpleDIS newdef SimpleDIS:PartonExtractor /Herwig/Partons/DISExtractor