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,1721 +1,1720 @@ // -*- 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 ( ! (isfinite(a) && isfinite(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()) { + for (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");