Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc b/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
--- a/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
@@ -1,896 +1,896 @@
// -*- C++ -*-
//
// MatchboxAmplitude.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.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxAmplitude class.
//
#include "MatchboxAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/SpinorHelicity.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/SU2Helper.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include "ThePEG/Utilities/StringUtils.h"
#include "MatchboxMEBase.h"
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
MatchboxAmplitude::MatchboxAmplitude()
: Amplitude(), theCleanupAfter(20),
treeLevelHelicityPoints(0),
oneLoopHelicityPoints(0) {
}
MatchboxAmplitude::~MatchboxAmplitude() {}
void MatchboxAmplitude::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << theColourBasis << theFactory
<< theCleanupAfter << treeLevelHelicityPoints << oneLoopHelicityPoints
<< theReshuffleMasses.size();
if ( !theReshuffleMasses.empty() ) {
for ( map<long,Energy>::const_iterator r = theReshuffleMasses.begin();
r != theReshuffleMasses.end(); ++r )
os << r->first << ounit(r->second,GeV);
}
}
void MatchboxAmplitude::persistentInput(PersistentIStream & is, int) {
size_t reshuffleSize;
is >> theLastXComb >> theColourBasis >> theFactory
>> theCleanupAfter >> treeLevelHelicityPoints >> oneLoopHelicityPoints
>> reshuffleSize;
theReshuffleMasses.clear();
while ( reshuffleSize > 0 ) {
long id; Energy m;
is >> id >> iunit(m,GeV);
theReshuffleMasses[id] = m;
--reshuffleSize;
}
lastMatchboxXComb(theLastXComb);
}
Ptr<MatchboxFactory>::tptr MatchboxAmplitude::factory() const {
return theFactory;
}
void MatchboxAmplitude::factory(Ptr<MatchboxFactory>::tptr f) {
theFactory = f;
}
void MatchboxAmplitude::doinit() {
Amplitude::doinit();
if ( colourBasis() ) {
colourBasis()->factory(factory());
colourBasis()->init();
}
}
void MatchboxAmplitude::doinitrun() {
Amplitude::doinitrun();
if ( colourBasis() )
colourBasis()->initrun();
}
void MatchboxAmplitude::cloneDependencies(const std::string&) {}
Ptr<MatchboxMEBase>::ptr MatchboxAmplitude::makeME(const PDVector&) const {
return new_ptr(MatchboxMEBase());
}
Selector<const ColourLines *> MatchboxAmplitude::colourGeometries(tcDiagPtr d) const {
if ( haveColourFlows() )
return colourBasis()->colourGeometries(d,lastLargeNAmplitudes());
return Selector<const ColourLines *>();
}
void MatchboxAmplitude::olpOrderFileHeader(ostream& os) const {
os << "# OLP order file created by Herwig++/Matchbox\n\n";
os << "InterfaceVersion BLHA2\n\n";
os << "Model SM\n"
<< "CorrectionType QCD\n"
<< "IRregularisation " << (isDR() ? "DRED" : "CDR") << "\n"
<< "Extra HelAvgInitial no\n"
<< "Extra ColAvgInitial no\n"
<< "Extra MCSymmetrizeFinal no\n";
os << "\n";
}
void MatchboxAmplitude::olpOrderFileProcesses(ostream& os,
const map<pair<Process,int>,int>& proc) const {
map<int,pair<Process,int> > sorted;
for ( map<pair<Process,int>,int>::const_iterator p = proc.begin();
p != proc.end(); ++p ) {
sorted[p->second] = p->first;
}
unsigned int currentOrderInAlphaS = sorted.begin()->second.first.orderInAlphaS;
unsigned int currentOrderInAlphaEW = sorted.begin()->second.first.orderInAlphaEW;
int currentType = sorted.begin()->second.second;
os << "AlphasPower " << currentOrderInAlphaS << "\n"
<< "AlphaPower " << currentOrderInAlphaEW << "\n"
<< "AmplitudeType ";
if ( currentType == ProcessType::treeME2 ) {
os << "tree\n";
} else if ( currentType == ProcessType::oneLoopInterference ) {
os << "loop\n";
} else if ( currentType == ProcessType::colourCorrelatedME2 ) {
os << "cctree\n";
} else if ( currentType == ProcessType::spinColourCorrelatedME2 ) {
os << "sctree\n";
} else if ( currentType == ProcessType::loopInducedME2 ) {
os << "loopinduced\n";
} else if ( currentType == ProcessType::spinCorrelatedME2 ) {
os << "stree\n";
} else assert(false);
for ( map<int,pair<Process,int> >::const_iterator p = sorted.begin();
p != sorted.end(); ++p ) {
if ( currentOrderInAlphaS != p->second.first.orderInAlphaS ) {
currentOrderInAlphaS = p->second.first.orderInAlphaS;
os << "AlphasPower " << currentOrderInAlphaS << "\n";
}
if ( currentOrderInAlphaEW != p->second.first.orderInAlphaEW ) {
currentOrderInAlphaEW = p->second.first.orderInAlphaEW;
os << "AlphaPower " << currentOrderInAlphaEW << "\n";
}
if ( currentType != p->second.second ) {
currentType = p->second.second;
os << "AmplitudeType ";
if ( currentType == ProcessType::treeME2 ) {
os << "tree\n";
} else if ( currentType == ProcessType::oneLoopInterference ) {
os << "loop\n";
} else if ( currentType == ProcessType::colourCorrelatedME2 ) {
os << "cctree\n";
} else if ( currentType == ProcessType::spinColourCorrelatedME2 ) {
os << "sctree\n";
} else if ( currentType == ProcessType::spinCorrelatedME2 ) {
os << "stree\n";
} else assert(false);
}
os << p->second.first.legs[0]->id() << " "
<< p->second.first.legs[1]->id() << " -> ";
for ( PDVector::const_iterator o = p->second.first.legs.begin() + 2;
o != p->second.first.legs.end(); ++o ) {
os << (**o).id() << " ";
}
os << "\n";
}
}
bool MatchboxAmplitude::startOLP(const map<pair<Process,int>,int>& procs) {
string orderFileName = factory()->buildStorage() + name() + ".OLPOrder.lh";
ofstream orderFile(orderFileName.c_str());
olpOrderFileHeader(orderFile);
olpOrderFileProcesses(orderFile,procs);
string contractFileName = factory()->buildStorage() + name() + ".OLPContract.lh";
signOLP(orderFileName, contractFileName);
// TODO check the contract file
int status = 0;
startOLP(contractFileName, status);
if ( status != 1 )
return false;
return true;
}
struct orderPartonData {
bool operator()(const pair<tcPDPtr,int>& a,
const pair<tcPDPtr,int>& b) const {
if ( a.first == b.first )
return a.second < b.second;
int acolour = a.first->iColour();
int bcolour = b.first->iColour();
if ( abs(acolour) != abs(bcolour) )
return abs(acolour) < abs(bcolour);
if ( a.first->iSpin() != b.first->iSpin() )
return a.first->iSpin() < b.first->iSpin();
int acharge = a.first->iCharge();
int bcharge = b.first->iCharge();
if ( abs(acharge) != abs(bcharge) )
return abs(acharge) < abs(bcharge);
if ( abs(a.first->id()) != abs(b.first->id()) )
return abs(a.first->id()) < abs(b.first->id());
return a.first->id() > b.first->id();
}
};
void MatchboxAmplitude::setXComb(tStdXCombPtr xc) {
theLastXComb = xc;
lastMatchboxXComb(xc);
fillCrossingMap();
if ( treeAmplitudes() || oneLoopAmplitudes() )
for ( size_t k = 0 ; k < meMomenta().size(); ++k )
amplitudeMomenta()[k] = amplitudeMomentum(k);
}
void MatchboxAmplitude::fillCrossingMap(size_t shift) {
if ( !amplitudePartonData().empty() )
return;
double csign = 1.;
set<pair<tcPDPtr,int>,orderPartonData > processLegs;
for ( unsigned int l = 0; l < mePartonData().size(); ++l ) {
if ( l > 1 )
processLegs.insert(make_pair(mePartonData()[l],l));
else {
if ( mePartonData()[l]->CC() ) {
processLegs.insert(make_pair(mePartonData()[l]->CC(),l));
if ( mePartonData()[l]->iSpin() == PDT::Spin1Half )
csign *= -1.;
} else {
processLegs.insert(make_pair(mePartonData()[l],l));
}
}
}
crossingSign(csign);
set<pair<tcPDPtr,int> > amplitudeLegs;
crossingMap().resize(mePartonData().size());
amplitudePartonData().resize(mePartonData().size());
amplitudeMomenta().resize(mePartonData().size());
int ampCount = 0;
// process legs are already sorted, we only need to arrange for
// adjacent particles and anti-particles
while ( !processLegs.empty() ) {
set<pair<tcPDPtr,int>,orderPartonData >::iterator next
= processLegs.begin();
while ( next->first->id() < 0 ) {
if ( ++next == processLegs.end() )
break;
}
//This happens for e.g. p p-> W- gamma & p p->W- W- j j
//Still working for pp->W-H-W- e+ nue jj ???
if(next == processLegs.end()){
next = processLegs.begin();
for (;next!=processLegs.end();next++){
assert(next->first->id() < 0 );
crossingMap()[ampCount] = next->second - shift;
amplitudeLegs.insert(make_pair(next->first,ampCount));
++ampCount;
processLegs.erase(next);
}
break;
}
crossingMap()[ampCount] = next->second - shift;
amplitudeLegs.insert(make_pair(next->first,ampCount));
tcPDPtr check = next->first;
processLegs.erase(next);
++ampCount;
if ( check->CC() ) {
set<pair<tcPDPtr,int>,orderPartonData>::iterator checkcc
= processLegs.end();
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( c->first == check->CC() ) {
checkcc = c; break;
}
}
if ( checkcc == processLegs.end() )
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( !SU2Helper::SU2CC(check) )
continue;
if ( c->first == SU2Helper::SU2CC(check)->CC() ) {
checkcc = c; break;
}
}
if ( checkcc == processLegs.end() ) {
int f = SU2Helper::family(check);
for ( int i = 1 - f; i < 5 - f; i++ ) {
bool gotone = false;
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( !SU2Helper::SU2CC(check,i) )
continue;
if ( c->first == SU2Helper::SU2CC(check,i)->CC() ) {
checkcc = c; gotone = true; break;
}
}
if ( gotone )
break;
}
}
// default to just pick the next available anti-particle
if ( processLegs.empty() ) break;
if ( checkcc == processLegs.end() ) {
checkcc = processLegs.begin();
while ( checkcc->first->id() > 0 )
if ( ++checkcc == processLegs.end() )
break;
}
// if still not there, use whatever is available at the end
if ( checkcc == processLegs.end() )
checkcc = processLegs.begin();
crossingMap()[ampCount] = checkcc->second - shift;
amplitudeLegs.insert(make_pair(checkcc->first,ampCount));
processLegs.erase(checkcc);
++ampCount;
}
}
for ( set<pair<tcPDPtr,int> >::const_iterator l = amplitudeLegs.begin();
l != amplitudeLegs.end(); ++l )
amplitudePartonData()[l->second] = l->first;
if ( colourBasis() ) {
assert(colourBasis()->indexMap().find(mePartonData()) !=
colourBasis()->indexMap().end());
const map<size_t,size_t> colourCross =
colourBasis()->indexMap().find(mePartonData())->second;
for ( size_t k = 0; k < crossingMap().size(); ++k ) {
if ( colourCross.find(crossingMap()[k]) !=
colourCross.end() ) {
size_t ccross = colourCross.find(crossingMap()[k])->second;
amplitudeToColourMap()[k] = ccross;
colourToAmplitudeMap()[ccross] = k;
}
}
}
}
const string& MatchboxAmplitude::colourOrderingString(size_t id) const {
static string empty = "";
if ( !colourBasis() ) {
return empty;
}
return colourBasis()->orderingString(mePartonData(),colourToAmplitudeMap(),id);
}
const set<vector<size_t> >& MatchboxAmplitude::colourOrdering(size_t id) const {
static set<vector<size_t> > empty;
if ( !colourBasis() ) {
return empty;
}
return colourBasis()->ordering(mePartonData(),colourToAmplitudeMap(),id);
}
Lorentz5Momentum MatchboxAmplitude::amplitudeMomentum(int i) const {
int iCrossed = crossingMap()[i];
Lorentz5Momentum res = meMomenta()[iCrossed];
if ( iCrossed < 2 )
res = -res;
res.setMass(meMomenta()[iCrossed].mass());
Energy2 rho = res.t()*res.t() - res.mass2();
res.setRho(sqrt(abs(rho)));
return res;
}
set<vector<int> > MatchboxAmplitude::generateHelicities() const {
set<vector<int> > res;
vector<int> current(amplitudePartonData().size());
doGenerateHelicities(res,current,0);
return res;
}
void MatchboxAmplitude::doGenerateHelicities(set<vector<int> >& res,
vector<int>& current,
size_t pos) const {
if ( pos == amplitudePartonData().size() ) {
res.insert(current);
return;
}
if ( amplitudePartonData()[pos]->iSpin() == PDT::Spin0 ) {
current[pos] = 0;
doGenerateHelicities(res,current,pos+1);
} else if ( amplitudePartonData()[pos]->iSpin() == PDT::Spin1Half ) {
current[pos] = 1;
doGenerateHelicities(res,current,pos+1);
current[pos] = -1;
doGenerateHelicities(res,current,pos+1);
}else if (amplitudePartonData()[pos]->iSpin() == PDT::Spin1 ) {
if (amplitudePartonData()[pos]->hardProcessMass() != ZERO){
current[pos] = 0;
doGenerateHelicities(res,current,pos+1);
}
current[pos] = 1;
doGenerateHelicities(res,current,pos+1);
current[pos] = -1;
doGenerateHelicities(res,current,pos+1);
}
}
vector<unsigned int> MatchboxAmplitude::physicalHelicities(const vector<int>&) const {
throw Exception()
- << "The amplitude '" << name() << "' does not support the spin correlation algorithm"
+ << "MatchboxAmplitude::physicalHelicities(): The amplitude '" << name() << "' does not support the spin correlation algorithm"
<< Exception::abortnow;
static vector<unsigned int> dummy;
return dummy;
}
void MatchboxAmplitude::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr) {
if ( !calculateTreeAmplitudes() )
return;
bool initialized =
!lastAmplitudes().empty() && treeLevelHelicityPoints > theCleanupAfter;
if ( !initialized ) {
treeLevelHelicityPoints++;
map<vector<int>,CVector> all;
map<vector<int>,CVector> allLargeN;
set<vector<int> > helicities = generateHelicities();
for ( set<vector<int> >::const_iterator h = helicities.begin();
h != helicities.end(); ++h ) {
all.insert(make_pair(*h,CVector(colourBasisDim())));
allLargeN.insert(make_pair(*h,CVector(colourBasisDim())));
}
AmplitudeIterator amp = all.begin();
AmplitudeIterator lamp = allLargeN.begin();
for ( ; amp != all.end(); ++amp, ++lamp ) {
for ( size_t k = 0; k < colourBasisDim(); ++k ){
amp->second(k) = evaluate(k,amp->first,lamp->second(k));
if ( amp->second(k) != Complex(0.0) ) {
if ( lastAmplitudes().find(amp->first)!=lastAmplitudes().end() ) {
lastAmplitudes().find(amp->first)->second = amp->second;
lastLargeNAmplitudes().find(lamp->first)->second = lamp->second;
} else {
lastAmplitudes().insert(*amp);
lastLargeNAmplitudes().insert(*lamp);
}
} else if ( lastAmplitudes().find(amp->first)!=lastAmplitudes().end() ){
lastAmplitudes().find(amp->first)->second = amp->second;
lastLargeNAmplitudes().find(lamp->first)->second = lamp->second;
}
}
}
} else {
AmplitudeIterator amp = lastAmplitudes().begin();
AmplitudeIterator lamp = lastLargeNAmplitudes().begin();
for ( ;amp != lastAmplitudes().end(); ++amp, ++lamp ) {
for ( size_t k = 0; k < colourBasisDim(); ++k ){
amp->second(k) = evaluate(k,amp->first,lamp->second(k));
}
}
}
haveTreeAmplitudes();
}
void MatchboxAmplitude::prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr) {
if ( !calculateOneLoopAmplitudes() )
return;
bool initialized =
!lastOneLoopAmplitudes().empty() && oneLoopHelicityPoints > theCleanupAfter;
if ( !initialized ) {
oneLoopHelicityPoints++;
map<vector<int>,CVector> all;
set<vector<int> > helicities = generateHelicities();
for ( set<vector<int> >::const_iterator h = helicities.begin();
h != helicities.end(); ++h ) {
all.insert(make_pair(*h,CVector(colourBasisDim())));
}
AmplitudeIterator amp = all.begin();
for ( ; amp != all.end(); ++amp ) {
for ( size_t k = 0; k < colourBasisDim(); ++k ){
amp->second(k) = evaluateOneLoop(k,amp->first);
if ( amp->second(k) != Complex(0.0) ) {
if ( lastOneLoopAmplitudes().find(amp->first)!=lastOneLoopAmplitudes().end() ) {
lastOneLoopAmplitudes().find(amp->first)->second = amp->second;
} else{
lastOneLoopAmplitudes().insert(*amp);
}
} else if ( lastOneLoopAmplitudes().find(amp->first)!=lastOneLoopAmplitudes().end() ){
lastOneLoopAmplitudes().find(amp->first)->second = amp->second;
}
}
}
} else {
AmplitudeIterator amp = lastOneLoopAmplitudes().begin();
for ( ;amp != lastOneLoopAmplitudes().end(); ++amp ) {
for ( size_t k = 0; k < colourBasisDim(); ++k ){
amp->second(k) = evaluateOneLoop(k,amp->first);
}
}
}
haveOneLoopAmplitudes();
}
Complex MatchboxAmplitude::value(const tcPDVector&,
const vector<Lorentz5Momentum>&,
const vector<int>&) {
assert(false && "ThePEG::Amplitude interface is not sufficient at the moment.");
- throw Exception() << "ThePEG::Amplitude interface is not sufficient at the moment."
+ throw Exception() << "MatchboxAmplitude::value(): ThePEG::Amplitude interface is not sufficient at the moment."
<< Exception::abortnow;
return 0.;
}
double MatchboxAmplitude::me2() const {
if ( !calculateTreeME2() )
return lastTreeME2();
lastTreeME2(colourBasis()->me2(mePartonData(),lastAmplitudes()));
return lastTreeME2();
}
double MatchboxAmplitude::largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const {
if ( !calculateLargeNME2() )
return lastLargeNME2();
double res = largeNBasis->me2(mePartonData(),lastLargeNAmplitudes());
lastLargeNME2(res);
return res;
}
double MatchboxAmplitude::oneLoopInterference() const {
if ( !calculateOneLoopInterference() )
return lastOneLoopInterference();
lastOneLoopInterference(colourBasis()->interference(mePartonData(),
lastOneLoopAmplitudes(),lastAmplitudes()));
return lastOneLoopInterference();
}
double MatchboxAmplitude::colourCorrelatedME2(pair<int,int> ij) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
if ( !calculateColourCorrelator(ij) )
return lastColourCorrelator(ij)/cfac;
double res =
colourBasis()->colourCorrelatedME2(ij,mePartonData(),lastAmplitudes());
lastColourCorrelator(ij,res);
return res/cfac;
}
double MatchboxAmplitude::largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr largeNBasis) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = Nc/2.;
} else assert(false);
if ( !calculateLargeNColourCorrelator(ij) )
return lastLargeNColourCorrelator(ij)/cfac;
double res =
largeNBasis->colourCorrelatedME2(ij,mePartonData(),lastLargeNAmplitudes());
lastLargeNColourCorrelator(ij,res);
return res/cfac;
}
// compare int vectors modulo certain element
// which needs to differe between the two
bool equalsModulo(unsigned int i, const vector<int>& a, const vector<int>& b) {
assert(a.size()==b.size());
if ( a[i] == b[i] )
return false;
for ( unsigned int k = 0; k < a.size(); ++k ) {
if ( k == i )
continue;
if ( a[k] != b[k] )
return false;
}
return true;
}
LorentzVector<Complex> MatchboxAmplitude::plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int) const {
using namespace SpinorHelicity;
LorentzVector<complex<Energy> > num =
PlusSpinorCurrent(PlusConjugateSpinor(n),MinusSpinor(p)).eval();
complex<Energy> den =
sqrt(2.)*PlusSpinorProduct(PlusConjugateSpinor(n),PlusSpinor(p)).eval();
LorentzVector<Complex> polarization(num.x()/den,num.y()/den,num.z()/den,num.t()/den);
return polarization;
}
double MatchboxAmplitude::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
colourCorrelatedME2(ij)*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
int iCrossed = -1;
for ( unsigned int k = 0; k < crossingMap().size(); ++k )
if ( crossingMap()[k] == ij.first ) {
iCrossed = k;
break;
}
assert(iCrossed >= 0);
Complex csCorr = 0.0;
if ( calculateColourSpinCorrelator(ij) ) {
set<const CVector*> done;
for ( AmplitudeConstIterator a = lastAmplitudes().begin();
a != lastAmplitudes().end(); ++a ) {
if ( done.find(&(a->second)) != done.end() )
continue;
AmplitudeConstIterator b = lastAmplitudes().begin();
while ( !equalsModulo(iCrossed,a->first,b->first) )
if ( ++b == lastAmplitudes().end() )
break;
if ( b == lastAmplitudes().end() || done.find(&(b->second)) != done.end() )
continue;
done.insert(&(a->second)); done.insert(&(b->second));
if ( a->first[iCrossed] == 1 )
swap(a,b);
csCorr += colourBasis()->colourCorrelatedInterference(ij,mePartonData(),a->second,b->second);
}
lastColourSpinCorrelator(ij,csCorr);
} else {
csCorr = lastColourSpinCorrelator(ij);
}
double corr =
2.*real(csCorr*sqr(pFactor));
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr/cfac;
}
double MatchboxAmplitude::spinCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
me2()*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
int iCrossed = -1;
for ( unsigned int k = 0; k < crossingMap().size(); ++k )
if ( crossingMap()[k] == ij.first ) {
iCrossed = k;
break;
}
assert(iCrossed >= 0);
Complex csCorr = 0.0;
if ( calculateSpinCorrelator(ij) ) {
set<const CVector*> done;
for ( AmplitudeConstIterator a = lastAmplitudes().begin();
a != lastAmplitudes().end(); ++a ) {
if ( done.find(&(a->second)) != done.end() )
continue;
AmplitudeConstIterator b = lastAmplitudes().begin();
while ( !equalsModulo(iCrossed,a->first,b->first) )
if ( ++b == lastAmplitudes().end() )
break;
if ( b == lastAmplitudes().end() || done.find(&(b->second)) != done.end() )
continue;
done.insert(&(a->second)); done.insert(&(b->second));
if ( a->first[iCrossed] == 1 )
swap(a,b);
csCorr += colourBasis()->interference(mePartonData(),a->second,b->second);
}
lastSpinCorrelator(ij,csCorr);
} else {
csCorr = lastSpinCorrelator(ij);
}
double corr =
2.*real(csCorr*sqr(pFactor));
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr;
}
void MatchboxAmplitude::checkReshuffling(Ptr<MatchboxPhasespace>::tptr ps) {
set<long> noReshuffle;
for ( map<long,Energy>::const_iterator m = reshuffleMasses().begin();
m != reshuffleMasses().end(); ++m ) {
tcPDPtr data = getParticleData(m->first);
assert(data);
bool needReshuffle = m->second != data->hardProcessMass();
needReshuffle |=
(data->hardProcessWidth() != ZERO || data->massGenerator()) &&
ps->useMassGenerators();
if ( !needReshuffle )
noReshuffle.insert(m->first);
}
for ( set<long>::const_iterator rm = noReshuffle.begin();
rm != noReshuffle.end(); ++rm )
theReshuffleMasses.erase(*rm);
}
string MatchboxAmplitude::doReshuffle(string in) {
in = StringUtils::stripws(in);
if ( in.empty() )
- throw Exception() << "expecting PDG id and mass value"
+ throw Exception() << "MatchboxAmplitude::doReshuffle(): Expecting PDG id and mass value"
<< Exception::abortnow;
istringstream ins(in);
long id;
ins >> id;
if ( ins.eof() )
- throw Exception() << "expecting PDG id and mass value"
+ throw Exception() << "MatchboxAmplitude::doReshuffle(): expecting PDG id and mass value"
<< Exception::abortnow;
Energy m;
ins >> iunit(m,GeV);
theReshuffleMasses[id] = m;
return "";
}
string MatchboxAmplitude::doMassless(string in) {
in = StringUtils::stripws(in);
if ( in.empty() )
- throw Exception() << "expecting PDG id"
+ throw Exception() << "MatchboxAmplitude::doMassless(): Expecting PDG id"
<< Exception::abortnow;
istringstream ins(in);
long id;
ins >> id;
theReshuffleMasses[id] = ZERO;
return "";
}
string MatchboxAmplitude::doOnShell(string in) {
in = StringUtils::stripws(in);
if ( in.empty() )
- throw Exception() << "expecting PDG id"
+ throw Exception() << "MatchboxAmplitude::doOnShell(): Expecting PDG id"
<< Exception::abortnow;
istringstream ins(in);
long id;
ins >> id;
tcPDPtr data = getParticleData(id);
assert(data);
theReshuffleMasses[id] = data->hardProcessMass();
return "";
}
string MatchboxAmplitude::doClearReshuffling(string) {
theReshuffleMasses.clear();
return "";
}
void MatchboxAmplitude::Init() {
static ClassDocumentation<MatchboxAmplitude> documentation
("MatchboxAmplitude is the base class for amplitude "
"implementations inside Matchbox.");
static Reference<MatchboxAmplitude,ColourBasis> interfaceColourBasis
("ColourBasis",
"Set the colour basis implementation.",
&MatchboxAmplitude::theColourBasis, false, false, true, true, false);
static Parameter<MatchboxAmplitude,int> interfaceCleanupAfter
("CleanupAfter",
"The number of points after which helicity combinations are cleaned up.",
&MatchboxAmplitude::theCleanupAfter, 20, 1, 0,
false, false, Interface::lowerlim);
static Command<MatchboxAmplitude> interfaceReshuffle
("Reshuffle",
"Reshuffle the mass for the given PDG id to a different mass shell for amplitude evaluation.",
&MatchboxAmplitude::doReshuffle, false);
static Command<MatchboxAmplitude> interfaceMassless
("Massless",
"Reshuffle the mass for the given PDG id to be massless for amplitude evaluation.",
&MatchboxAmplitude::doMassless, false);
static Command<MatchboxAmplitude> interfaceOnShell
("OnShell",
"Reshuffle the mass for the given PDG id to be the on-shell mass for amplitude evaluation.",
&MatchboxAmplitude::doOnShell, false);
static Command<MatchboxAmplitude> interfaceClearReshuffling
("ClearReshuffling",
"Do not perform any reshuffling.",
&MatchboxAmplitude::doClearReshuffling, false);
}
// *** 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<MatchboxAmplitude,Amplitude>
describeMatchboxAmplitude("Herwig::MatchboxAmplitude", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc b/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc
--- a/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc
@@ -1,244 +1,244 @@
// -*- C++ -*-
//
// MatchboxHybridAmplitude.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 MatchboxHybridAmplitude class.
//
#include "MatchboxHybridAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.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/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
using namespace Herwig;
MatchboxHybridAmplitude::MatchboxHybridAmplitude()
: theUseOLPCorrelators(false) {}
MatchboxHybridAmplitude::~MatchboxHybridAmplitude() {}
IBPtr MatchboxHybridAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxHybridAmplitude::fullclone() const {
return new_ptr(*this);
}
void MatchboxHybridAmplitude::factory(Ptr<MatchboxFactory>::tptr f) {
if ( treeLevelAmplitude() )
treeLevelAmplitude()->factory(f);
if ( oneLoopAmplitude() )
oneLoopAmplitude()->factory(f);
MatchboxAmplitude::factory(f);
}
bool MatchboxHybridAmplitude::isConsistent() const {
assert(oneLoopAmplitude());
return
!treeLevelAmplitude()->isOLPTree() &&
!treeLevelAmplitude()->isOLPLoop() &&
oneLoopAmplitude()->haveOneLoop() &&
treeLevelAmplitude()->orderInGs() ==
oneLoopAmplitude()->orderInGs() &&
treeLevelAmplitude()->orderInGem() ==
oneLoopAmplitude()->orderInGem() &&
treeLevelAmplitude()->hasRunningAlphaS() ==
oneLoopAmplitude()->hasRunningAlphaS() &&
treeLevelAmplitude()->hasRunningAlphaEW() ==
oneLoopAmplitude()->hasRunningAlphaEW() &&
!(treeLevelAmplitude()->nDimAdditional() != 0 &&
oneLoopAmplitude()->nDimAdditional() != 0);
}
bool MatchboxHybridAmplitude::canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr f,
bool virt) const {
if ( !virt )
return treeLevelAmplitude()->canHandle(p,f,false);
if ( treeLevelAmplitude()->canHandle(p,f,false) &&
oneLoopAmplitude()->canHandle(p,f,true) ) {
if ( !isConsistent() ) {
generator()->log() << "Warning: Inconsistent settings encountered for MatchboxHybridAmplitude '"
<< name() << "'\n" << flush;
return false;
}
return true;
}
return false;
}
void MatchboxHybridAmplitude::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
treeLevelAmplitude()->prepareAmplitudes(me);
}
void MatchboxHybridAmplitude::prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
assert(oneLoopAmplitude());
oneLoopAmplitude()->prepareOneLoopAmplitudes(me);
}
double MatchboxHybridAmplitude::symmetryRatio() const {
assert(oneLoopAmplitude());
double ifact = 1.;
if ( treeLevelAmplitude()->hasInitialAverage() &&
!oneLoopAmplitude()->hasInitialAverage() ) {
ifact = 1./4.;
if (lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3bar )
ifact /= SM().Nc();
else if ( lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour8 )
ifact /= (SM().Nc()*SM().Nc()-1.);
if ( lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3bar )
ifact /= SM().Nc();
else if ( mePartonData()[1]->iColour() == PDT::Colour8 )
ifact /= (SM().Nc()*SM().Nc()-1.);
}
if ( !treeLevelAmplitude()->hasInitialAverage() &&
oneLoopAmplitude()->hasInitialAverage() ) {
ifact = 4.;
if ( lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3bar )
ifact *= SM().Nc();
else if ( lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour8 )
ifact *= (SM().Nc()*SM().Nc()-1.);
if ( lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3bar )
ifact *= SM().Nc();
else if ( lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour8 )
ifact *= (SM().Nc()*SM().Nc()-1.);
}
if ( treeLevelAmplitude()->hasFinalStateSymmetry() &&
!oneLoopAmplitude()->hasFinalStateSymmetry() ) {
assert(lastMatchboxXComb()->matchboxME());
ifact *= lastMatchboxXComb()->matchboxME()->finalStateSymmetry();
}
if ( !treeLevelAmplitude()->hasFinalStateSymmetry() &&
oneLoopAmplitude()->hasFinalStateSymmetry() ) {
assert(lastMatchboxXComb()->matchboxME());
ifact /= lastMatchboxXComb()->matchboxME()->finalStateSymmetry();
}
return ifact;
}
void MatchboxHybridAmplitude::cloneDependencies(const std::string& prefix) {
if ( treeLevelAmplitude() ) {
Ptr<MatchboxAmplitude>::ptr myTreeLevelAmplitude = treeLevelAmplitude()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myTreeLevelAmplitude->name();
if ( ! (generator()->preinitRegister(myTreeLevelAmplitude,pname.str()) ) )
- throw InitException() << "Amplitude " << pname.str() << " already existing.";
+ throw InitException() << "MatchboxHybridAmplitude::cloneDependencies(): Amplitude " << pname.str() << " already existing.";
myTreeLevelAmplitude->cloneDependencies(pname.str());
treeLevelAmplitude(myTreeLevelAmplitude);
}
if ( oneLoopAmplitude() ) {
Ptr<MatchboxAmplitude>::ptr myOneLoopAmplitude = oneLoopAmplitude()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myOneLoopAmplitude->name();
if ( ! (generator()->preinitRegister(myOneLoopAmplitude,pname.str()) ) )
- throw InitException() << "Amplitude " << pname.str() << " already existing.";
+ throw InitException() << "MatchboxHybridAmplitude::cloneDependencies(): Amplitude " << pname.str() << " already existing.";
myOneLoopAmplitude->cloneDependencies(pname.str());
oneLoopAmplitude(myOneLoopAmplitude);
}
MatchboxAmplitude::cloneDependencies(prefix);
}
void MatchboxHybridAmplitude::doinit() {
MatchboxAmplitude::doinit();
if ( treeLevelAmplitude() )
treeLevelAmplitude()->init();
if ( oneLoopAmplitude() )
oneLoopAmplitude()->init();
}
void MatchboxHybridAmplitude::doinitrun() {
MatchboxAmplitude::doinitrun();
if ( treeLevelAmplitude() )
treeLevelAmplitude()->initrun();
if ( oneLoopAmplitude() )
oneLoopAmplitude()->initrun();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxHybridAmplitude::persistentOutput(PersistentOStream & os) const {
os << theTreeLevelAmplitude << theOneLoopAmplitude << theUseOLPCorrelators;
}
void MatchboxHybridAmplitude::persistentInput(PersistentIStream & is, int) {
is >> theTreeLevelAmplitude >> theOneLoopAmplitude >> theUseOLPCorrelators;
}
// *** 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<MatchboxHybridAmplitude,Herwig::MatchboxAmplitude>
describeHerwigMatchboxHybridAmplitude("Herwig::MatchboxHybridAmplitude", "Herwig.so");
void MatchboxHybridAmplitude::Init() {
static ClassDocumentation<MatchboxHybridAmplitude> documentation
("MatchboxHybridAmplitude unifies two amplitude objects to "
"provide tree and one-loop matrix elements.");
static Reference<MatchboxHybridAmplitude,MatchboxAmplitude> interfaceTreeLevelAmplitude
("TreeLevelAmplitude",
"Set the tree level amplitude to be used.",
&MatchboxHybridAmplitude::theTreeLevelAmplitude, false, false, true, false, false);
static Reference<MatchboxHybridAmplitude,MatchboxAmplitude> interfaceOneLoopAmplitude
("OneLoopAmplitude",
"Set the one-loop amplitude to be used.",
&MatchboxHybridAmplitude::theOneLoopAmplitude, false, false, true, true, false);
static Switch<MatchboxHybridAmplitude,bool> interfaceUseOLPCorrelators
("UseOLPCorrelators",
"",
&MatchboxHybridAmplitude::theUseOLPCorrelators, false, false, false);
static SwitchOption interfaceUseOLPCorrelatorsYes
(interfaceUseOLPCorrelators,
"Yes",
"",
true);
static SwitchOption interfaceUseOLPCorrelatorsNo
(interfaceUseOLPCorrelators,
"No",
"",
false);
}
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,1692 +1,1692 @@
// -*- 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 <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::abortnow;
}
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::abortnow;
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 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::abortnow;
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::abortnow;
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);
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::abortnow;
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::abortnow;
return ZERO;
}
Energy2 MatchboxMEBase::renormalizationScaleQED() const {
if ( scaleChoice() ) {
return scaleChoice()->renormalizationScaleQED();
}
return renormalizationScale();
}
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) const {
assert(lastXCombPtr()->partonBins().first->pdf());
if ( xEx < 1. && lastX1() >= xEx ) {
return
( ( 1. - lastX1() ) / ( 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())/lastX1();
}
double MatchboxMEBase::pdf2(Energy2 fscale, double xEx) const {
assert(lastXCombPtr()->partonBins().second->pdf());
if ( xEx < 1. && lastX2() >= xEx ) {
return
( ( 1. - lastX2() ) / ( 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())/lastX2();
}
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::abortnow;
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::abortnow;
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() ) {
lastME2(0.0);
lastMECrossSection(ZERO);
return lastMECrossSection();
}
double xme2 = me2();
lastME2(xme2);
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() )
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::abortnow;
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 InitException() << "Dipole " << dname.str() << " already existing.";
+ throw InitException() << "MatchboxMEBase::getDipoles(): Dipole " << dname.str() << " already existing.";
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::abortnow;
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::abortnow;
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::abortnow;
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::abortnow;
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)
<< " me2 = " << lastME2() << "\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 InitException() << "Phasespace generator " << pname.str() << " already existing.";
+ throw InitException() << "MatchboxMEBase::cloneDependencies(): Phasespace generator " << pname.str() << " already existing.";
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 InitException() << "Amplitude " << pname.str() << " already existing.";
+ throw InitException() << "MatchboxMEBase::cloneDependencies(): Amplitude " << pname.str() << " already existing.";
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 InitException() << "Scale choice " << pname.str() << " already existing.";
+ throw InitException() << "MatchboxMEBase::cloneDependencies(): Scale choice " << pname.str() << " already existing.";
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 InitException() << "Reweight " << pname.str() << " already existing.";
+ throw InitException() << "MatchboxMEBase::cloneDependencies(): Reweight " << pname.str() << " already existing.";
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 InitException() << "Insertion operator " << pname.str() << " already existing.";
+ throw InitException() << "MatchboxMEBase::cloneDependencies(): Insertion operator " << pname.str() << " already existing.";
*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() ) {
string fname = name() + ".diagrams";
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/MatchboxOLPME.cc b/MatrixElement/Matchbox/Base/MatchboxOLPME.cc
--- a/MatrixElement/Matchbox/Base/MatchboxOLPME.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxOLPME.cc
@@ -1,341 +1,341 @@
// -*- C++ -*-
//
// MatchboxOLPME.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 MatchboxOLPME class.
//
#include "MatchboxOLPME.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "MatchboxMEBase.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxOLPME::MatchboxOLPME()
: theOrderInGs(0), theOrderInGem(0), theSetMuToMuR(false),
theUseRunningAlphaS(false), theUseRunningAlphaEW(false) {}
MatchboxOLPME::~MatchboxOLPME() {}
bool MatchboxOLPME::canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr factory,
bool) const {
if ( factory->processData()->diagramMap().find(p) !=
factory->processData()->diagramMap().end() )
return true;
vector<Ptr<Tree2toNDiagram>::ptr> diags =
factory->diagramGenerator()->generate(p,orderInGs(),orderInGem());
if ( diags.empty() )
return false;
factory->processData()->diagramMap()[p] = diags;
return true;
}
void MatchboxOLPME::setXComb(tStdXCombPtr xc) {
theLastXComb = xc;
lastMatchboxXComb(xc);
}
double MatchboxOLPME::me2() const {
if ( !calculateTreeME2() )
return lastTreeME2();
evalSubProcess();
return lastTreeME2();
}
double MatchboxOLPME::colourCorrelatedME2(pair<int,int> ij) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
if ( !calculateColourCorrelator(ij) )
return lastColourCorrelator(ij)/cfac;
evalColourCorrelator(ij);
return lastColourCorrelator(ij)/cfac;
}
double MatchboxOLPME::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
colourCorrelatedME2(ij)*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
Complex csCorr = 0.0;
if ( calculateColourSpinCorrelator(ij) )
evalSpinColourCorrelator(ij);
csCorr = lastColourSpinCorrelator(ij);
double corr =
2.*real(csCorr*sqr(pFactor));
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr/cfac;
}
double MatchboxOLPME::spinCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
me2()*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
Complex csCorr = 0.0;
if ( calculateSpinCorrelator(ij) )
evalSpinCorrelator(ij);
csCorr = lastSpinCorrelator(ij);
double corr =
2.*real(csCorr*sqr(pFactor));
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr;
}
void MatchboxOLPME::evalSpinCorrelator(pair<int,int>) const {
throw Exception()
<< "MatchboxOLPME::spinCorrelatedME2() is not implemented.\n"
<< "Please check your setup." << Exception::abortnow;
}
double MatchboxOLPME::oneLoopDoublePole() const {
if ( !calculateOneLoopPoles() )
return lastOneLoopPoles().first;
evalSubProcess();
return lastOneLoopPoles().first;
}
double MatchboxOLPME::oneLoopSinglePole() const {
if ( !calculateOneLoopPoles() )
return lastOneLoopPoles().second;
evalSubProcess();
return lastOneLoopPoles().second;
}
double MatchboxOLPME::oneLoopInterference() const {
if ( !calculateOneLoopInterference() )
return lastOneLoopInterference();
evalSubProcess();
return lastOneLoopInterference();
}
double MatchboxOLPME::largeNColourCorrelatedME2(pair<int,int>,
Ptr<ColourBasis>::tptr) const {
- throw Exception() << "largeNColourCorrelatedME2 not supported by MatchboxOLPME"
+ throw Exception() << "MatchboxOLPME::largeNColourCorrelatedME2(): not supported"
<< Exception::abortnow;
return 0.;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxOLPME::doinit() {
if ( theUseRunningAlphaS && !theSetMuToMuR ) {
- throw Exception()
+ throw Exception() << "MatchboxOLPME::doinit(): "
<< "Amplitude '" << name() << "' "
<< "uses a running alpha_s but fixed renormalization scale!\n"
<< Exception::abortnow;
}
if ( !theUseRunningAlphaS && theSetMuToMuR ) {
- throw Exception()
+ throw Exception() << "MatchboxOLPME::doinit(): "
<< "Amplitude '" << name() << "' "
<< "uses a fixed alpha_s but running renormalization scale!\n"
<< Exception::abortnow;
}
if ( !didStartOLP() ) {
string contractFileName =
optionalContractFile().empty() ?
factory()->buildStorage() + name() + ".OLPContract.lh" :
optionalContractFile();
int status = -1;
startOLP(contractFileName,status);
didStartOLP()=true;
if ( status != 1 ) {
- throw Exception()
+ throw Exception() << "MatchboxOLPME::doinit(): "
<< "Failed to restart one loop provider for amplitude '"
<< name() << "'\n" << Exception::abortnow;
}
}
MatchboxAmplitude::doinit();
}
void MatchboxOLPME::doinitrun() {
if ( theUseRunningAlphaS && !theSetMuToMuR ) {
- throw Exception()
+ throw Exception() << "MatchboxOLPME::doinitrun(): "
<< "Amplitude '" << name() << "' "
<< "uses a running alpha_s but fixed renormalization scale!\n"
<< Exception::abortnow;
}
if ( !theUseRunningAlphaS && theSetMuToMuR ) {
- throw Exception()
+ throw Exception() << "MatchboxOLPME::doinitrun(): "
<< "Amplitude '" << name() << "' "
<< "uses a fixed alpha_s but running renormalization scale!\n"
<< Exception::abortnow;
}
if ( !didStartOLP() ) {
string contractFileName =
optionalContractFile().empty() ?
factory()->buildStorage() + name() + ".OLPContract.lh" :
optionalContractFile();
int status = -1;
startOLP(contractFileName,status);
didStartOLP()=true;
if ( status != 1 ) {
- throw Exception()
+ throw Exception() << "MatchboxOLPME::doinitrun(): "
<< "Failed to restart one loop provider for amplitude '"
<< name() << "'\n" << Exception::abortnow;
}
}
MatchboxAmplitude::doinitrun();
}
Energy2 MatchboxOLPME::mu2() const {
if (theSetMuToMuR) {
return lastMatchboxXComb()->lastRenormalizationScale();
}
return lastSHat();
}
bool MatchboxOLPME::hasRunningAlphaS() const {
if (theUseRunningAlphaS) {
return true;
}
return false;
}
bool MatchboxOLPME::hasRunningAlphaEW() const {
if (theUseRunningAlphaEW) {
return true;
}
return false;
}
void MatchboxOLPME::persistentOutput(PersistentOStream & os) const {
os << theOrderInGs << theOrderInGem << theSetMuToMuR << theUseRunningAlphaS << theUseRunningAlphaEW;
}
void MatchboxOLPME::persistentInput(PersistentIStream & is, int) {
is >> theOrderInGs >> theOrderInGem >> theSetMuToMuR >> theUseRunningAlphaS >> theUseRunningAlphaEW;
}
// *** 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<MatchboxOLPME,MatchboxAmplitude>
describeHerwigMatchboxOLPME("Herwig::MatchboxOLPME", "Herwig.so");
void MatchboxOLPME::Init() {
static ClassDocumentation<MatchboxOLPME> documentation
("MatchboxOLPME implements OLP interfaces.");
static Switch<MatchboxOLPME,bool> interfaceSetMuToMuR
("SetMuToMuR",
"Switch On to set the value of the dimensional regularization parameter mu2 for this OLP"
"to the value of the renormalization scale muR2. Default is Off. The restoration for the "
"full renormalization scale dependence in the DipoleIOperator isn't needed in this case.",
&MatchboxOLPME::theSetMuToMuR, false, false, false);
static SwitchOption interfaceSetMuToMuROn
(interfaceSetMuToMuR,
"On",
"On",
true);
static SwitchOption interfaceSetMuToMuROff
(interfaceSetMuToMuR,
"Off",
"Off",
false);
static Switch<MatchboxOLPME,bool> interfaceUseRunningAlphaS
("UseRunningAlphaS",
"Switch On to set the value of alpha_s for this OLP to the value of the running alpha_s "
"instead of to the value of the reference alpha_s. Default is Off. This also sets the value "
"for hasRunningAlphaS() to true.",
&MatchboxOLPME::theUseRunningAlphaS, false, false, false);
static SwitchOption interfaceUseRunningAlphaSOn
(interfaceUseRunningAlphaS,
"On",
"On",
true);
static SwitchOption interfaceUseRunningAlphaSOff
(interfaceUseRunningAlphaS,
"Off",
"Off",
false);
static Switch<MatchboxOLPME,bool> interfaceUseRunningAlphaEW
("UseRunningAlphaEW",
"Switch On to set the value of alpha_ew for this OLP to the value of the running alpha_ew "
"instead of to the value of the reference alpha_ew. Default is Off. This also sets the value "
"for hasRunningAlphaEW() to true.",
&MatchboxOLPME::theUseRunningAlphaEW, false, false, false);
static SwitchOption interfaceUseRunningAlphaEWOn
(interfaceUseRunningAlphaEW,
"On",
"On",
true);
static SwitchOption interfaceUseRunningAlphaEWOff
(interfaceUseRunningAlphaEW,
"Off",
"Off",
false);
}
diff --git a/MatrixElement/Matchbox/Base/SubtractedME.cc b/MatrixElement/Matchbox/Base/SubtractedME.cc
--- a/MatrixElement/Matchbox/Base/SubtractedME.cc
+++ b/MatrixElement/Matchbox/Base/SubtractedME.cc
@@ -1,790 +1,790 @@
// -*- C++ -*-
//
// SubtractedME.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.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SubtractedME class.
//
#include "SubtractedME.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/Utilities/DescribeClass.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Handlers/StdXCombGroup.h"
#include "ThePEG/Utilities/Rebinder.h"
#include "ThePEG/Utilities/Throw.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig++/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
using namespace Herwig;
SubtractedME::SubtractedME()
: MEGroup(),
theRealShowerSubtraction(false), theVirtualShowerSubtraction(false),
theLoopSimSubtraction(false), theSubProcessGroups(false) {}
SubtractedME::~SubtractedME() {}
Ptr<MatchboxFactory>::tcptr SubtractedME::factory() const { return theFactory; }
void SubtractedME::factory(Ptr<MatchboxFactory>::tcptr f) { theFactory = f; }
bool SubtractedME::subProcessGroups() const {
return
(factory()->subProcessGroups() && !showerApproximation()) ||
factory()->subtractionData() != "" || theSubProcessGroups;
}
Ptr<ShowerApproximation>::tptr SubtractedME::showerApproximation() const { return factory()->showerApproximation(); }
const vector<Ptr<MatchboxMEBase>::ptr>& SubtractedME::borns() const {
return theBorns.empty() ? factory()->bornMEs() : theBorns;
}
bool SubtractedME::verbose() const { return factory()->verbose(); }
bool SubtractedME::initVerbose() const { return factory()->initVerbose(); }
IBPtr SubtractedME::clone() const {
return new_ptr(*this);
}
IBPtr SubtractedME::fullclone() const {
return new_ptr(*this);
}
StdXCombPtr SubtractedME::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,
tMEPtr newME) {
tMEGroupPtr newMEGroup = dynamic_ptr_cast<tMEGroupPtr>(newME);
if ( !newMEGroup )
newMEGroup = this;
Ptr<MatchboxXCombGroup>::ptr res =
new_ptr(MatchboxXCombGroup(newMaxEnergy, inc,
newEventHandler, newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts, newMEGroup,
newDiagrams, mir,
newHead));
res->build(allPBins);
theReal->prepareXComb(*res);
if ( factory()->subtractionData() != "" ) {
set<cPDVector> procs;
for ( DiagramVector::const_iterator d = head()->diagrams().begin();
d != head()->diagrams().end(); ++d ) {
if ( procs.find((**d).partons()) == procs.end() )
procs.insert((**d).partons());
}
for ( set<cPDVector>::const_iterator p = procs.begin();
p != procs.end(); ++p ) {
for ( size_t i = 0; i < (*p).size(); ++i ) {
if ( !(*p)[i]->coloured() )
continue;
if ( i > 1 &&
(*p)[i]->id() == ParticleID::g ) {
softHistograms[SoftSubtractionIndex(*p,i)] = SubtractionHistogram(0.00001,1000.);
ostringstream fname("");
fname << factory()->subtractionData();
const cPDVector& myproc = SoftSubtractionIndex(*p,i).first;
for (cPDVector::const_iterator pp = myproc.begin(); pp != myproc.end(); ++pp) fname << (**pp).PDGName();
fname << "-" << i << "-" << i << "-scatter.dat";
fnamesSoftSubtraction[SoftSubtractionIndex(*p,i)] = fname.str();
if ( theReal->phasespace() )
res->singularLimits().insert(make_pair(i,i));
}
for ( size_t j = i+1; j < (*p).size(); ++j ) {
if ( !(*p)[j]->coloured() )
continue;
long iid = (*p)[i]->id();
long jid = (*p)[j]->id();
if ( i < 2 && j < 2 )
continue;
if ( i < 2 && j > 1 ) {
if ( abs(iid) < 7 && abs(jid) < 7 && iid != jid )
continue;
}
if ( i > 1 && j > 1 ) {
if ( abs(iid) < 7 && abs(jid) < 7 && iid + jid != 0 )
continue;
}
bool haveDipole = false;
for ( MEVector::const_iterator k = dependent().begin();
k != dependent().end(); ++k ) {
const SubtractionDipole& dip = dynamic_cast<const SubtractionDipole&>(**k);
if ( ( (size_t)(dip.realEmitter()) == i && (size_t)(dip.realEmission()) == j ) ||
( (size_t)(dip.realEmitter()) == j && (size_t)(dip.realEmission()) == i ) ) {
haveDipole = true;
break;
}
}
if ( !haveDipole )
continue;
collinearHistograms[CollinearSubtractionIndex(*p,make_pair(i,j))] = SubtractionHistogram(0.00001,1000.);
ostringstream fname("");
fname << factory()->subtractionData();
const cPDVector& myproc = CollinearSubtractionIndex(*p,make_pair(i,j)).first;
for (cPDVector::const_iterator pp = myproc.begin(); pp != myproc.end(); ++pp) fname << (**pp).PDGName();
fname << "-" << i << "-" << j << "-scatter.dat";
fnamesCollinearSubtraction[CollinearSubtractionIndex(*p,make_pair(i,j))] = fname.str();
if ( theReal->phasespace() )
res->singularLimits().insert(make_pair(i,j));
}
}
}
}
return res;
}
void SubtractedME::setXComb(tStdXCombPtr xc) {
MEGroup::setXComb(xc);
lastMatchboxXComb(xc);
}
MEBase::DiagramVector SubtractedME::dependentDiagrams(const cPDVector& proc,
tMEPtr depME) const {
Ptr<SubtractionDipole>::tptr dipole =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(depME);
if ( !dipole ) {
- Throw<InitException>() << "A dependent matrix element of SubtractedME "
+ throw InitException() << "SubtractedME: A dependent matrix element of SubtractedME "
<< "has not been derived from SubtractionDipole. "
<< "Please check the corresponding input file.";
}
return dipole->underlyingBornDiagrams(proc);
}
vector<Ptr<SubtractionDipole>::ptr> SubtractedME::dipoles() {
if ( dependent().empty() )
getDipoles();
vector<Ptr<SubtractionDipole>::ptr> res;
for ( MEVector::const_iterator k = dependent().begin();
k != dependent().end(); ++k )
res.push_back(dynamic_ptr_cast<Ptr<SubtractionDipole>::ptr>(*k));
return res;
}
void SubtractedME::getDipoles() {
if ( !dependent().empty() )
return;
Ptr<MatchboxMEBase>::tptr real =
dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
if ( borns().empty() || !real )
- Throw<InitException>() << "The SubtractedME '"
+ throw InitException() << "SubtractedME: The SubtractedME '"
<< name() << "' could not generate "
<< "subtraction terms for the real emission "
<< "matrix element '" << real->name() << "'. "
<< "Please check the corresponding input file.";
Ptr<MatchboxMEBase>::ptr myRealEmissionME = real->cloneMe();
ostringstream pname;
pname << fullName() << "/" << myRealEmissionME->name();
if ( ! (generator()->preinitRegister(myRealEmissionME,pname.str()) ) )
- throw InitException() << "Matrix element " << pname.str() << " already existing.";
+ throw InitException() << "SubtractedME: Matrix element " << pname.str() << " already existing.";
myRealEmissionME->cloneDependencies(pname.str());
head(myRealEmissionME);
real = myRealEmissionME;
dependent().clear();
vector<Ptr<SubtractionDipole>::ptr> genDipoles
= real->getDipoles(DipoleRepository::dipoles(factory()->dipoleSet()),borns());
if ( factory()->subtractionData() != "" ) {
for ( vector<Ptr<SubtractionDipole>::ptr>::const_iterator d =
genDipoles.begin(); d != genDipoles.end(); ++d )
(**d).doTestSubtraction();
}
if ( genDipoles.empty() && factory()->initVerbose() ) {
// probably finite real contribution, but warn
generator()->log() << "\nWarning: No subtraction dipoles could be found for the process:\n";
generator()->log() << real->subProcess().legs[0]->PDGName() << " "
<< real->subProcess().legs[1]->PDGName() << " -> ";
for ( PDVector::const_iterator p = real->subProcess().legs.begin() + 2;
p != real->subProcess().legs.end(); ++p )
generator()->log() << (**p).PDGName() << " ";
generator()->log() << "\n" << flush;
generator()->log() << "Assuming finite tree-level O(alphaS) correction.\n";
}
dependent().resize(genDipoles.size());
copy(genDipoles.begin(),genDipoles.end(),dependent().begin());
if ( !factory()->reweighters().empty() ) {
for ( MEVector::const_iterator d = dependent().begin(); d != dependent().end(); ++d ) {
for ( vector<ReweightPtr>::const_iterator rw = factory()->reweighters().begin();
rw != factory()->reweighters().end(); ++rw )
(**d).addReweighter(*rw);
}
}
if ( !factory()->preweighters().empty() ) {
for ( MEVector::const_iterator d = dependent().begin(); d != dependent().end(); ++d ) {
for ( vector<ReweightPtr>::const_iterator rw = factory()->preweighters().begin();
rw != factory()->preweighters().end(); ++rw )
(**d).addPreweighter(*rw);
}
}
}
void SubtractedME::cloneRealME(const string& prefix) {
theReal = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
if ( theReal ) {
Ptr<MatchboxMEBase>::ptr myRealEmissionME = theReal->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myRealEmissionME->name();
if ( ! (generator()->preinitRegister(myRealEmissionME,pname.str()) ) )
- throw InitException() << "Matrix element " << pname.str() << " already existing.";
+ throw InitException() << "SubtractedME: Matrix element " << pname.str() << " already existing.";
myRealEmissionME->cloneDependencies(pname.str());
theReal = myRealEmissionME;
}
head(theReal);
}
void SubtractedME::cloneDipoles(const string& prefix) {
MEVector dipMEs;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
Ptr<SubtractionDipole>::ptr cloned = dip->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << cloned->name();
if ( ! (generator()->preinitRegister(cloned,pname.str()) ) )
- throw InitException() << "Subtraction dipole " << pname.str() << " already existing.";
+ throw InitException() << "SubtractedME: Subtraction dipole " << pname.str() << " already existing.";
cloned->cloneDependencies(pname.str());
dipMEs.push_back(cloned);
}
dependent() = dipMEs;
}
vector<Ptr<SubtractionDipole>::ptr> SubtractedME::splitDipoles(const cPDVector& born) {
vector<Ptr<SubtractionDipole>::ptr> dips = dipoles();
vector<Ptr<SubtractionDipole>::ptr> res;
for ( vector<Ptr<SubtractionDipole>::ptr>::iterator d = dips.begin();
d != dips.end(); ++d ) {
for ( DiagramVector::const_iterator p = (**d).underlyingBornME()->diagrams().begin();
p != (**d).underlyingBornME()->diagrams().end(); ++p )
if ( born == (**p).partons() ) {
res.push_back(*d);
break;
}
}
return res;
}
void SubtractedME::doRealEmissionScales() {
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->doRealEmissionScales();
}
}
void SubtractedME::doRealShowerSubtraction() {
theRealShowerSubtraction = true;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->showerApproximation(showerApproximation());
dip->doRealShowerSubtraction();
}
}
void SubtractedME::doVirtualShowerSubtraction() {
theVirtualShowerSubtraction = true;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->showerApproximation(showerApproximation());
dip->doVirtualShowerSubtraction();
}
}
void SubtractedME::doLoopSimSubtraction() {
theLoopSimSubtraction = true;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->showerApproximation(showerApproximation());
dip->doLoopSimSubtraction();
}
}
void SubtractedME::setVetoScales(tSubProPtr) const {}
void SubtractedME::fillProjectors() {
if ( !virtualShowerSubtraction() && !loopSimSubtraction() )
return;
Ptr<StdXCombGroup>::tptr group =
dynamic_ptr_cast<Ptr<StdXCombGroup>::tptr>(lastXCombPtr());
for ( vector<StdXCombPtr>::const_iterator d = group->dependent().begin();
d != group->dependent().end(); ++d ) {
if ( !(**d).matrixElement()->apply() ||
!(**d).kinematicsGenerated() )
continue;
if ( (**d).willPassCuts() )
lastXCombPtr()->projectors().insert((**d).cutWeight(),*d);
}
}
double SubtractedME::reweightHead(const vector<tStdXCombPtr>&) {
if ( showerApproximation() ) {
if ( realShowerSubtraction() )
return 1.;
if ( virtualShowerSubtraction() || loopSimSubtraction() )
return 0.;
}
return 1.;
}
double SubtractedME::reweightDependent(tStdXCombPtr xc, const vector<tStdXCombPtr>& dep) {
if ( showerApproximation() ) {
if ( realShowerSubtraction() )
return 1.0;
if ( virtualShowerSubtraction() || loopSimSubtraction() ) {
if ( !lastXComb().lastProjector() )
return 0.0;
if ( xc != lastXComb().lastProjector() )
return 0.0;
double invPAlpha = 0.;
for ( vector<tStdXCombPtr>::const_iterator d = dep.begin(); d != dep.end(); ++d ) {
if ( !(**d).matrixElement()->apply() ||
!(**d).kinematicsGenerated() )
continue;
if ( (**d).willPassCuts() ) {
invPAlpha += (**d).cutWeight();
}
}
assert(invPAlpha != 0.0);
double palpha = xc->cutWeight()/invPAlpha;
return 1./palpha;
}
}
return 1.;
}
void SubtractedME::doinit() {
// has been deactivated by the factory
if ( !head() ) {
MEBase::doinit();
return;
}
theReal = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
if ( theReal ) {
getDipoles();
}
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator b = theBorns.begin();
b != theBorns.end(); ++b )
(**b).init();
if ( initVerbose() )
print(Repository::clog());
MEGroup::doinit();
}
void SubtractedME::doinitrun() {
// has been deactivated by the factory
if ( !head() ) {
MEBase::doinitrun();
return;
}
theReal = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator b = theBorns.begin();
b != theBorns.end(); ++b )
(**b).initrun();
MEGroup::doinitrun();
}
void SubtractedME::dofinish() {
// has been deactivated by the factory
if ( !head() ) {
MEBase::dofinish();
return;
}
MEGroup::dofinish();
for ( map<CollinearSubtractionIndex,SubtractionHistogram>::
const_iterator b = collinearHistograms.begin();
b != collinearHistograms.end(); ++b ) {
b->second.dump(factory()->subtractionData(),
factory()->subtractionPlotType(),
factory()->subtractionScatterPlot(),
b->first.first,
b->first.second.first,
b->first.second.second);
}
for ( map<SoftSubtractionIndex,SubtractionHistogram>::
const_iterator b = softHistograms.begin();
b != softHistograms.end(); ++b ) {
b->second.dump(factory()->subtractionData(),
factory()->subtractionPlotType(),
factory()->subtractionScatterPlot(),
b->first.first,
b->first.second,
b->first.second);
}
}
void SubtractedME::print(ostream& os) const {
os << "--- SubtractedME setup ---------------------------------------------------------\n";
os << " '" << name() << "' subtracting real emission\n '"
<< head()->name() << "' using the dipoles:\n";
for ( MEVector::const_iterator d = dependent().begin();
d != dependent().end(); ++d )
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*d)->print(os);
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void SubtractedME::printLastEvent(ostream& os) const {
os << "--- SubtractedME last event information ----------------------------------------\n";
os << " for subtracted matrix element '" << name() << "'\n";
os << " real emission event information:\n";
dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head())->printLastEvent(os);
os << " dipoles event information:\n";
for ( MEVector::const_iterator d = dependent().begin();
d != dependent().end(); ++d )
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*d)->printLastEvent(os);
os << "--- end SubtractedME last event information ------------------------------------\n\n\n";
os << flush;
}
void SubtractedME::lastEventStatistics() {
MEGroup::lastEventStatistics();
if ( !generator() )
return;
/*
if ( verbose() )
printLastEvent(generator()->log());
*/
if ( !collinearHistograms.empty() )
lastEventSubtraction();
}
SubtractedME::SubtractionHistogram::
SubtractionHistogram(double low,
double up,
unsigned int nbins)
: lower(low) {
nbins = nbins + 1;
double c = log10(up/low) / (nbins-1.);
for ( unsigned int k = 1; k < nbins; ++k ) {
bins[low*pow(10.0,k*c)] = make_pair(Constants::MaxDouble,0.);
}
}
void SubtractedME::SubtractionHistogram::persistentOutput(PersistentOStream& os) const {
os << lower << bins;
}
void SubtractedME::SubtractionHistogram::persistentInput(PersistentIStream& is) {
is >> lower >> bins;
}
void SubtractedME::SubtractionHistogram::
dump(const std::string& prefix,
const int& plottype,
const bool& scatterplot,
const cPDVector& proc,
int i, int j) const {
bool bbmin = true;
double bmin = bins.begin()->first;
double bmax = bins.begin()->first;
ostringstream fname("");
for ( cPDVector::const_iterator p = proc.begin();
p != proc.end(); ++p )
fname << (**p).PDGName();
fname << "-" << i << "-" << j;
ofstream out((prefix+fname.str()+".dat").c_str());
for ( map<double,pair<double,double> >::const_iterator b = bins.begin();
b != bins.end(); ++b ) {
map<double,pair<double,double> >::const_iterator bp = b; --bp;
if ( b->second.first != Constants::MaxDouble ||
b->second.second != 0.0 ) {
if ( b != bins.begin() ){
out << bp->first;
if (bbmin){
bmin = bp->first;
bbmin = false;
}
}
else {
out << lower;
if (bbmin){
bmin = lower;
bbmin = false;
}
}
bmax = b->first;
out << " " << b->first
<< " " << b->second.first
<< " " << b->second.second
<< "\n" << flush;
}
}
double xmin = pow(10.0, floor(log10(bmin)));
double xmax = pow(10.0, ceil(log10(bmax)));
ofstream gpout((prefix+fname.str()+".gp").c_str());
gpout << "set terminal epslatex color solid\n"
<< "set output '" << fname.str() << "-plot.tex'\n"
<< "set format x '$10^{%T}$'\n"
<< "set logscale x\n"
<< "set xrange [" << xmin << ":" << xmax << "]\n";
if ( i != j ) {
gpout << "set xlabel '$\\sqrt{s_{" << i << j << "}}/{\\rm GeV}$'\n";
} else {
gpout << "set xlabel '$E_{" << i << "}/{\\rm GeV}$'\n";
}
if (plottype == 1){
gpout << "set size 0.5,0.6\n"
<< "set yrange [0:2]\n";
gpout << "plot 1 w lines lc rgbcolor \"#DDDDDD\" notitle, '" << fname.str()
<< ".dat' u (($1+$2)/2.):3:($4 < 4. ? $4 : 4.) w filledcurves lc rgbcolor \"#00AACC\" t '$";
}
else if (plottype == 2){
gpout << "set key left top Left reverse\n"
<< "set logscale y\n"
<< "set format y '$10^{%T}$'\n"
<< "set size 0.7,0.8\n"
<< "set yrange [1e-6:1e1]\n"
<< "set ylabel '$\\max\\left\\{\\left|\\mathcal{D}-\\mathcal{M}\\right|/\\left|\\mathcal{M}\\right|\\right\\}$'\n"
<< "unset bars\n";
gpout << "plot '";
if (scatterplot) gpout << fname.str() << "-scatter.dat' w points pt 7 ps 0.5 lc rgbcolor \"#00AACC\" not, \\\n'";
gpout << fname.str() << ".dat' u (($1+$2)/2.):4 w lines lw 4 lc rgbcolor \"#00AACC\" t '$";
}
for ( size_t k = 0; k < proc.size(); k++ ) {
if ( k == 2 )
gpout << "\\to ";
gpout << (proc[k]->id() < 0 ? "\\bar{" : "")
<< (proc[k]->id() < 0 ? proc[k]->CC()->PDGName() : proc[k]->PDGName())
<< (proc[k]->id() < 0 ? "}" : "") << " ";
}
gpout << "$'\n";
gpout << "reset\n";
}
void SubtractedME::lastEventSubtraction() {
tStdXCombGroupPtr xc = dynamic_ptr_cast<tStdXCombGroupPtr>(lastXCombPtr());
CrossSection xcme2 = xc->lastHeadCrossSection();
CrossSection xcdip = ZERO;
for ( vector<StdXCombPtr>::const_iterator d = xc->dependent().begin();
d != xc->dependent().end(); ++d ) {
if ( !(*d) )
continue;
if ( !(**d).matrixElement()->apply() )
continue;
if ( !(**d).willPassCuts() )
continue;
xcdip += (**d).lastCrossSection();
}
// want a real emission safely above the cut
if ( xc->cutWeight() < 1.0 )
return;
double delta;
if (factory()->subtractionPlotType() == 2) delta = abs(xcdip+xcme2)/abs(xcme2);
else delta = abs(xcdip)/abs(xcme2);
if ( theReal->phasespace() ) {
size_t i = lastSingularLimit()->first;
size_t j = lastSingularLimit()->second;
if ( i == j &&
softHistograms.find(SoftSubtractionIndex(head()->mePartonData(),i))
!= softHistograms.end() ) {
softHistograms[SoftSubtractionIndex(head()->mePartonData(),i)].
book(meMomenta()[i].t()/GeV,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesSoftSubtraction[SoftSubtractionIndex(head()->mePartonData(),i)]).c_str(),ofstream::app);
outstream << meMomenta()[i].t()/GeV << " " << delta << "\n";
}
}
if ( i != j &&
collinearHistograms.find(CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j)))
!= collinearHistograms.end() ) {
double s = sqrt(2.*meMomenta()[i]*meMomenta()[j])/GeV;
collinearHistograms[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))].
book(s,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesCollinearSubtraction[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))]).c_str(),ofstream::app);
outstream << s << " " << delta << "\n";
}
}
return;
}
for ( size_t i = 0; i < meMomenta().size(); ++i ) {
if ( i > 1 ) {
if ( softHistograms.find(SoftSubtractionIndex(head()->mePartonData(),i))
!= softHistograms.end() ) {
softHistograms[SoftSubtractionIndex(head()->mePartonData(),i)].
book(meMomenta()[i].t()/GeV,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesSoftSubtraction[SoftSubtractionIndex(head()->mePartonData(),i)]).c_str(),ofstream::app);
outstream << meMomenta()[i].t()/GeV << " " << delta << "\n";
}
}
}
for ( size_t j = i+1; j < meMomenta().size(); ++j ) {
if ( collinearHistograms.find(CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j)))
== collinearHistograms.end() )
continue;
double s = sqrt(2.*meMomenta()[i]*meMomenta()[j])/GeV;
collinearHistograms[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))].
book(s,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesCollinearSubtraction[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))]).c_str(),ofstream::app);
outstream << s << " " << delta << "\n";
}
}
}
}
void SubtractedME::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << theFactory << theBorns << theReal
<< collinearHistograms << softHistograms
<< fnamesSoftSubtraction
<< theRealShowerSubtraction << theVirtualShowerSubtraction
<< theLoopSimSubtraction
<< theSubProcessGroups;
}
void SubtractedME::persistentInput(PersistentIStream & is, int) {
is >> theLastXComb >> theFactory >> theBorns >> theReal
>> collinearHistograms >> softHistograms
>> fnamesSoftSubtraction
>> theRealShowerSubtraction >> theVirtualShowerSubtraction
>> theLoopSimSubtraction
>> theSubProcessGroups;
lastMatchboxXComb(theLastXComb);
}
void SubtractedME::Init() {
static ClassDocumentation<SubtractedME> documentation
("SubtractedME represents a subtracted real emission matrix element.");
}
// *** 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<SubtractedME,MEGroup>
describeHerwigSubtractedME("Herwig::SubtractedME", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc
@@ -1,220 +1,219 @@
// -*- C++ -*-
//
// MatchboxAmplitudeqqbarttbarg.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 MatchboxAmplitudeqqbarttbarg class.
//
#include "MatchboxAmplitudeqqbarttbarg.h"
#include "ThePEG/Interface/ClassDocumentation.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 "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudeqqbarttbarg::MatchboxAmplitudeqqbarttbarg() {}
MatchboxAmplitudeqqbarttbarg::~MatchboxAmplitudeqqbarttbarg() {}
IBPtr MatchboxAmplitudeqqbarttbarg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudeqqbarttbarg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudeqqbarttbarg::setupParams(map<string, double> &MGParams){
// create parameter map for adapted Madgraph amplitude to use
MGParams["aS"] = SM().alphaS();
MGParams["MZ"] = getParticleData(ParticleID::Z0) -> hardProcessMass()/GeV;
MGParams["MW"] = getParticleData(ParticleID::Wplus) -> hardProcessMass()/GeV;
MGParams["MH"] = getParticleData(ParticleID::h0) -> hardProcessMass()/GeV;
MGParams["WW"] = getParticleData(ParticleID::Wplus) ->hardProcessWidth()/GeV;
MGParams["WZ"] = getParticleData(ParticleID::Z0) ->hardProcessWidth()/GeV;
MGParams["WH"] = getParticleData(ParticleID::h0) ->hardProcessWidth()/GeV;
MGParams["MT"] = getParticleData(ParticleID::t) -> hardProcessMass()/GeV;
MGParams["MB"] = getParticleData(ParticleID::b) -> hardProcessMass()/GeV;
MGParams["WT"] = getParticleData(ParticleID::t) ->hardProcessWidth()/GeV;
MGParams["WB"] = getParticleData(ParticleID::b) ->hardProcessWidth()/GeV;
MGParams["MTA"] = getParticleData(ParticleID::tauminus)-> hardProcessMass()/GeV;
MGParams["GF"] = SM().fermiConstant()*GeV2;
MGParams["aEWM1"] = 1./SM().alphaEMMZ();
return;
}
void MatchboxAmplitudeqqbarttbarg::doinit() {
setupParams(MGParams_);
MatchboxAmplitude::doinit();
nPoints(5);
}
void MatchboxAmplitudeqqbarttbarg::doinitrun() {
setupParams(MGParams_);
MatchboxAmplitude::doinitrun();
nPoints(5);
}
bool MatchboxAmplitudeqqbarttbarg::canHandle(const PDVector& proc) const {
// check process is qqbar > ttbarg or some crossing of this
if ( proc.size() != 5 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator top = xproc.begin();
long topId = 0;
for ( ; top != xproc.end(); ++top )
if ( (**top).id() == 6 ) {
break;
}
if ( top == xproc.end() )
return false;
topId = (**top).id();
xproc.erase(top);
PDVector::iterator antiTop = xproc.begin();
for ( ; antiTop != xproc.end(); ++antiTop )
if ( (**antiTop).id() == -topId ) {
break;
}
if ( antiTop == xproc.end() )
return false;
xproc.erase(antiTop);
PDVector::iterator quark = xproc.begin();
long quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 6 &&
(**quark).id() > 0 ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
PDVector::iterator antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
return xproc[0]->id() == 21;
}
void MatchboxAmplitudeqqbarttbarg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudeqqbarttbarg::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
// check if doing qqbar, qg or qbarg initiated process
int crossed;
cPDVector partons = mePartonData();
if (abs(partons[0]->id())< 6 &&
partons[1]->id()==-partons[0]->id()) crossed=1;
else if (((partons[0]->id()>0 && partons[0]->id()<6) &&
partons[1]->id()==ParticleID::g) ||
((partons[1]->id()>0 && partons[1]->id()<6) &&
partons[0]->id()==ParticleID::g)) crossed=2;
else if (((partons[0]->id()<0 && partons[0]->id()>-6) &&
partons[1]->id()==ParticleID::g) ||
((partons[1]->id()<0 && partons[1]->id()>-6) &&
partons[0]->id()==ParticleID::g)) crossed=3;
else
- throw Exception() << "Unrecognised process in "
- << "MatchboxAmplitudeqqbarststbarg::evaluate\n"
+ throw Exception() << "MatchboxAmplitudeqqbarststbarg::evaluate(): Unrecognised process\n"
<< Exception::runerror;
// set up momenta to pass into Madgraph amplitude
vector<double*> p;
p.push_back(mom0); p.push_back(mom1); p.push_back(mom2); p.push_back(mom3); p.push_back(mom4);
for (int ip=0; ip<5; ++ip){
p[ip][0] = abs(momentum(ip).e())<1.e-13 ? 0.0:double(momentum(ip).e()*amplitudeScale()/GeV);
p[ip][1] = abs(momentum(ip).x())<1.e-13 ? 0.0:double(momentum(ip).x()*amplitudeScale()/GeV);
p[ip][2] = abs(momentum(ip).y())<1.e-13 ? 0.0:double(momentum(ip).y()*amplitudeScale()/GeV);
p[ip][3] = abs(momentum(ip).z())<1.e-13 ? 0.0:double(momentum(ip).z()*amplitudeScale()/GeV);
}
// calculate amplitudes
vector<complex<double> > amplitudes;
MG_qqx2ttxg process;
double factor=lastSHat()/GeV2;
process.initProc(MGParams_);
process.setMomenta(p);
process.sigmaKin(amplitudes, hel, crossed);
for (int iamp=0; iamp<int(amplitudes.size()); ++iamp)
amplitudes[iamp]*=sqrt(factor);
complex<double> matrixElement;
complex<double> i = complex<double>(0,1);
// calculate colour flows
if (a==0)
matrixElement = (1./6.)*(amplitudes[1] + amplitudes[2]);
else if (a==1)
matrixElement = 1./2.*( i*amplitudes[0] - amplitudes[1] - amplitudes[3]);
else if (a==2)
matrixElement = (1./6.)*( amplitudes[3] + amplitudes[4]);
else if (a==3)
matrixElement = 1./2.*(-i*amplitudes[0] - amplitudes[2] - amplitudes[4]);
else assert(false);
largeN = matrixElement;
return matrixElement;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudeqqbarttbarg::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudeqqbarttbarg::persistentInput(PersistentIStream &, int) {}
// *** 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<MatchboxAmplitudeqqbarttbarg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudeqqbarttbarg("Herwig::MatchboxAmplitudeqqbarttbarg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudeqqbarttbarg::Init() {
static ClassDocumentation<MatchboxAmplitudeqqbarttbarg> documentation
("MatchboxAmplitudeqqbarttbarg");
}
diff --git a/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.cc b/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.cc
--- a/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.cc
+++ b/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.cc
@@ -1,158 +1,164 @@
// -*- C++ -*-
//
// FrixionePhotonSeparationCut.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 FrixionePhotonSeparationCut class.
//
#include "FrixionePhotonSeparationCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/PDT/MatcherBase.h"
#include "ThePEG/PDT/StandardMatchers.h"
using namespace Herwig;
struct FrixionePartonInfo {
double DeltaR;
Energy pT;
double f;
};
void FrixionePhotonSeparationCut::describe() const {
CurrentGenerator::log()
- << fullName() << ":\n"
+ << fullName()
+ << " matching unresolved particles from '"
+ << matcher()->name() << "':\n"
<< "DeltaZero = " << theDeltaZero << " \n"
<< "Exponent n = " << theExponentn << " \n"
<< "Efficiency = " << theEfficiency << " \n"
<< "Cut Type = " << theCutType << " \n\n";
}
IBPtr FrixionePhotonSeparationCut::clone() const {
return new_ptr(*this);
}
IBPtr FrixionePhotonSeparationCut::fullclone() const {
return new_ptr(*this);
}
bool FrixionePhotonSeparationCut::passCuts(tcCutsPtr parent, const tcPDVector & ptype,
const vector<LorentzMomentum> & p) const {
if ( theDeltaZero <= 0 ) return true;
double weight = 1.0;
for ( int i = 0, N = ptype.size(); i < N; ++i )
if ( ptype[i]->id() == ParticleID::gamma ) {
vector<FrixionePartonInfo> partonvec;
for ( int j = 0, M = ptype.size(); j < M; ++j ) {
- long idj = ptype[j]->id();
- if ( !(idj && ( abs(idj) <= 5 || idj == ParticleID::g ) ) ) continue;
+ if ( !matcher()->matches(ptype[j]) ) continue;
FrixionePartonInfo finfo;
double dphi = abs(p[i].phi() - p[j].phi());
if ( dphi > Constants::pi ) dphi = 2.0*Constants::pi - dphi;
finfo.DeltaR = sqrt(sqr(p[i].eta() - p[j].eta()) + sqr(dphi));
if ( finfo.DeltaR < theDeltaZero ){
finfo.pT = p[j].perp();
finfo.f = pow((1-cos(finfo.DeltaR))/(1-cos(theDeltaZero)),theExponentn);
partonvec.push_back(finfo);
}
}
for ( unsigned int j = 0; j < partonvec.size(); ++j ) {
Energy chidelta=ZERO;
if (theCutType == 1) {
for ( unsigned int k = 0; k < partonvec.size(); ++k )
if ( partonvec[k].DeltaR <= partonvec[j].DeltaR ) chidelta += partonvec[k].pT;
}
else if (theCutType == 2) {
chidelta = partonvec[j].pT;
}
if ( !parent->isLessThan<CutTypes::Momentum>(chidelta,p[i].perp() * theEfficiency * partonvec[j].f,weight) ) {
parent->lastCutWeight(0.0);
return false;
}
}
}
parent->lastCutWeight(weight);
return true;
}
void FrixionePhotonSeparationCut::persistentOutput(PersistentOStream & os) const {
- os << theDeltaZero << theExponentn << theEfficiency << theCutType;
+ os << theDeltaZero << theExponentn << theEfficiency << theCutType << theMatcher;
}
void FrixionePhotonSeparationCut::persistentInput(PersistentIStream & is, int) {
- is >> theDeltaZero >> theExponentn >> theEfficiency >> theCutType;
+ is >> theDeltaZero >> theExponentn >> theEfficiency >> theCutType >> theMatcher;
}
ClassDescription<FrixionePhotonSeparationCut> FrixionePhotonSeparationCut::initFrixionePhotonSeparationCut;
// Definition of the static class description member.
void FrixionePhotonSeparationCut::Init() {
static ClassDocumentation<FrixionePhotonSeparationCut> documentation
("This class implements a separation criterium a la Frixione between "
"final-state partons and photons.");
static Parameter<FrixionePhotonSeparationCut,double> interfaceDeltaZero
("DeltaZero",
"The maximal legoplot separation up to which partons are included in the criterium ",
&FrixionePhotonSeparationCut::theDeltaZero, 0.7, 0.0, 10.0,
false, false, Interface::limited);
static Parameter<FrixionePhotonSeparationCut,double> interfaceExponentn
("Exponentn",
"The exponent n of the algorithm ",
&FrixionePhotonSeparationCut::theExponentn, 1.0, 0.0, 10.0,
false, false, Interface::limited);
static Parameter<FrixionePhotonSeparationCut,double> interfaceEfficiency
("Efficiency",
"The efficiency epsilon of the algorithm ",
&FrixionePhotonSeparationCut::theEfficiency, 1.0, 0.0, 10.0,
false, false, Interface::limited);
static Switch<FrixionePhotonSeparationCut,int> interfaceCutType
("CutType",
"Switch for controlling which definition of Frixione cut is used",
&FrixionePhotonSeparationCut::theCutType, 1, false, false);
static SwitchOption interfaceCutTypeVBFNLO
(interfaceCutType,
"VBFNLO",
"Switch to Frixione cut a la VBFNLO",
1);
static SwitchOption interfaceCutTypeMCFM
(interfaceCutType,
"MCFM",
"Switch to Frixione cut a la MCFM",
2);
+ static Reference<FrixionePhotonSeparationCut,MatcherBase> interfaceMatcher
+ ("UnresolvedMatcher",
+ "A matcher for particles to isolate on.",
+ &FrixionePhotonSeparationCut::theMatcher, false, false, true, false, false);
+
interfaceDeltaZero.setHasDefault(false);
interfaceExponentn.setHasDefault(false);
interfaceEfficiency.setHasDefault(false);
interfaceCutType.setHasDefault(false);
}
diff --git a/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.h b/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.h
--- a/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.h
+++ b/MatrixElement/Matchbox/Cuts/FrixionePhotonSeparationCut.h
@@ -1,176 +1,186 @@
// -*- C++ -*-
//
// FrixionePhotonSeparationCut.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_FrixionePhotonSeparationCut_H
#define Herwig_FrixionePhotonSeparationCut_H
//
// This is the declaration of the FrixionePhotonSeparationCut class.
//
#include "ThePEG/Cuts/MultiCutBase.h"
#include "ThePEG/PDT/MatcherBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Michael Rauch
*
* \brief This class implements a cut on legoplot and rapidity separation
*
* @see \ref FrixionePhotonSeparationCutInterfaces "The interfaces"
* defined for FrixionePhotonSeparationCut.
*/
class FrixionePhotonSeparationCut: public MultiCutBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FrixionePhotonSeparationCut() : theDeltaZero(0.0), theExponentn(1.0), theEfficiency(0.0), theCutType(1) {}
//@}
public:
/** @name Overridden virtual functions defined in the base class. */
//@{
/**
* Return true if a pair of particles with type \a pitype and \a
* pjtype and momenta \a pi and \a pj respectively passes the
* cuts. \a inci and \a inj indicates if the corresponding particles
* are incoming.
*/
virtual bool passCuts(tcCutsPtr, const tcPDVector & ptype,
const vector<LorentzMomentum> & p) const;
//@}
/**
* Describe the currently active cuts in the log file.
*/
virtual void describe() const;
+ /**
+ * Return the matcher for particles to isolate on.
+ */
+ Ptr<MatcherBase>::tptr matcher() const { return theMatcher; }
+
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;
//@}
private:
/**
* The maximal legoplot separation where partons are included in the criterium
*/
double theDeltaZero;
/**
* The exponent n of the algorithm
*/
double theExponentn;
/**
* The efficiency epsilon of the algorithm
*/
double theEfficiency;
/**
* The cut type of the algorithm
*/
int theCutType;
+ /**
+ * A matcher for particles to isolate on.
+ */
+ Ptr<MatcherBase>::ptr theMatcher;
+
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FrixionePhotonSeparationCut> initFrixionePhotonSeparationCut;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FrixionePhotonSeparationCut & operator=(const FrixionePhotonSeparationCut &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FrixionePhotonSeparationCut. */
template <>
struct BaseClassTrait<Herwig::FrixionePhotonSeparationCut,1> {
/** Typedef of the first base class of FrixionePhotonSeparationCut. */
typedef MultiCutBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FrixionePhotonSeparationCut class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FrixionePhotonSeparationCut>
: public ClassTraitsBase<Herwig::FrixionePhotonSeparationCut> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FrixionePhotonSeparationCut"; }
/** Return the name of the shared library be loaded to get
* access to the FrixionePhotonSeparationCut class and every other class it uses
* (except the base class). */
static string library() { return "HwMatchboxCuts.so"; }
};
/** @endcond */
}
#endif /* Herwig_FrixionePhotonSeparationCut_H */
diff --git a/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc b/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc
--- a/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc
+++ b/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc
@@ -1,148 +1,149 @@
// -*- C++ -*-
//
// IdentifiedParticleCut.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 IdentifiedParticleCut class.
//
#include "IdentifiedParticleCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IdentifiedParticleCut::IdentifiedParticleCut()
: thePtMin(0.*GeV), thePtMax(Constants::MaxEnergy) {}
IdentifiedParticleCut::~IdentifiedParticleCut() {}
IBPtr IdentifiedParticleCut::clone() const {
return new_ptr(*this);
}
IBPtr IdentifiedParticleCut::fullclone() const {
return new_ptr(*this);
}
bool IdentifiedParticleCut::passCuts(tcCutsPtr parent,
tcPDPtr ptype, LorentzMomentum p) const {
if ( !matcher()->matches(ptype) )
return true;
double weight = 1.0;
if ( !parent->isInside<CutTypes::Momentum>(p.perp(),ptMin(),ptMax(),weight) ) {
parent->lastCutWeight(0.0);
return false;
}
double y = p.rapidity() + parent->currentYHat();
for ( vector<pair<double,double> >::const_iterator dy = yRanges().begin();
dy != yRanges().end(); ++dy ) {
if ( !parent->isInside<CutTypes::Rapidity>(y,dy->first,dy->second,weight) ) {
parent->lastCutWeight(0.0);
return false;
}
}
parent->lastCutWeight(weight);
return true;
}
void IdentifiedParticleCut::describe() const {
CurrentGenerator::log()
- << "IdentifiedParticleCut '" << name() << "' matching ";
+ << "IdentifiedParticleCut '" << name() << "' matching "
+ << "'" << matcher()->name() << "'";
CurrentGenerator::log() << " within:\n";
CurrentGenerator::log()
<< "pt = " << ptMin()/GeV << " .. " << ptMax()/GeV << " GeV\n";
for ( vector<pair<double,double> >::const_iterator r = yRanges().begin();
r != yRanges().end(); ++r ) {
CurrentGenerator::log() << "y = " << r->first << " .. " << r->second << "\n";
}
}
string IdentifiedParticleCut::doYRange(string in) {
istringstream ins(in);
double first, second;
ins >> first >> second;
if ( first > second )
swap(first,second);
theYRanges.push_back(make_pair(first,second));
return "";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IdentifiedParticleCut::persistentOutput(PersistentOStream & os) const {
os << ounit(thePtMin,GeV) << ounit(thePtMax,GeV)
<< theYRanges << theMatcher;
}
void IdentifiedParticleCut::persistentInput(PersistentIStream & is, int) {
is >> iunit(thePtMin,GeV) >> iunit(thePtMax,GeV)
>> theYRanges >> theMatcher;
}
// *** 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<IdentifiedParticleCut,OneCutBase>
describeHerwigIdentifiedParticleCut("Herwig::IdentifiedParticleCut", "HwMatchboxCuts.so");
void IdentifiedParticleCut::Init() {
static ClassDocumentation<IdentifiedParticleCut> documentation
("IdentifiedParticleCut implements cuts on single momenta.");
static Parameter<IdentifiedParticleCut,Energy> interfacePtMin
("PtMin",
"The minimum pt required.",
&IdentifiedParticleCut::thePtMin, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<IdentifiedParticleCut,Energy> interfacePtMax
("PtMax",
"The maximum pt allowed.",
&IdentifiedParticleCut::thePtMax, GeV, Constants::MaxEnergy, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Command<IdentifiedParticleCut> interfaceYRange
("YRange",
"Insert a rapidity range.",
&IdentifiedParticleCut::doYRange, false);
static Reference<IdentifiedParticleCut,MatcherBase> interfaceMatcher
("Matcher",
"A matcher for particles to cut on.",
&IdentifiedParticleCut::theMatcher, false, false, true, false, false);
}
diff --git a/MatrixElement/Matchbox/Cuts/InvariantMassCut.h b/MatrixElement/Matchbox/Cuts/InvariantMassCut.h
--- a/MatrixElement/Matchbox/Cuts/InvariantMassCut.h
+++ b/MatrixElement/Matchbox/Cuts/InvariantMassCut.h
@@ -1,226 +1,228 @@
// -*- C++ -*-
//
// InvariantMassCut.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_InvariantMassCut_H
#define Herwig_InvariantMassCut_H
//
// This is the declaration of the InvariantMassCut class.
//
#include "ThePEG/Cuts/TwoCutBase.h"
#include "ThePEG/PDT/MatcherBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Michael Rauch
*
* \brief This class implements a cut on the invariant mass
*
* @see \ref InvariantMassCutInterfaces "The interfaces"
* defined for InvariantMassCut.
*/
class InvariantMassCut: public TwoCutBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
- InvariantMassCut() : theMinMass(0*GeV), theMaxMass(Constants::MaxEnergy), theSameFlavourOnly(true), theOppositeSignOnly(true) {}
+ InvariantMassCut() :
+ theMinMass(0*GeV), theMaxMass(Constants::MaxEnergy),
+ theSameFlavourOnly(false), theOppositeSignOnly(false) {}
//@}
public:
/** @name Overridden virtual functions defined in the base class. */
//@{
/**
* Return true if a pair of particles with type \a pitype and \a
* pjtype and momenta \a pi and \a pj respectively passes the
* cuts. \a inci and \a inj indicates if the corresponding particles
* are incoming.
*/
virtual bool passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype,
LorentzMomentum pi, LorentzMomentum pj,
bool inci = false, bool incj = false) const;
/**
* Return the minimum allowed squared invariant mass of two outgoing
* partons of type \a pi and \a pj.
*/
virtual Energy2 minSij(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of the negative of the squared
* invariant mass of an incoming parton of type \a pi and an
* outgoing parton of type \a po.
*/
virtual Energy2 minTij(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of \f$\Delta
* R_{ij}=\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ of two
* outgoing partons of type \a pi and \a pj.
*/
virtual double minDeltaR(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of the longitudinally invariant
* \f$k_\perp\f$-algorithms distance measure. This is defined as
* \f$\min(p_{\perp i}, p_{\perp
* j})\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ for two outgoing
* partons, or simply \f$p_{\perp i}\f$ or \f$p_{\perp j}\f$ for a
* single outgoing parton. Returns 0 if both partons are incoming. A
* null pointer indicates an incoming parton, hence the type of the
* incoming parton is irrelevant.
*/
virtual Energy minKTClus(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of the Durham
* \f$k_\perp\f$-algorithms distance measure. This is defined as
* \f$2\min(E_j^2, E_j^2)(1-\cos\theta_{ij})/\hat{s}\f$ for two
* outgoing partons.
*/
virtual double minDurham(tcPDPtr , tcPDPtr ) const { return ZERO; }
//@}
/**
* Describe the currently active cuts in the log file.
*/
virtual void describe() const;
public:
/**
* Return the minimal allowed invariant mass
*/
Energy minMass() const { return theMinMass; }
/**
* Return the maximal allowed invariant mass
*/
Energy maxMass() const { return theMaxMass; }
/**
* Return whether cut acts on same-flavour fermions only
*/
bool sameFlavourOnly() const { return theSameFlavourOnly; }
/**
* Return whether cut acts on opposite-sign fermions only
*/
bool oppositeSignOnly() const { return theOppositeSignOnly; }
/**
* Return the matchers for a pair of particles to cut on.
* Only a pair of particles, matching these objects, will be affected.
*/
Ptr<MatcherBase>::tptr firstMatcher() const { return theFirstMatcher; }
Ptr<MatcherBase>::tptr secondMatcher() const { return theSecondMatcher; }
protected:
/**
* Return the family of the given PDG id number.
*/
int family(long id) 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:
/** @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;
//@}
private:
/**
* The minimal allowed mass cut value
*/
Energy theMinMass;
/**
* The maximal allowed mass cut value
*/
Energy theMaxMass;
/**
* Whether the cut is active on same-flavour fermions only
* (ignored for pairs not consisting of two fermions)
*/
bool theSameFlavourOnly;
/**
* Whether the cut is active on opposite-sign fermions only
* (ignored for pairs not consisting of two fermions)
*/
bool theOppositeSignOnly;
/**
* Matchers for a pair of particles to cut on. Only a pair
* of particles, matching these objects, will be affected.
*/
Ptr<MatcherBase>::ptr theFirstMatcher;
Ptr<MatcherBase>::ptr theSecondMatcher;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
InvariantMassCut & operator=(const InvariantMassCut &);
};
}
#endif /* Herwig_InvariantMassCut_H */
diff --git a/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc b/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc
--- a/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc
+++ b/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc
@@ -1,189 +1,194 @@
// -*- C++ -*-
//
// MatchboxDeltaRCut.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 MatchboxDeltaRCut class.
//
#include "MatchboxDeltaRCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxDeltaRCut::MatchboxDeltaRCut()
- : theDeltaRMin(0.0), theDeltaRMax(Constants::MaxRapidity), theDeltaYMin(0.0), theDeltaYMax(Constants::MaxRapidity), theDeltaPhiMin(0.0), theDeltaPhiMax(2.0*Constants::pi) {}
+ : theDeltaRMin(0.0), theDeltaRMax(Constants::MaxRapidity),
+ theDeltaYMin(0.0), theDeltaYMax(Constants::MaxRapidity),
+ theDeltaPhiMin(0.0), theDeltaPhiMax(2.0*Constants::pi) {}
MatchboxDeltaRCut::~MatchboxDeltaRCut() {}
IBPtr MatchboxDeltaRCut::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxDeltaRCut::fullclone() const {
return new_ptr(*this);
}
bool MatchboxDeltaRCut::passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype,
LorentzMomentum pi, LorentzMomentum pj,
bool inci, bool incj) const {
bool match = false;
if ( theFirstMatcher->matches(*pitype) && theSecondMatcher->matches(*pjtype) ) match = true;
if ( theFirstMatcher->matches(*pjtype) && theSecondMatcher->matches(*pitype) ) match = true;
if ( !match ) return true;
if ( inci || incj ) return true;
double weight = 1.0;
double dY = abs(pi.rapidity() - pj.rapidity());
double dPhi = abs(pi.phi() - pj.phi());
if ( dPhi > Constants::pi ) dPhi = 2.0*Constants::pi - dPhi;
double dR = sqrt(sqr(dY) + sqr(dPhi));
if ( !parent->isInside<CutTypes::Rapidity>(dY,deltaYMin(),deltaYMax(),weight) )
{
parent->lastCutWeight(0.0);
return false;
}
if ( !parent->isInside<CutTypes::Azimuth>(dPhi,deltaPhiMin(),deltaPhiMax(),weight) )
{
parent->lastCutWeight(0.0);
return false;
}
if ( !parent->isInside<CutTypes::Rapidity>(dR,deltaRMin(),deltaRMax(),weight) )
{
parent->lastCutWeight(0.0);
return false;
}
parent->lastCutWeight(weight);
return true;
}
void MatchboxDeltaRCut::describe() const {
CurrentGenerator::log()
- << fullName() << ":\n"
+ << fullName() << "\n"
+ << "matching distances between: '"
+ << theFirstMatcher->name() << "' and '"
+ << theSecondMatcher->name() << "':\n"
<< "DeltaRMin = " << theDeltaRMin << " \n"
<< "DeltaRMax = " << theDeltaRMax << " \n"
<< "DeltaPhiMin = " << theDeltaPhiMin << " \n"
<< "DeltaPhiMax = " << theDeltaPhiMax << " \n"
<< "DeltaYMin = " << theDeltaYMin << " \n"
<< "DeltaYMax = " << theDeltaYMax << " \n"
<< "FirstMatcher = " << theFirstMatcher << " \n"
<< "SecondMatcher = " << theSecondMatcher << " \n\n";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxDeltaRCut::persistentOutput(PersistentOStream & os) const {
os << theDeltaYMin << theDeltaYMax
<< theDeltaPhiMin << theDeltaPhiMax
<< theDeltaRMin << theDeltaRMax
<< theFirstMatcher << theSecondMatcher;
}
void MatchboxDeltaRCut::persistentInput(PersistentIStream & is, int) {
is >> theDeltaYMin >> theDeltaYMax
>> theDeltaPhiMin >> theDeltaPhiMax
>> theDeltaRMin >> theDeltaRMax
>> theFirstMatcher >> theSecondMatcher;
}
// *** 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<MatchboxDeltaRCut,TwoCutBase>
describeHerwigMatchboxDeltaRCut("Herwig::MatchboxDeltaRCut", "HwMatchboxCuts.so");
void MatchboxDeltaRCut::Init() {
static ClassDocumentation<MatchboxDeltaRCut> documentation
("This class implements cuts on legoplot, rapidity and azimuthal separation, "
"i.e. on the \\f$\\Delta R\\f$-measure and on \\f$\\Delta Y\\f$ and \\f$\\Delta \\phi\\f$. "
"By default the cuts are only applied to coloured particles, but "
"may optionally be applied to all particle types. ");
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaRMin
("DeltaRMin",
"The minimum allowed for the legoplot distance "
"\\f$\\Delta R_{ij}=\\sqrt{\\Delta \\phi_{ij}^2+\\Delta Y_{ij}^2}\\f$ ",
&MatchboxDeltaRCut::theDeltaRMin, 0.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaRMax
("DeltaRMax",
"The maximum allowed for the legoplot distance "
"\\f$\\Delta R_{ij}=\\sqrt{\\Delta \\phi_{ij}^2+\\Delta Y_{ij}^2}\\f$ ",
&MatchboxDeltaRCut::theDeltaRMax, Constants::MaxRapidity, 0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaPhiMin
("DeltaPhiMin",
"The minimum allowed for the azimuthal separation "
"\\f$\\Delta \\phi_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaPhiMin, 0.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaPhiMax
("DeltaPhiMax",
"The maximum allowed for the azimuthal separation "
"\\f$\\Delta \\phi_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaPhiMax, 2.0*Constants::pi, 0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaYMin
("DeltaYMin",
"The minimum allowed for the rapidity separation "
"\\f$\\Delta Y_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaYMin, 0.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaYMax
("DeltaYMax",
"The maximum allowed for the rapidity separation "
"\\f$\\Delta Y_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaYMax, Constants::MaxRapidity, 0, 0,
false, false, Interface::lowerlim);
static Reference<MatchboxDeltaRCut,MatcherBase> interfaceFirstMatcher
("FirstMatcher",
"Matcher for first particle of type pitype in the pair (pitype,pjtype). "
"If non-null only particles matching this object will be affected "
"by the cut. ",
&MatchboxDeltaRCut::theFirstMatcher, true, false, true, true, false);
// &MatchboxDeltaRCut::theFirstMatcher, false, false, true, false, false);
static Reference<MatchboxDeltaRCut,MatcherBase> interfaceSecondMatcher
("SecondMatcher",
"Matcher for second particle of type pjtype in the pair (pitype,pjtype). "
"If non-null only particles matching this object will be affected "
"by the cut. ",
&MatchboxDeltaRCut::theSecondMatcher, true, false, true, true, false);
// &MatchboxDeltaRCut::theSecondMatcher, false, false, true, false, false);
}
diff --git a/MatrixElement/Matchbox/Cuts/MissingPtCut.cc b/MatrixElement/Matchbox/Cuts/MissingPtCut.cc
--- a/MatrixElement/Matchbox/Cuts/MissingPtCut.cc
+++ b/MatrixElement/Matchbox/Cuts/MissingPtCut.cc
@@ -1,167 +1,175 @@
// -*- C++ -*-
//
// MissingPtCut.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 MissingPtCut class.
//
#include "MissingPtCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.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/Repository/CurrentGenerator.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MissingPtCut::MissingPtCut()
: thePtMissMin(0.*GeV), thePtMissMax(Constants::MaxEnergy) {}
MissingPtCut::~MissingPtCut() {}
IBPtr MissingPtCut::clone() const {
return new_ptr(*this);
}
IBPtr MissingPtCut::fullclone() const {
return new_ptr(*this);
}
bool MissingPtCut::passCuts(tcCutsPtr parent, const tcPDVector & ptype,
const vector<LorentzMomentum> & p) const {
// Energy ptMissSum = 0.0*GeV;
LorentzMomentum momentumMissSum;
bool nonu = true;
for ( int i = 0, N = ptype.size(); i < N; ++i ) {
if ( invisibleParticles().size() == 0 ) {
- if ( abs(ptype[i]->id())==ParticleID::nu_e || abs(ptype[i]->id())==ParticleID::nu_mu || abs(ptype[i]->id())==ParticleID::nu_tau ) {
+ if ( matcher()->matches(ptype[i]) ) {
// ptMissSum = ptMissSum + p[i].perp();
momentumMissSum = momentumMissSum + p[i];
nonu = false;
}
}
else if ( invisibleParticles().size() != 0 ) {
for ( vector<int>::const_iterator iID = invisibleParticles().begin(); iID != invisibleParticles().end(); ++iID ) {
int iInt = *iID;
if ( abs(ptype[i]->id())==iInt ) {
// ptMissSum = ptMissSum + p[i].perp();
momentumMissSum = momentumMissSum + p[i];
nonu = false;
}
}
}
}
if ( nonu ) return true;
Energy ptMiss = momentumMissSum.perp();
double weight = 1.0;
// if ( !parent->isInside<CutTypes::Momentum>(ptMissSum,ptMissMin(),ptMissMax(),weight) ) {
if ( !parent->isInside<CutTypes::Momentum>(ptMiss,ptMissMin(),ptMissMax(),weight) ) {
parent->lastCutWeight(0.0);
return false;
}
parent->lastCutWeight(weight);
return true;
}
string MissingPtCut::doInvisibleParticles(string in) {
istringstream ins(in);
int first;
ins >> first;
theInvisibleParticles.push_back(first);
return "";
}
void MissingPtCut::describe() const {
CurrentGenerator::log()
- << "MissingPtCut '" << name() << "' matching ";
+ << "MissingPtCut '" << name() << "' matching "
+ << "'" << matcher()->name() << "'";
CurrentGenerator::log() << " within:\n";
CurrentGenerator::log()
<< "ptMiss = " << ptMissMin()/GeV << " .. " << ptMissMax()/GeV << " GeV\n";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MissingPtCut::persistentOutput(PersistentOStream & os) const {
// os << ounit(thePtMissMin,GeV) << ounit(thePtMissMax,GeV);
- os << ounit(thePtMissMin,GeV) << ounit(thePtMissMax,GeV) << theInvisibleParticles;
+ os << ounit(thePtMissMin,GeV) << ounit(thePtMissMax,GeV)
+ << theInvisibleParticles << theMatcher;
}
void MissingPtCut::persistentInput(PersistentIStream & is, int) {
// is >> iunit(thePtMissMin,GeV) >> iunit(thePtMissMax,GeV);
- is >> iunit(thePtMissMin,GeV) >> iunit(thePtMissMax,GeV) >> theInvisibleParticles;
+ is >> iunit(thePtMissMin,GeV) >> iunit(thePtMissMax,GeV)
+ >> theInvisibleParticles >> theMatcher;
}
// *** 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<MissingPtCut,MultiCutBase>
describeHerwigMissingPtCut("Herwig::MissingPtCut", "HwMatchboxCuts.so");
void MissingPtCut::Init() {
static ClassDocumentation<MissingPtCut> documentation
// ("MissingPtCut implements a cut on the missing transverse momentum "
// "of a set of outgoing particles, i.e. for now the total transverse momentum "
// "of all outgoing neutrinos in an event.");
("MissingPtCut implements a cut on the transverse momentum of the four-momentum "
"sum of a set of outgoing particles that cannot be detected. By default the three "
"standard model neutrinos are considered. If at least one undetectable particle "
"is specified through the InvisibleParticles interface, the default choice is "
"nullified.");
static Command<MissingPtCut> interfaceInvisibleParticles
("InvisibleParticles",
"Insert the PDG code of a particle that cannot be detected. If no particle "
"is inserted at all, the three standard model neutrinos are considered by "
"default. If at least one particle is inserted, the default choice is nullified.",
&MissingPtCut::doInvisibleParticles, false);
static Parameter<MissingPtCut,Energy> interfacePtMissMin
("PtMissMin",
"The minimum missing pt required.",
&MissingPtCut::thePtMissMin, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MissingPtCut,Energy> interfacePtMissMax
("PtMissMax",
"The maximum missing pt allowed.",
&MissingPtCut::thePtMissMax, GeV, Constants::MaxEnergy, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
+ static Reference<MissingPtCut,MatcherBase> interfaceMatcher
+ ("Matcher",
+ "A matcher for particles to cut on.",
+ &MissingPtCut::theMatcher, false, false, true, false, false);
+
}
diff --git a/MatrixElement/Matchbox/Cuts/MissingPtCut.h b/MatrixElement/Matchbox/Cuts/MissingPtCut.h
--- a/MatrixElement/Matchbox/Cuts/MissingPtCut.h
+++ b/MatrixElement/Matchbox/Cuts/MissingPtCut.h
@@ -1,178 +1,188 @@
// -*- C++ -*-
//
// MissingPtCut.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_MissingPtCut_H
#define Herwig_MissingPtCut_H
//
// This is the declaration of the MissingPtCut class.
//
#include "ThePEG/Cuts/MultiCutBase.h"
#include "ThePEG/PDT/MatcherBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Christian Reuschle
*
* \brief MissingPtCut implements a cut on the total missing transverse momentum of a set of outgoing particles, i.e. for now the total transverse momentum of all outgoing neutrinos in an event.
*
* @see \ref MissingPtCutInterfaces "The interfaces"
* defined for MissingPtCut.
*/
class MissingPtCut: public MultiCutBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
MissingPtCut();
/**
* The destructor.
*/
virtual ~MissingPtCut();
//@}
public:
/** @name Virtual functions to be overridden by sub-classes. */
//@{
/**
* Return the minimum allowed value of the squared invariant mass of
* a set of outgoing partons of the given types. Typically used to
* cut off the tails of the mass of a resonance for efficiency.
*/
virtual Energy2 minS(const tcPDVector) const { return ZERO; }
/**
* Return the maximum allowed value of the squared invariant mass of
* a set of outgoing partons of the given types. Typically used to
* cut off the tails of the mass of a resonance for efficiency.
*/
virtual Energy2 maxS(const tcPDVector) const { return Constants::MaxEnergy2; }
/**
* Return true if a set of outgoing particles with type \a ptype
* and corresponding momenta \a p passes the cuts.
*/
virtual bool passCuts(tcCutsPtr parent, const tcPDVector & ptype,
const vector<LorentzMomentum> & p) const;
/**
* Describe the currently active cuts in the log file.
*/
virtual void describe() const;
+
+ /**
+ * Return the matcher for particles to cut on.
+ */
+ Ptr<MatcherBase>::tptr matcher() const { return theMatcher; }
//@}
public:
/**
* Return the PDG codes of those particles that cannot be detected
*/
const vector<int>& invisibleParticles() const { return theInvisibleParticles; }
/**
* Command to insert the PDG code of a particle that cannot be detected
*/
string doInvisibleParticles(string);
/**
* Return the minimum missing pt.
*/
Energy ptMissMin() const { return thePtMissMin; }
/**
* Return the maximum missing pt.
*/
Energy ptMissMax() const { return thePtMissMax; }
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:
/**
* The PDG codes of those particles that cannot be detected
*/
vector<int> theInvisibleParticles;
/**
* The minimum missing pt.
*/
Energy thePtMissMin;
/**
* The maximum missing pt.
*/
Energy thePtMissMax;
+ /**
+ * A matcher for particles to cut on.
+ */
+ Ptr<MatcherBase>::ptr theMatcher;
+
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MissingPtCut & operator=(const MissingPtCut &);
};
}
#endif /* Herwig_MissingPtCut_H */
diff --git a/MatrixElement/Matchbox/Dipoles/SubtractionDipole.cc b/MatrixElement/Matchbox/Dipoles/SubtractionDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/SubtractionDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/SubtractionDipole.cc
@@ -1,1223 +1,1223 @@
// -*- C++ -*-
//
// SubtractionDipole.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 SubtractionDipole class.
//
#include "SubtractionDipole.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Utilities/Rebinder.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDF/PartonBin.h"
#include "ThePEG/PDF/PartonExtractor.h"
#include "Herwig++/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
#include "Herwig++/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
SubtractionDipole::SubtractionDipole()
: MEBase(), theSplitting(false), theApply(true), theSubtractionTest(false),
theIgnoreCuts(false),
theRealEmitter(-1), theRealEmission(-1), theRealSpectator(-1),
lastRealEmissionKey(realEmissionKey(cPDVector(),-1,-1,-1)),
lastUnderlyingBornKey(underlyingBornKey(cPDVector(),-1,-1)),
theBornEmitter(-1), theBornSpectator(-1),
theLastSubtractionScale(ZERO), theLastSplittingScale(ZERO),
theLastSubtractionPt(ZERO), theLastSplittingPt(ZERO),
theLastSubtractionZ(0.0), theLastSplittingZ(0.0),
theRealShowerSubtraction(false), theVirtualShowerSubtraction(false),
theLoopSimSubtraction(false), theRealEmissionScales(false),
theShowerHardScale(ZERO), theShowerScale(ZERO),
theIsInShowerPhasespace(false), theIsAboveCutoff(false) {}
SubtractionDipole::~SubtractionDipole() {}
double SubtractionDipole::alpha() const{
return factory()->alphaParameter();
}
void SubtractionDipole::clearBookkeeping() {
theRealEmitter = -1;
theRealEmission = -1;
theRealSpectator = -1;
theBornEmitter = -1;
theBornSpectator = -1;
theMergingMap.clear();
theSplittingMap.clear();
theIndexMap.clear();
theUnderlyingBornDiagrams.clear();
theRealEmissionDiagrams.clear();
}
void SubtractionDipole::setupBookkeeping(const map<Ptr<DiagramBase>::ptr,SubtractionDipole::MergeInfo>& mergeInfo) {
theMergingMap.clear();
theSplittingMap.clear();
theUnderlyingBornDiagrams.clear();
theRealEmissionDiagrams.clear();
int xemitter = -1;
int xspectator = -1;
map<int,int> mergeLegs;
map<int,int> remapLegs;
map<int,int> realBornMap;
map<int,int> bornRealMap;
for ( map<Ptr<DiagramBase>::ptr,MergeInfo>::const_iterator mit = mergeInfo.begin();
mit != mergeInfo.end(); ++mit ) {
DiagramVector::const_iterator bd =
theUnderlyingBornME->diagrams().end();
map<int,int> theRemapLegs;
for ( DiagramVector::const_iterator b =
theUnderlyingBornME->diagrams().begin();
b != theUnderlyingBornME->diagrams().end(); ++b )
if ( mit->second.diagram->isSame(*b,theRemapLegs) ) {
bd = b; break;
}
// no underlying Born
if ( bd == theUnderlyingBornME->diagrams().end() )
continue;
if ( xemitter == -1 ) {
xemitter = mit->second.emitter;
mergeLegs = mit->second.mergeLegs;
remapLegs = theRemapLegs;
assert(remapLegs.find(xemitter) != remapLegs.end());
xemitter = remapLegs[xemitter];
// work out the leg remapping real -> born
for ( map<int,int>::const_iterator k = mergeLegs.begin();
k != mergeLegs.end(); ++k ) {
assert(remapLegs.find(k->second) != remapLegs.end());
realBornMap[k->first] = remapLegs[k->second];
}
// work out the leg remapping born -> real
for ( map<int,int>::const_iterator k = realBornMap.begin();
k != realBornMap.end(); ++k ) {
bornRealMap[k->second] = k->first;
}
// work out the spectator
assert(mergeLegs.find(realSpectator()) != mergeLegs.end());
assert(remapLegs.find(mergeLegs[realSpectator()]) != remapLegs.end());
xspectator = realBornMap[realSpectator()];
}
RealEmissionKey realKey = realEmissionKey((*mit->first).partons(),realEmitter(),realEmission(),realSpectator());
UnderlyingBornKey bornKey = underlyingBornKey((**bd).partons(),xemitter,xspectator);
if ( theMergingMap.find(realKey) == theMergingMap.end() )
theMergingMap.insert(make_pair(realKey,make_pair(bornKey,realBornMap)));
RealEmissionInfo realInfo = make_pair(realKey,bornRealMap);
bool gotit = false;
typedef multimap<UnderlyingBornKey,RealEmissionInfo>::const_iterator spIterator;
pair<spIterator,spIterator> range = theSplittingMap.equal_range(bornKey);
for ( ; range.first != range.second; ++range.first )
if ( range.first->second == realInfo ) {
gotit = true;
break;
}
if ( !gotit ) {
theSplittingMap.insert(make_pair(bornKey,realInfo));
theUnderlyingBornDiagrams[process(realKey)].push_back(*bd);
theRealEmissionDiagrams[process(bornKey)].push_back(mit->first);
}
}
if ( theSplittingMap.empty() )
return;
theIndexMap.clear();
for ( multimap<UnderlyingBornKey,RealEmissionInfo>::const_iterator s =
theSplittingMap.begin(); s != theSplittingMap.end(); ++s ) {
theIndexMap[process(s->first)] = make_pair(emitter(s->first),spectator(s->first));
}
}
void SubtractionDipole::subtractionBookkeeping() {
/*
if ( theMergingMap.empty() )
setupBookkeeping();
*/
assert(!theMergingMap.empty());
lastRealEmissionKey =
realEmissionKey(lastHeadXComb().mePartonData(),realEmitter(),realEmission(),realSpectator());
map<RealEmissionKey,UnderlyingBornInfo>::const_iterator k =
theMergingMap.find(lastRealEmissionKey);
if ( k == theMergingMap.end() ) {
theApply = false;
return;
}
theApply = true;
lastUnderlyingBornKey = k->second.first;
bornEmitter(emitter(lastUnderlyingBornKey));
bornSpectator(spectator(lastUnderlyingBornKey));
}
void SubtractionDipole::splittingBookkeeping() {
/*
if ( theMergingMap.empty() )
setupBookkeeping();
*/
assert(!theMergingMap.empty());
map<cPDVector,pair<int,int> >::const_iterator esit =
theIndexMap.find(lastHeadXComb().mePartonData());
if ( esit == theIndexMap.end() ) {
theApply = false;
return;
}
theApply = true;
pair<int,int> es = esit->second;
bornEmitter(es.first);
bornSpectator(es.second);
lastUnderlyingBornKey = underlyingBornKey(lastHeadXComb().mePartonData(),bornEmitter(),bornSpectator());
typedef multimap<UnderlyingBornKey,RealEmissionInfo>::const_iterator spit;
pair<spit,spit> kr = theSplittingMap.equal_range(lastUnderlyingBornKey);
assert(kr.first != kr.second);
lastRealEmissionInfo = kr.first;
for ( ; lastRealEmissionInfo != kr.second; ++lastRealEmissionInfo )
if ( process(lastRealEmissionInfo->second.first) == lastXComb().mePartonData() )
break;
assert(lastRealEmissionInfo != kr.second);
lastRealEmissionKey = lastRealEmissionInfo->second.first;
realEmitter(emitter(lastRealEmissionKey));
realEmission(emission(lastRealEmissionKey));
realSpectator(spectator(lastRealEmissionKey));
}
StdXCombPtr SubtractionDipole::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& allBins,
tStdXCombPtr newHead,
tMEPtr newME) {
if ( !newME )
newME = this;
if ( !splitting() ) {
return
underlyingBornME()->makeXComb(newMaxEnergy, inc,
newEventHandler, newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts,
newDiagrams, mir, allBins,
newHead, newME);
}
return
realEmissionME()->makeXComb(newMaxEnergy, inc,
newEventHandler, newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts,
newDiagrams, mir, allBins,
newHead, newME);
}
StdXCombPtr SubtractionDipole::makeXComb(tStdXCombPtr newHead,
const PBPair & newPartonBins,
const DiagramVector & newDiagrams,
tMEPtr newME) {
if ( !newME )
newME = this;
if ( !splitting() ) {
return
underlyingBornME()->makeXComb(newHead, newPartonBins,
newDiagrams, newME);
}
return
realEmissionME()->makeXComb(newHead, newPartonBins,
newDiagrams, newME);
}
StdXCombPtr SubtractionDipole::makeBornXComb(tStdXCombPtr realXC) {
const cPDVector& proc = const_cast<const StandardXComb&>(*realXC).mePartonData();
lastRealEmissionKey =
realEmissionKey(proc,realEmitter(),realEmission(),realSpectator());
map<RealEmissionKey,UnderlyingBornInfo>::const_iterator k =
theMergingMap.find(lastRealEmissionKey);
if ( k == theMergingMap.end() )
return StdXCombPtr();
PartonPairVec pbs = realXC->pExtractor()->getPartons(realXC->maxEnergy(),
realXC->particles(),
*(realXC->cuts()));
DiagramVector bornDiags = underlyingBornDiagrams(proc);
assert(!bornDiags.empty());
PartonPairVec::iterator ppit = pbs.begin();
for ( ; ppit != pbs.end(); ++ppit ) {
if ( ppit->first->parton() == bornDiags.front()->partons()[0] &&
ppit->second->parton() == bornDiags.front()->partons()[1] )
break;
}
assert(ppit != pbs.end());
return
underlyingBornME()->makeXComb(realXC,*ppit,bornDiags,this);
}
vector<StdXCombPtr> SubtractionDipole::makeRealXCombs(tStdXCombPtr bornXC) {
const cPDVector& proc = const_cast<const StandardXComb&>(*bornXC).mePartonData();
map<cPDVector,pair<int,int> >::const_iterator esit = theIndexMap.find(proc);
if ( esit == theIndexMap.end() )
return vector<StdXCombPtr>();
pair<int,int> es = esit->second;
bornEmitter(es.first);
bornSpectator(es.second);
lastUnderlyingBornKey = underlyingBornKey(proc,bornEmitter(),bornSpectator());
if ( theSplittingMap.find(lastUnderlyingBornKey) == theSplittingMap.end() )
return vector<StdXCombPtr>();
PartonPairVec pbs = bornXC->pExtractor()->getPartons(bornXC->maxEnergy(),
bornXC->particles(),
*(bornXC->cuts()));
DiagramVector realDiags = realEmissionDiagrams(proc);
assert(!realDiags.empty());
vector<StdXCombPtr> res;
map<cPDVector,DiagramVector> realProcs;
for ( MEBase::DiagramVector::const_iterator d = realDiags.begin();
d != realDiags.end(); ++d ) {
realProcs[(**d).partons()].push_back(*d);
}
for ( map<cPDVector,DiagramVector>::const_iterator pr =
realProcs.begin(); pr != realProcs.end(); ++pr ) {
PartonPairVec::iterator ppit = pbs.begin();
for ( ; ppit != pbs.end(); ++ppit ) {
if ( ppit->first->parton() == pr->second.front()->partons()[0] &&
ppit->second->parton() == pr->second.front()->partons()[1] )
break;
}
assert(ppit != pbs.end());
StdXCombPtr rxc =
realEmissionME()->makeXComb(bornXC,*ppit,pr->second,this);
res.push_back(rxc);
}
return res;
}
const MEBase::DiagramVector& SubtractionDipole::underlyingBornDiagrams(const cPDVector& real) const {
static DiagramVector empty;
map<cPDVector,DiagramVector>::const_iterator k = theUnderlyingBornDiagrams.find(real);
if (k == theUnderlyingBornDiagrams.end() )
return empty;
return k->second;
}
const MEBase::DiagramVector& SubtractionDipole::realEmissionDiagrams(const cPDVector& born) const {
static DiagramVector empty;
map<cPDVector,DiagramVector>::const_iterator k = theRealEmissionDiagrams.find(born);
if ( k == theRealEmissionDiagrams.end() )
return empty;
return k->second;
}
void SubtractionDipole::getDiagrams() const {
if ( splitting() ) {
realEmissionME()->diagrams();
useDiagrams(realEmissionME());
} else {
underlyingBornME()->diagrams();
useDiagrams(underlyingBornME());
}
}
Selector<MEBase::DiagramIndex> SubtractionDipole::diagrams(const DiagramVector & dv) const {
Ptr<MatchboxMEBase>::tcptr me =
splitting() ?
realEmissionME() :
underlyingBornME();
if ( me->phasespace() ) {
me->phasespace()->setXComb(lastXCombPtr());
me->phasespace()->fillDiagramWeights();
}
return
me->diagrams(dv);
}
Selector<const ColourLines *>
SubtractionDipole::colourGeometries(tcDiagPtr diag) const {
return
splitting() ?
realEmissionME()->colourGeometries(diag) :
underlyingBornME()->colourGeometries(diag);
}
const ColourLines &
SubtractionDipole::selectColourGeometry(tcDiagPtr diag) const {
return
splitting() ?
realEmissionME()->selectColourGeometry(diag) :
underlyingBornME()->selectColourGeometry(diag);
}
void SubtractionDipole::flushCaches() {
theUnderlyingBornME->flushCaches();
theRealEmissionME->flushCaches();
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator r =
reweights().begin(); r != reweights().end(); ++r ) {
(**r).flushCaches();
}
}
void SubtractionDipole::setXComb(tStdXCombPtr xc) {
if ( !xc ) {
theApply = false;
return;
} else {
theApply = true;
}
lastMatchboxXComb(xc);
MEBase::setXComb(xc);
if ( splitting() ) {
realEmissionME()->setXComb(xc);
underlyingBornME()->setXComb(xc->head());
splittingBookkeeping();
} else {
realEmissionME()->setXComb(xc->head());
underlyingBornME()->setXComb(xc);
subtractionBookkeeping();
}
if ( !apply() )
return;
}
void SubtractionDipole::setKinematics() {
MEBase::setKinematics();
if ( splitting() )
realEmissionME()->setKinematics();
else
underlyingBornME()->setKinematics();
}
bool SubtractionDipole::generateKinematics(const double * r) {
if ( lastXCombPtr()->kinematicsGenerated() )
return true;
if ( splitting() ) {
if ( !generateRadiationKinematics(r) )
return false;
realEmissionME()->lastXCombPtr()->setIncomingPartons();
realEmissionME()->setScale();
double jac = jacobian();
jac *= pow(underlyingBornME()->lastXComb().lastSHat() / realEmissionME()->lastXComb().lastSHat(),
realEmissionME()->lastXComb().mePartonData().size()-4.);
jacobian(jac);
assert(lastXCombPtr() == realEmissionME()->lastXCombPtr());
lastXCombPtr()->didGenerateKinematics();
return true;
}
if ( !generateTildeKinematics() )
return false;
underlyingBornME()->lastXCombPtr()->setIncomingPartons();
underlyingBornME()->setScale();
assert(lastXCombPtr() == underlyingBornME()->lastXCombPtr());
underlyingBornME()->lastXCombPtr()->setIncomingPartons();
// need to have the scale and x's available for checking shower phase space
if ( showerApproximation() &&
lastXCombPtr()->willPassCuts() )
showerApproximation()->getShowerVariables();
lastXCombPtr()->didGenerateKinematics();
return true;
}
int SubtractionDipole::nDim() const {
if ( !splitting() )
return underlyingBornME()->nDim();
return underlyingBornME()->nDim() + nDimRadiation();
}
void SubtractionDipole::clearKinematics() {
MEBase::clearKinematics();
if ( splitting() )
realEmissionME()->clearKinematics();
else
underlyingBornME()->clearKinematics();
}
void SubtractionDipole::tildeKinematics(Ptr<TildeKinematics>::tptr tk) {
theTildeKinematics = tk;
}
bool SubtractionDipole::generateTildeKinematics() {
assert(!splitting());
Ptr<TildeKinematics>::tptr kinematics = theTildeKinematics;
if ( showerApproximation() ) {
showerApproximation()->setBornXComb(lastXCombPtr());
showerApproximation()->setRealXComb(realEmissionME()->lastXCombPtr());
showerApproximation()->setDipole(this);
showerApproximation()->checkCutoff();
if ( showerApproximation()->showerTildeKinematics() &&
isAboveCutoff() &&
realShowerSubtraction() )
kinematics = showerApproximation()->showerTildeKinematics();
}
if ( !kinematics ) {
jacobian(0.0);
return false;
}
kinematics->prepare(lastHeadXCombPtr(),lastXCombPtr());
if ( !kinematics->doMap() ) {
jacobian(0.0);
return false;
}
theLastSubtractionScale = kinematics->lastScale();
theLastSubtractionPt = kinematics->lastPt();
theLastSubtractionZ = kinematics->lastZ();
meMomenta().resize(lastHeadXComb().meMomenta().size() - 1);
assert(mergingMap().find(lastRealEmissionKey) != mergingMap().end());
map<int,int>& trans = theMergingMap[lastRealEmissionKey].second;
int n = lastHeadXComb().meMomenta().size();
for ( int k = 0; k < n; ++k ) {
if ( k == realEmitter() || k == realEmission() || k == realSpectator() )
continue;
meMomenta()[trans[k]] = lastHeadXComb().meMomenta()[k];
if ( kinematics->doesTransform() && k > 1 )
meMomenta()[trans[k]] = kinematics->transform(meMomenta()[trans[k]]);
}
meMomenta()[bornEmitter()] =
const_cast<const TildeKinematics&>(*kinematics).bornEmitterMomentum();
meMomenta()[bornSpectator()] =
const_cast<const TildeKinematics&>(*kinematics).bornSpectatorMomentum();
cPDVector::const_iterator pd = mePartonData().begin();
vector<Lorentz5Momentum>::iterator p = meMomenta().begin();
for ( ; pd != mePartonData().end(); ++pd, ++p ) {
p->setMass((**pd).hardProcessMass());
p->rescaleRho();
}
jacobian(realEmissionME()->lastXComb().jacobian());
logGenerateTildeKinematics();
return true;
}
void SubtractionDipole::invertedTildeKinematics(Ptr<InvertedTildeKinematics>::tptr itk) {
theInvertedTildeKinematics = itk;
}
int SubtractionDipole::nDimRadiation() const {
return invertedTildeKinematics() ?
invertedTildeKinematics()->nDimRadiation() :
0;
}
bool SubtractionDipole::generateRadiationKinematics(const double * r) {
assert(splitting());
Ptr<InvertedTildeKinematics>::tptr kinematics = theInvertedTildeKinematics;
if ( showerApproximation() ) {
showerApproximation()->setBornXComb(lastHeadXCombPtr());
showerApproximation()->setRealXComb(lastXCombPtr());
showerApproximation()->setDipole(this);
if ( showerApproximation()->showerInvertedTildeKinematics() ) {
kinematics = showerApproximation()->showerInvertedTildeKinematics();
}
}
if ( !kinematics ) {
jacobian(0.0);
return false;
}
kinematics->prepare(lastXCombPtr(),lastHeadXCombPtr());
if ( !kinematics->doMap(r) ) {
jacobian(0.0);
return false;
}
theLastSplittingScale = kinematics->lastScale();
theLastSplittingPt = kinematics->lastPt();
theLastSplittingZ = kinematics->lastZ();
meMomenta().resize(lastHeadXComb().meMomenta().size() + 1);
assert(splittingMap().find(lastUnderlyingBornKey) != splittingMap().end());
map<int,int>& trans = const_cast<map<int,int>&>(lastRealEmissionInfo->second.second);
int n = lastHeadXComb().meMomenta().size();
for ( int k = 0; k < n; ++k ) {
if ( k == bornEmitter() || k == bornSpectator() )
continue;
meMomenta()[trans[k]] = lastHeadXComb().meMomenta()[k];
if ( kinematics->doesTransform() && k > 1 )
meMomenta()[trans[k]] = kinematics->transform(meMomenta()[trans[k]]);
}
meMomenta()[realEmitter()] =
const_cast<const InvertedTildeKinematics&>(*kinematics).realEmitterMomentum();
meMomenta()[realEmission()] =
const_cast<const InvertedTildeKinematics&>(*kinematics).realEmissionMomentum();
meMomenta()[realSpectator()] =
const_cast<const InvertedTildeKinematics&>(*kinematics).realSpectatorMomentum();
cPDVector::const_iterator pd = mePartonData().begin();
vector<Lorentz5Momentum>::iterator p = meMomenta().begin();
for ( ; pd != mePartonData().end(); ++pd, ++p ) {
p->setMass((**pd).hardProcessMass());
p->rescaleRho();
}
jacobian(underlyingBornME()->lastXComb().jacobian() *
kinematics->jacobian());
logGenerateRadiationKinematics(r);
return true;
}
void SubtractionDipole::ptCut(Energy cut) {
theInvertedTildeKinematics->ptCut(cut);
}
CrossSection SubtractionDipole::dSigHatDR(Energy2 factorizationScale) const {
double pdfweight = 1.;
double jac = jacobian();
if ( splitting() && jac == 0.0 ) {
lastMECrossSection(ZERO);
lastME2(0.0);
return ZERO;
}
if ( factorizationScale == ZERO ) {
factorizationScale = underlyingBornME()->lastScale();
}
if ( havePDFWeight1() ) {
pdfweight *= realEmissionME()->pdf1(factorizationScale);
}
if ( havePDFWeight2() ) {
pdfweight *= realEmissionME()->pdf2(factorizationScale);
}
lastMEPDFWeight(pdfweight);
bool needTheDipole = true;
CrossSection shower = ZERO;
double lastThetaMu = 1.0;
double showerFactor = 1.;
if ( showerApproximation() ) {
assert(!splitting());
showerApproximation()->setBornXComb(lastXCombPtr());
showerApproximation()->setRealXComb(realEmissionME()->lastXCombPtr());
showerApproximation()->setDipole(const_cast<SubtractionDipole*>(this));
if ( !isAboveCutoff() ) {
showerApproximation()->wasBelowCutoff();
lastThetaMu = 0.0;
} else {
lastThetaMu = 1.0;
}
if ( lastThetaMu > 0.0 && isInShowerPhasespace() ) {
if ( realShowerSubtraction() )
shower = showerApproximation()->dSigHatDR()*lastThetaMu;
if ( virtualShowerSubtraction() || loopSimSubtraction() )
shower = -showerApproximation()->dSigHatDR()*lastThetaMu;
if ( virtualShowerSubtraction() &&
isAboveCutoff() &&
showerApproximation()->showerTildeKinematics() ) {
// map shower to dipole kinematics; we are always above the
// cutoff in this case
showerFactor *=
showerApproximation()->showerTildeKinematics()->jacobianRatio();
}
shower *= showerFactor;
}
if ( realShowerSubtraction() && lastThetaMu == 1.0 )
needTheDipole = false;
if ( virtualShowerSubtraction() && lastThetaMu == 0.0 )
needTheDipole = false;
if ( factory()->loopSimCorrections() ||
factory()->meCorrectionsOnly() )
needTheDipole = false;
}
double xme2 = 0.0;
if ( needTheDipole )
xme2 = me2();
if ( factory()->loopSimCorrections() ||
factory()->meCorrectionsOnly() ) {
assert(showerApproximation());
xme2 = realEmissionME()->me2() * showerApproximation()->channelWeight();
double rws =
pow(underlyingBornME()->lastXComb().lastAlphaS()/
realEmissionME()->lastXComb().lastAlphaS(),
realEmissionME()->orderInAlphaS());
xme2 *= rws;
double rwe =
pow(underlyingBornME()->lastXComb().lastAlphaEM()/
realEmissionME()->lastXComb().lastAlphaEM(),
underlyingBornME()->orderInAlphaEW());
xme2 *= rwe;
}
if ( realShowerSubtraction() )
xme2 *= 1. - lastThetaMu;
if ( virtualShowerSubtraction() || loopSimSubtraction() )
xme2 *= lastThetaMu;
double coupl = lastMECouplings();
coupl *= underlyingBornME()->lastXComb().lastAlphaS();
lastMECouplings(coupl);
lastME2(xme2);
CrossSection res =
sqr(hbarc) * jac * pdfweight * xme2 /
(2. * realEmissionME()->lastXComb().lastSHat());
if ( !showerApproximation() && xme2 != 0.0 ) {
double weight = 0.0;
bool applied = false;
for ( vector<Ptr<MatchboxReweightBase>::ptr>::const_iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
(**rw).setXComb(theRealEmissionME->lastXCombPtr());
if ( !(**rw).apply() )
continue;
weight += (**rw).evaluate();
applied = true;
}
if ( applied )
res *= weight;
}
lastMECrossSection(-res-shower);
logDSigHatDR(jac);
return lastMECrossSection();
}
void SubtractionDipole::print(ostream& os) const {
os << "--- SubtractionDipole setup ----------------------------------------------------\n";
os << " subtraction '" << name() << "'\n for real emission '"
<< theRealEmissionME->name() << "'\n using underlying Born '"
<< theUnderlyingBornME->name() << "'\n";
os << " tilde kinematics are '"
<< (theTildeKinematics ? theTildeKinematics->name() : "")
<< " '\n inverted tilde kinematics are '"
<< (theInvertedTildeKinematics ? theInvertedTildeKinematics->name() : "") << "'\n";
os << " the following subtraction mappings have been found:\n";
for ( map<RealEmissionKey,UnderlyingBornInfo>::const_iterator m =
theMergingMap.begin(); m != theMergingMap.end(); ++m ) {
os << " " << process(m->second.first)[0]->PDGName() << " "
<< process(m->second.first)[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = process(m->second.first).begin() + 2;
p != process(m->second.first).end(); ++p ) {
os << (**p).PDGName() << " ";
}
os << "[" << emitter(m->second.first) << "," << spectator(m->second.first) << "] <=> ";
os << process(m->first)[0]->PDGName() << " "
<< process(m->first)[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = process(m->first).begin() + 2;
p != process(m->first).end(); ++p ) {
os << (**p).PDGName() << " ";
}
os << "[(" << emitter(m->first) << "," << emission(m->first) << ")," << spectator(m->first) << "]\n"
<< " non-dipole momenta ( ";
for ( map<int,int>::const_iterator k = m->second.second.begin();
k != m->second.second.end(); ++k ) {
if ( k->first == spectator(m->first) )
continue;
os << k->second << " ";
}
os << ") <=> ( ";
for ( map<int,int>::const_iterator k = m->second.second.begin();
k != m->second.second.end(); ++k ) {
if ( k->first == spectator(m->first) )
continue;
os << k->first << " ";
}
os << ")\n";
}
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void SubtractionDipole::printLastEvent(ostream& os) const {
os << "--- SubtractionDipole last event information -----------------------------------\n";
os << " for dipole '" << name() << "' applying ["
<< bornEmitter() << "," << bornSpectator() << "] <=> [("
<< realEmitter() << "," << realEmission() << ")," << realSpectator() << "]\n"
<< " evaluated the cross section/nb " << (lastMECrossSection()/nanobarn) << "\n"
<< " with subtraction parameters x[0] = " << subtractionParameters()[0]
<< " x[1] = " << subtractionParameters()[1] << "\n";
os << " the last real emission event was:\n";
realEmissionME()->printLastEvent(os);
os << " the last underlying Born event was:\n";
underlyingBornME()->printLastEvent(os);
os << "--- end SubtractionDipole last event information -------------------------------\n";
os << flush;
}
void SubtractionDipole::logME2() const {
if ( !realEmissionME()->verbose() &&
!underlyingBornME()->verbose() )
return;
tcStdXCombPtr bornxc = splitting() ? lastHeadXCombPtr() : lastXCombPtr();
tcStdXCombPtr realxc = splitting() ? lastXCombPtr() : lastHeadXCombPtr();
generator()->log() << "'" << name() << "' evaluated me2 using\n"
<< "Born XComb " << bornxc << " real XComb " << realxc << "\n";
generator()->log() << "subtraction parameters: ";
copy(subtractionParameters().begin(),subtractionParameters().end(),
ostream_iterator<double>(generator()->log()," "));
generator()->log() << "\n";
generator()->log() << "Born phase space point (in GeV):\n";
vector<Lorentz5Momentum>::const_iterator pit = bornxc->meMomenta().begin();
cPDVector::const_iterator dit = bornxc->mePartonData().begin();
for ( ; pit != bornxc->meMomenta().end() ; ++pit, ++dit )
generator()->log() << (**dit).PDGName() << " : "
<< (*pit/GeV) << "\n";
generator()->log() << "with x1 = " << bornxc->lastX1() << " x2 = " << bornxc->lastX2() << "\n"
<< "sHat/GeV2 = " << (bornxc->lastSHat()/GeV2) << "\n";
generator()->log() << "Real emission phase space point (in GeV):\n";
pit = realxc->meMomenta().begin();
dit = realxc->mePartonData().begin();
for ( ; pit != realxc->meMomenta().end() ; ++pit, ++dit )
generator()->log() << (**dit).PDGName() << " : "
<< (*pit/GeV) << "\n";
generator()->log() << "with x1 = " << realxc->lastX1() << " x2 = " << realxc->lastX2() << "\n"
<< "sHat/GeV2 = " << (realxc->lastSHat()/GeV2) << "\n";
generator()->log() << "me2 = " << lastME2() << "\n" << flush;
}
void SubtractionDipole::logDSigHatDR(double effectiveJac) const {
if ( !realEmissionME()->verbose() &&
!underlyingBornME()->verbose() )
return;
tcStdXCombPtr bornxc = splitting() ? lastHeadXCombPtr() : lastXCombPtr();
tcStdXCombPtr realxc = splitting() ? lastXCombPtr() : lastHeadXCombPtr();
generator()->log() << "'" << name() << "' evaluated cross section using\n"
<< "Born XComb " << bornxc << " real XComb " << realxc << "\n"
<< "Jacobian = " << jacobian()
<< " effective Jacobian = " << effectiveJac << "\n"
<< "Born sHat/GeV2 = " << (bornxc->lastSHat()/GeV2)
<< " real sHat/GeV2 = " << (realxc->lastSHat()/GeV2)
<< " dsig/nb = "
<< (lastMECrossSection()/nanobarn) << "\n" << flush;
}
void SubtractionDipole::logGenerateTildeKinematics() const {
if ( !realEmissionME()->verbose() &&
!underlyingBornME()->verbose() )
return;
generator()->log() << "'" << name() << "' generating tilde kinematics.\n"
<< "configuration: [" << bornEmitter() << ","
<< bornSpectator() << "] => "
<< "[(" << realEmitter() << "," << realEmission() << "),"
<< realSpectator() << "]\n"
<< "with real xcomb " << lastHeadXCombPtr() << " born xcomb "
<< lastXCombPtr() << "\n"
<< "from real emission phase space point:\n";
Lorentz5Momentum rSum;
vector<Lorentz5Momentum>::const_iterator pr = lastHeadXComb().meMomenta().begin();
cPDVector::const_iterator dr = lastHeadXComb().mePartonData().begin();
size_t count = 0;
for ( ; pr != lastHeadXComb().meMomenta().end(); ++pr,++dr ) {
generator()->log() << (**dr).PDGName() << " : "
<< (*pr/GeV) << "\n";
if ( count < 2 ) {
rSum -= *pr;
} else {
rSum += *pr;
}
++count;
}
generator()->log() << "sum : " << (rSum/GeV) << "\n";
generator()->log() << "subtraction parameters: ";
copy(subtractionParameters().begin(),subtractionParameters().end(),
ostream_iterator<double>(generator()->log()," "));
generator()->log() << "\n"
<< "with scale/GeV = " << (theLastSubtractionScale/GeV)
<< "and pt/GeV = " << (theLastSubtractionPt/GeV) << "\n";
generator()->log() << "generated tilde kinematics:\n";
pr = lastXComb().meMomenta().begin();
dr = lastXComb().mePartonData().begin();
count = 0;
Lorentz5Momentum bSum;
for ( ; pr != lastXComb().meMomenta().end(); ++pr,++dr ) {
generator()->log() << (**dr).PDGName() << " : "
<< (*pr/GeV) << "\n";
if ( count < 2 ) {
bSum -= *pr;
} else {
bSum += *pr;
}
++count;
}
generator()->log() << "sum : " << (bSum/GeV) << "\n";
generator()->log() << "Jacobian = " << jacobian() << "\n" << flush;
}
void SubtractionDipole::logGenerateRadiationKinematics(const double * r) const {
if ( !realEmissionME()->verbose() &&
!underlyingBornME()->verbose() )
return;
generator()->log() << "'" << name() << "' generating radiation kinematics.\n"
<< "configuration: [" << bornEmitter() << ","
<< bornSpectator() << "] => "
<< "[(" << realEmitter() << "," << realEmission() << "),"
<< realSpectator() << "]\n"
<< "with born xcomb " << lastHeadXCombPtr() << " real xcomb "
<< lastXCombPtr() << "\n"
<< "from random numbers:\n";
copy(r,r+nDimRadiation(),ostream_iterator<double>(generator()->log()," "));
generator()->log() << "\n";
generator()->log() << "and born phase space point:\n";
vector<Lorentz5Momentum>::const_iterator pr = lastHeadXComb().meMomenta().begin();
cPDVector::const_iterator dr = lastHeadXComb().mePartonData().begin();
for ( ; pr != lastHeadXComb().meMomenta().end(); ++pr,++dr )
generator()->log() << (**dr).PDGName() << " : "
<< (*pr/GeV) << "\n";
generator()->log() << "subtraction parameters: ";
copy(subtractionParameters().begin(),subtractionParameters().end(),
ostream_iterator<double>(generator()->log()," "));
generator()->log() << "\n" << flush;
generator()->log() << "scales: scale/GeV = " << (theLastSplittingScale/GeV)
<< " pt/GeV = " << (theLastSplittingPt/GeV) << "\n" << flush;
generator()->log() << "generated real emission kinematics:\n";
pr = lastXComb().meMomenta().begin();
dr = lastXComb().mePartonData().begin();
for ( ; pr != lastXComb().meMomenta().end(); ++pr,++dr )
generator()->log() << (**dr).PDGName() << " : "
<< (*pr/GeV) << "\n";
generator()->log() << "Jacobian = "
<< jacobian() << " = "
<< underlyingBornME()->lastXComb().jacobian()
<< "|Born * "
<< invertedTildeKinematics()->jacobian()
<< "|Radiation\n" << flush;
}
void SubtractionDipole::doinit() {
MEBase::doinit();
if ( underlyingBornME() ) {
theUnderlyingBornME->init();
}
if ( realEmissionME() ) {
theRealEmissionME->init();
}
if ( tildeKinematics() ) {
theTildeKinematics->init();
}
if ( invertedTildeKinematics() ) {
theInvertedTildeKinematics->init();
}
if ( showerApproximation() ) {
theShowerApproximation->init();
}
for ( vector<Ptr<SubtractionDipole>::tptr>::iterator p = thePartners.begin();
p != thePartners.end(); ++p ) {
(**p).init();
}
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
(**rw).init();
}
}
void SubtractionDipole::doinitrun() {
MEBase::doinitrun();
if ( underlyingBornME() ) {
theUnderlyingBornME->initrun();
}
if ( realEmissionME() ) {
theRealEmissionME->initrun();
}
if ( tildeKinematics() ) {
theTildeKinematics->initrun();
}
if ( invertedTildeKinematics() ) {
theInvertedTildeKinematics->initrun();
}
if ( showerApproximation() ) {
theShowerApproximation->initrun();
}
for ( vector<Ptr<SubtractionDipole>::tptr>::iterator p = thePartners.begin();
p != thePartners.end(); ++p ) {
(**p).initrun();
}
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
(**rw).initrun();
}
}
void SubtractionDipole::cloneDependencies(const std::string& prefix) {
if ( underlyingBornME() ) {
Ptr<MatchboxMEBase>::ptr myUnderlyingBornME = underlyingBornME()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myUnderlyingBornME->name();
if ( ! (generator()->preinitRegister(myUnderlyingBornME,pname.str()) ) )
- throw InitException() << "Matrix element " << pname.str() << " already existing.";
+ throw InitException() << "SubtractionDipole::cloneDependencies(): Matrix element " << pname.str() << " already existing.";
myUnderlyingBornME->cloneDependencies(pname.str());
underlyingBornME(myUnderlyingBornME);
}
if ( realEmissionME() ) {
Ptr<MatchboxMEBase>::ptr myRealEmissionME = realEmissionME()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myRealEmissionME->name();
if ( ! (generator()->preinitRegister(myRealEmissionME,pname.str()) ) )
- throw InitException() << "Matrix element " << pname.str() << " already existing.";
+ throw InitException() << "SubtractionDipole::cloneDependencies(): Matrix element " << pname.str() << " already existing.";
myRealEmissionME->cloneDependencies(pname.str());
realEmissionME(myRealEmissionME);
}
if ( tildeKinematics() ) {
Ptr<TildeKinematics>::ptr myTildeKinematics = tildeKinematics()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myTildeKinematics->name();
if ( ! (generator()->preinitRegister(myTildeKinematics,pname.str()) ) )
- throw InitException() << "Tilde kinematics " << pname.str() << " already existing.";
+ throw InitException() << "SubtractionDipole::cloneDependencies(): Tilde kinematics " << pname.str() << " already existing.";
myTildeKinematics->dipole(this);
tildeKinematics(myTildeKinematics);
}
if ( invertedTildeKinematics() ) {
Ptr<InvertedTildeKinematics>::ptr myInvertedTildeKinematics = invertedTildeKinematics()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myInvertedTildeKinematics->name();
if ( ! (generator()->preinitRegister(myInvertedTildeKinematics,pname.str()) ) )
- throw InitException() << "Inverted tilde kinematics " << pname.str() << " already existing.";
+ throw InitException() << "SubtractionDipole::cloneDependencies(): Inverted tilde kinematics " << pname.str() << " already existing.";
myInvertedTildeKinematics->dipole(this);
invertedTildeKinematics(myInvertedTildeKinematics);
}
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 InitException() << "Reweight " << pname.str() << " already existing.";
+ throw InitException() << "SubtractionDipole::cloneDependencies(): Reweight " << pname.str() << " already existing.";
myReweight->cloneDependencies(pname.str());
*rw = myReweight;
}
}
void SubtractionDipole::constructVertex(tSubProPtr sub) {
if ( splitting() )
realEmissionME()->constructVertex(sub);
else
underlyingBornME()->constructVertex(sub);
}
void SubtractionDipole::constructVertex(tSubProPtr sub, const ColourLines* cl) {
if ( splitting() )
realEmissionME()->constructVertex(sub,cl);
else
underlyingBornME()->constructVertex(sub,cl);
}
void SubtractionDipole::generateSubCollision(SubProcess & sub) {
if ( splitting() )
realEmissionME()->generateSubCollision(sub);
else
underlyingBornME()->generateSubCollision(sub);
}
void SubtractionDipole::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << theSplitting << theApply << theSubtractionTest
<< theIgnoreCuts << theRealEmissionME << theUnderlyingBornME
<< thePartners << theTildeKinematics << theInvertedTildeKinematics
<< theReweights << theRealEmitter << theRealEmission << theRealSpectator
<< theSubtractionParameters << theMergingMap << theSplittingMap
<< theIndexMap << theUnderlyingBornDiagrams << theRealEmissionDiagrams
<< lastRealEmissionKey << lastUnderlyingBornKey
<< theBornEmitter << theBornSpectator << ounit(theLastSubtractionScale,GeV)
<< ounit(theLastSplittingScale,GeV) << ounit(theLastSubtractionPt,GeV)
<< ounit(theLastSplittingPt,GeV) << theLastSubtractionZ
<< theLastSplittingZ << theShowerApproximation
<< theRealShowerSubtraction << theVirtualShowerSubtraction
<< theLoopSimSubtraction << theRealEmissionScales << theFactory
<< ounit(theShowerHardScale,GeV) << ounit(theShowerScale,GeV)
<< theShowerParameters << theIsInShowerPhasespace << theIsAboveCutoff;
}
void SubtractionDipole::persistentInput(PersistentIStream & is, int) {
is >> theLastXComb >> theSplitting >> theApply >> theSubtractionTest
>> theIgnoreCuts >> theRealEmissionME >> theUnderlyingBornME
>> thePartners >> theTildeKinematics >> theInvertedTildeKinematics
>> theReweights >> theRealEmitter >> theRealEmission >> theRealSpectator
>> theSubtractionParameters >> theMergingMap >> theSplittingMap
>> theIndexMap >> theUnderlyingBornDiagrams >> theRealEmissionDiagrams
>> lastRealEmissionKey >> lastUnderlyingBornKey
>> theBornEmitter >> theBornSpectator >> iunit(theLastSubtractionScale,GeV)
>> iunit(theLastSplittingScale,GeV) >> iunit(theLastSubtractionPt,GeV)
>> iunit(theLastSplittingPt,GeV) >> theLastSubtractionZ
>> theLastSplittingZ >> theShowerApproximation
>> theRealShowerSubtraction >> theVirtualShowerSubtraction
>> theLoopSimSubtraction >> theRealEmissionScales >> theFactory
>> iunit(theShowerHardScale,GeV) >> iunit(theShowerScale,GeV)
>> theShowerParameters >> theIsInShowerPhasespace >> theIsAboveCutoff;
lastMatchboxXComb(theLastXComb);
typedef multimap<UnderlyingBornKey,RealEmissionInfo>::const_iterator spit;
pair<spit,spit> kr = theSplittingMap.equal_range(lastUnderlyingBornKey);
lastRealEmissionInfo = kr.first;
for ( ; lastRealEmissionInfo != kr.second; ++lastRealEmissionInfo )
if ( process(lastRealEmissionInfo->second.first) == lastXComb().mePartonData() )
break;
}
Ptr<MatchboxFactory>::tptr SubtractionDipole::factory() const {
return theFactory;
}
void SubtractionDipole::factory(Ptr<MatchboxFactory>::tptr f) {
theFactory = f;
}
void SubtractionDipole::Init() {
static ClassDocumentation<SubtractionDipole> documentation
("SubtractionDipole represents a dipole subtraction "
"term 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<SubtractionDipole,MEBase>
describeSubtractionDipole("Herwig::SubtractionDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc b/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc
--- a/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc
+++ b/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc
@@ -1,1045 +1,1045 @@
// -*- C++ -*-
//
// GoSamAmplitude.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 GoSamAmplitude class.
//
#include "GoSamAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Utilities/StringUtils.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include <boost/progress.hpp>
#include <boost/filesystem.hpp>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <exception>
using namespace Herwig;
namespace bfs = boost::filesystem;
#ifndef HERWIG_BINDIR
#error Makefile.am needs to define HERWIG_BINDIR
#endif
#ifndef HERWIG_PKGDATADIR
#error Makefile.am needs to define HERWIG_PKGDATADIR
#endif
#ifndef GOSAM_PREFIX
#error Makefile.am needs to define GOSAM_PREFIX
#endif
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
GoSamAmplitude::GoSamAmplitude() :
theAccuracyTarget(6),theCodeExists(false),theFormOpt(true),theNinja(true),
theHiggsEff(false),theMassiveLeptons(false),theLoopInducedOption(0),
isitDR(false),doneGoSamInit(false),doneGoSamInitRun(false),
bindir_(HERWIG_BINDIR), pkgdatadir_(HERWIG_PKGDATADIR), GoSamPrefix_(GOSAM_PREFIX)
{}
GoSamAmplitude::~GoSamAmplitude() {}
IBPtr GoSamAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr GoSamAmplitude::fullclone() const {
return new_ptr(*this);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void GoSamAmplitude::doinit() {
optionalContractFile() = name() + ".OLPContract.lh";
MatchboxOLPME::doinit();
doneGoSamInit = true;
}
void GoSamAmplitude::doinitrun() {
optionalContractFile() = name() + ".OLPContract.lh";
MatchboxOLPME::doinitrun();
doneGoSamInitRun = true;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
extern "C" void OLP_Start(const char*, int* i);
extern "C" void OLP_Polvec(double*, double*, double*);
extern "C" void OLP_SetParameter(char*, double*, double*, int*);
extern "C" void OLP_PrintParameter(char*);
extern "C" void OLP_EvalSubProcess2(int*, double*, double*, double*, double*);
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool GoSamAmplitude::startOLP(const map<pair<Process, int>, int>& procs) {
char char_cwd[256];
getcwd(char_cwd, sizeof(char_cwd));
string cwd = string(char_cwd);
string folderMatchboxBuild = factory()->buildStorage();
folderMatchboxBuild.erase(folderMatchboxBuild.begin());
// set all necessary path and file names
gosamPath = gosamPathInterface == "" ? cwd + folderMatchboxBuild + "GoSam" : gosamPathInterface;
// When transitioning to C++ 11 this length()-1 workaround can be replaced by string.back()
if (gosamPath.at(gosamPath.length()-1) != '/') gosamPath.append("/");
gosamSourcePath = gosamPath + "source/";
gosamInstallPath = gosamPath + "build/";
// create all the directories
if (!bfs::is_directory(gosamPath)){
try {
bfs::create_directory(gosamPath);
} catch (exception& e) {
cerr << "--------------------------------------------------------------------------------\n";
cerr << "The following exception occured:\n\n";
cerr << " " << e.what() << "\n\n";
cerr << " -> Please create the parent directory of\n";
cerr << " " << gosamPath << "\n";
cerr << " manually!\n";
cerr << "--------------------------------------------------------------------------------\n";
abort();
}
}
if (!bfs::is_directory(gosamSourcePath)) bfs::create_directory(gosamSourcePath);
if (!bfs::is_directory(gosamInstallPath)) bfs::create_directory(gosamInstallPath);
contractFileTitle = name() + ".OLPContract.lh";
contractFileName = gosamPath + "/" + contractFileTitle;
string orderFileName = gosamPath + "/" + name() + ".OLPOrder.lh";
// Set the path variable (plus file name) where to find the GoSam specific input file
gosamSetupInFileName = gosamSetupInFileNameInterface == "" ? gosamPath + "/setup.gosam.in" : gosamSetupInFileNameInterface;
// Use the python script GoSamHelper.py to make replacements in the GoSam
// specific input file at gosamSetupInFileName. If the GoSam input file
// does not exist yet at gosamSetupInFileName the python script will get
// it from src/defaults/ before making the replacements.
string cmd = "python "+bindir_+"/GoSamHelper.py ";
cmd+=" --usrinfile="+gosamSetupInFileNameInterface;
cmd+=" --infile="+gosamSetupInFileName+".tbu";
cmd+=" --definfile="+pkgdatadir_+"/defaults/setup.gosam.in";
cmd+=" --formtempdir="+StringUtils::replace(gosamSourcePath, string("/"), string("\\/")); //@FORMTEMPDIR@
cmd+=" --reduction="+(theNinja ? string("ninja,golem95") : string("samurai,golem95")); //@REDUCTIONPROGRAMS@
cmd+=" --formopt="+(theFormOpt ? string("") : string(", noformopt")); //@FORMOPT@
cmd+=" --higgseff="+(theHiggsEff ? string("smehc") : string("smdiag")); //@MODEL@
std::system(cmd.c_str());
if ( factory()->initVerbose() ) {
generator()->log() << "\n\n>>> NOTE: According to the repository settings for the GoSam interface:\n" << flush;
if (theHiggsEff) generator()->log() << "\n -- GoSam will use a model with an effective ggH coupling (model=smehc).\n" << flush;
else if (!theHiggsEff) generator()->log() << "\n -- GoSam will use its default model (model=smdiag).\n" << flush;
if (theNinja) generator()->log() << " -- GoSam will use Ninja as reduction program (reduction_programs=ninja,golem95).\n" << flush;
else if (!theNinja) generator()->log() << " -- GoSam will use Samurai as reduction program (reduction_programs=samurai,golem95).\n" << flush;
if (theFormOpt) generator()->log() << " -- Form optimization switched on (extensions=autotools).\n" << flush;
else if (!theFormOpt) generator()->log() << " -- Form optimization switched off (extensions=autotools, noformopt).\n" << flush;
- if (theNinja && !theFormOpt) throw Exception() << "\n\n>>> NOTE: Ninja reduction needs form optimization!\n" << Exception::abortnow;
+ if (theNinja && !theFormOpt) throw Exception() << "GoSamAmplitude: Ninja reduction needs form optimization!\n" << Exception::abortnow;
if (gosamSetupInFileNameInterface == "") {
generator()->log() << "\n Please be aware that you are using a copy of the default GoSam input file!\n"
<< " Please note that if you need special options to be considered for the specific\n"
<< " process you are looking at (diagram filtering, etc.) these are not automatically\n"
<< " set for you. In that case please consider to specify your own GoSam input file\n"
<< " via 'set " << name() << ":SetupInFilename' in the input file.\n\n" << flush;
}
// If one uses a custom GoSam input file at gosamSetupInFileName = gosamSetupInFileNameInterface
// then please note that not all options in there might match the corresponding Herwig repository
// options
if (gosamSetupInFileNameInterface != "") {
generator()->log() << "\n Please be aware that you are using a custom GoSam input file!\n"
<< " Please note that if you have set the options for model, reduction_programs,\n"
<< " extensions and/or form.tempdir manually these will of course not be replaced\n"
<< " by the corresponding repository settings mentioned above.\n\n" << flush;
}
generator()->log() << "\n>>> NOTE: GoSam may return the set of used parameters for this process via the OLP_PrintParameter() function:\n\n"
<< " -- If Debug::level > 1, the OLP parameters are being written to file: at " << factory()->runStorage() + name() + ".OLPParameters.lh.\n\n" << flush;
}
double accuracyTarget = 1.0/pow(10.0,accuracyTargetNegExp());
time_t rawtime;
time (&rawtime);
accuracyFileTitle = name() + ".OLPAccuracy.lh";
accuracyFile = factory()->buildStorage() + accuracyFileTitle;
ofstream accuracyFileStream;
if ( Debug::level > 1 ) {
accuracyFileStream.open(accuracyFile.c_str()); // Opening accuracyFile once here removes all previous content before the read step
accuracyFileStream << "\nFile to contain those PSPs for which GoSam evaluated one-loop interference terms or loop induced ME2s\n"
<< "with acc > target accuracy = " << accuracyTarget << ". Date/Time: " << ctime(&rawtime) << endl;
}
if ( factory()->initVerbose() ) {
generator()->log() << "\n>>> NOTE: GoSam will return the accuracy of one-loop interference terms or loop induced ME2s\n"
<< " at every PSP via the BLHA2 acc parameter:\n\n"
<< " -- In cases where acc > 10^-AccuracyTarget = " << accuracyTarget << " the corresponding PSPs are being dis-\n"
<< " carded.\n"
<< " -- The default value for AccuracyTarget is 6, but you may consider setting it otherwise\n"
<< " via 'set " << name() << ":AccuracyTarget' in the input file.\n"
<< " -- Currently the value for AccuracyTarget is set to " << accuracyTargetNegExp() << ".\n"
<< " -- If Debug::level > 1, the discarded PSPs are being written to file: at " + accuracyFile << ".\n"
<< " -- If the amount of PSPs with acc > " << accuracyTarget << " is significant, please consider to re-evaluate\n"
<< " your process setup (accuracy target, masses, cuts, etc.)!\n\n\n" << flush;
}
// check for old order file and create it if it doesn't already exist
fillOrderFile(procs, orderFileName);
ifstream ifile(contractFileName.c_str());
if(!ifile){
signOLP(orderFileName, contractFileName);
}
if ( !checkOLPContract(contractFileName) ) {
- throw Exception() << "failed to start GoSam" << Exception::abortnow;
+ throw Exception() << "GoSamAmplitude: failed to start GoSam" << Exception::abortnow;
}
if (!( DynamicLoader::load(gosamInstallPath+"/lib/libgolem_olp.so")
|| DynamicLoader::load(gosamInstallPath+"/lib64/libgolem_olp.so")
|| DynamicLoader::load(gosamInstallPath+"/lib/libgolem_olp.dylib")
|| DynamicLoader::load(gosamInstallPath+"/lib64/libgolem_olp.dylib"))) buildGoSam();
int status = -1;
startOLP(contractFileTitle, status);
if ( status != 1 ) return false;
return true;
}
void GoSamAmplitude::startOLP(const string& contract, int& status) {
string tempcontract = contract;
char char_cwd[256];
getcwd(char_cwd, sizeof(char_cwd));
string cwd = string(char_cwd);
string folderMatchboxBuild = factory()->buildStorage();
folderMatchboxBuild.erase(folderMatchboxBuild.begin());
gosamPath = gosamPathInterface == "" ? cwd + folderMatchboxBuild + "GoSam" : gosamPathInterface;
// When transitioning to C++ 11 this length()-1 workaround can be replaced by string.back()
if (gosamPath.at(gosamPath.length()-1) != '/') gosamPath.append("/");
if (!( DynamicLoader::load(gosamPath+"build/lib/libgolem_olp.so")
|| DynamicLoader::load(gosamPath+"build/lib64/libgolem_olp.so")
|| DynamicLoader::load(gosamPath+"build/lib/libgolem_olp.dylib")
|| DynamicLoader::load(gosamPath+"build/lib64/libgolem_olp.dylib")))
- throw Exception() << "Failed to load GoSam. Please check the log file.\n"
+ throw Exception() << "GoSamAmplitude: Failed to load GoSam. Please check the log file.\n"
<< Exception::abortnow;
tempcontract = gosamPath + tempcontract;
OLP_Start(tempcontract.c_str(), &status);
// hand over input parameters for EW scheme considered
int pStatus = 0;
double zero = 0.0;
if ( SM().ewScheme() == 0 || SM().ewScheme() == 6 ) { // EW/Scheme Default and EW/Scheme Independent
- throw Exception() << "`Best value' schemes are not supported by GoSam"
+ throw Exception() << "GoSamAmplitude: `Best value' schemes are not supported by GoSam"
<< Exception::abortnow;
} else if ( SM().ewScheme() == 4 ) { // EW/Scheme mW (uses mW,GF,sin2thetaW) seems not to be supported by GoSam
- throw Exception() << "`mW' scheme is not supported by GoSam"
+ throw Exception() << "GoSamAmplitude: `mW' scheme is not supported by GoSam"
<< Exception::abortnow;
} else if ( SM().ewScheme() == 1 ) { // EW/Scheme GMuScheme (uses mW,mZ,GF)
double in1=getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
double in2=getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV;
double in3=SM().fermiConstant()*GeV2;
OLP_SetParameter((char *)"mass(23)",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"mass(24)",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"Gf",&in3,&zero,&pStatus);
} else if ( SM().ewScheme() == 2 ) { // EW/Scheme alphaMZScheme (uses mW,mZ,alpha(mZ))
double in1=getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
double in2=getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV;
double in3=SM().alphaEMMZ();
OLP_SetParameter((char *)"mass(23)",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"mass(24)",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"alpha",&in3,&zero,&pStatus);
} else if ( SM().ewScheme() == 3 ) { // EW/Scheme NoMass (uses alpha(mZ),GF,sin2thetaW)
double in1=SM().fermiConstant()*GeV2;
double in2=SM().alphaEMMZ();
double in3=SM().sin2ThetaW();
OLP_SetParameter((char *)"Gf",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"alpha",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"sw2",&in3,&zero,&pStatus);
} else if ( SM().ewScheme() == 5 ) { // EW/Scheme mZ (uses mZ,alphaEM,sin2thetaW)
double in1=getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
double in2=SM().alphaEMMZ();
double in3=SM().sin2ThetaW();
OLP_SetParameter((char *)"mass(23)",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"alpha",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"sw2",&in3,&zero,&pStatus);
}
// hand over mass and width of the Higgs
double wH = getParticleData(25)->hardProcessWidth()/GeV;
double mH = getParticleData(25)->hardProcessMass()/GeV;
OLP_SetParameter((char*)"width(25)",&wH,&zero,&pStatus);
OLP_SetParameter((char*)"mass(25)",&mH,&zero,&pStatus);
// hand over initial input parameter for alphaS
double as = SM().alphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
// fill massive Particle vector
if (massiveParticles.empty()) {
// with quark masses
for (int i=1; i<=6; ++i)
if (getParticleData(i)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(i);
// with lepton masses
if (theMassiveLeptons && getParticleData(11)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(11);
if (theMassiveLeptons && getParticleData(13)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(13);
if (theMassiveLeptons && getParticleData(15)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(15);
}
// hand over quark (and possibly lepton) masses and widths (iff massive)
if ( massiveParticles.size() != 0 ) {
for ( vector<int>::const_iterator mID = massiveParticles.begin(); mID != massiveParticles.end(); ++mID ) {
string mstr;
string wstr;
int mInt = *mID;
double mass=getParticleData(mInt)->hardProcessMass()/GeV;
double width=getParticleData(mInt)->hardProcessWidth()/GeV;
std::stringstream ss;
ss << mInt;
string str = ss.str();
mstr="mass("+str+")";
wstr="width("+str+")";
char * mchar = new char[mstr.size()+1];
char * wchar = new char[wstr.size()+1];
std::copy(mstr.begin(),mstr.end(),mchar);
std::copy(wstr.begin(),wstr.end(),wchar);
mchar[mstr.size()] = '\0';
wchar[wstr.size()] = '\0';
OLP_SetParameter( mchar, &mass, &zero, &pStatus );
OLP_SetParameter( wchar, &width, &zero, &pStatus );
delete[] mchar;
delete[] wchar;
// Nicer but not working properly:
// double mass=getParticleData(*mID)->hardProcessMass()/GeV;
// double width=getParticleData(*mID)->hardProcessWidth()/GeV;
// string mstr="mass("+static_cast<ostringstream*>(&(ostringstream()<<(*mID)))->str()+")";
// string wstr="width("+static_cast<ostringstream*>(&(ostringstream()<<(*mID)))->str()+")";
// cout<<"\n massiv "<<mstr;
//
// OLP_SetParameter((char *)&mstr,&mass, &zero, &pStatus );
// OLP_SetParameter((char *)&wstr,&width, &zero, &pStatus );
}
}
// Note: In the GoSam input file, the standard is to set the parameter
// 'symmetries' for quark families and lepton generations, which allow
// for flavour changing only between families/generations. If this pa-
// rameter is set, GoSam won't allow to set electron and muon mass and
// width via the interface. Also setting mass and width for the tau is
// not yet considered.
// print OLP parameters
if ( Debug::level > 1 ) {
string ppstr = factory()->runStorage() + name() + ".OLPParameters.lh";
OLP_PrintParameter(const_cast<char*>(ppstr.c_str()));
}
didStartOLP() = true;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void GoSamAmplitude::fillOrderFile(const map<pair<Process, int>, int>& procs, string orderFileName) {
for ( map<pair<Process, int>, int>::const_iterator p = procs.begin() ; p != procs.end() ; ++p ) {
std::stringstream Processstr;
std::stringstream Typestr;
Processstr << (*p).first.first.legs[0]->id() << " " << (*p).first.first.legs[1]->id() << " -> ";
for ( PDVector::const_iterator o = (*p).first.first.legs.begin() + 2 ; o != (*p).first.first.legs.end() ; ++o )
Processstr << (**o).id() << " ";
if ( (*p).first.second == ProcessType::treeME2 ) {
Typestr << "Tree";
} else if ( (*p).first.second == ProcessType::loopInducedME2 ) {
Typestr << "LoopInduced";
} else if ( (*p).first.second == ProcessType::colourCorrelatedME2 ) {
Typestr << "ccTree";
} else if ( (*p).first.second == ProcessType::spinColourCorrelatedME2 ) {
Typestr << "scTree";
} else if ( (*p).first.second == ProcessType::oneLoopInterference ) {
Typestr << "Loop";
}
gosamprocinfo pro = gosamprocinfo((*p).second, -1, Processstr.str(), Typestr.str());
pro.setOAs(p->first.first.orderInAlphaS);
pro.setOAew(p->first.first.orderInAlphaEW);
processmap[(*p).second] = pro;
}
ifstream oldOrderFileStream(orderFileName.c_str());
if (oldOrderFileStream){
oldOrderFileStream.close();
return;
}
ofstream orderFile(orderFileName.c_str());
int asPower = 100;
int minlegs = 100;
int maxlegs = -1;
int maxasPower = -1;
int aewPower = 100;
int maxaewPower = -1;
for ( map<pair<Process, int>, int>::const_iterator t = procs.begin() ; t != procs.end() ; ++t ) {
asPower = min(asPower, static_cast<int>(t->first.first.orderInAlphaS));
minlegs = min(minlegs, static_cast<int>(t->first.first.legs.size()));
maxlegs = max(maxlegs, static_cast<int>(t->first.first.legs.size()));
maxasPower = max(maxasPower, static_cast<int>(t->first.first.orderInAlphaS));
aewPower = min(aewPower, static_cast<int>(t->first.first.orderInAlphaEW));
maxaewPower = max(maxaewPower, static_cast<int>(t->first.first.orderInAlphaEW));
}
orderFile << "# OLP order file created by Herwig++/Matchbox for GoSam\n\n";
orderFile << "InterfaceVersion BLHA2\n";
orderFile << "MatrixElementSquareType CHsummed\n";
orderFile << "CorrectionType QCD\n";
orderFile << "IRregularisation " << (isDR() ? "DRED" : "CDR") << "\n";
// loop over quarks to check if they have non-zero masses
for (int i=1; i<=6; ++i) if (getParticleData(i)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(i);
// check if leptons have non-zero masses (iff theMassiveLeptons==true)
if (theMassiveLeptons && getParticleData(11)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(11);
if (theMassiveLeptons && getParticleData(13)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(13);
if (theMassiveLeptons && getParticleData(15)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(15);
if ( massiveParticles.size() != 0 ) {
orderFile << "MassiveParticles ";
for ( vector<int>::const_iterator mID = massiveParticles.begin(); mID != massiveParticles.end(); ++mID ) {
int mInt = *mID;
orderFile << mInt << " ";
}
orderFile << "\n";
}
orderFile << "\n";
vector < string > types;
types.push_back("Tree");
types.push_back("LoopInduced");
types.push_back("ccTree");
types.push_back("scTree");
types.push_back("Loop");
for ( int i = asPower ; i != maxasPower + 1 ; i++ ) {
for ( int j = aewPower ; j != maxaewPower + 1 ; j++ ) {
orderFile << "\nAlphasPower " << i << "\n";
orderFile << "AlphaPower " << j << "\n";
for ( vector<string>::iterator it = types.begin() ; it != types.end() ; it++ ) {
if ( *it == "LoopInduced" ) continue;
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p )
if ( (*p).second.Tstr() == *it && i == (*p).second.orderAs() && j == (*p).second.orderAew() ) {
orderFile << "\nAmplitudeType " << *it << "\n";
break;
}
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p )
if ( (*p).second.Tstr() == *it && i == (*p).second.orderAs() && j == (*p).second.orderAew() ) {
orderFile << (*p).second.Pstr() << "\n";
}
}
}
}
// Write out the loop induced processes separately
int asPowerLI = 100;
int aewPowerLI = 100;
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p ) {
if ( (*p).second.Tstr() != "LoopInduced" ) continue;
if ( (*p).second.orderAs() != asPowerLI || (*p).second.orderAew() != aewPowerLI ) {
asPowerLI = (*p).second.orderAs();
aewPowerLI = (*p).second.orderAew();
// At the moment GoSam requires for qcd loop induced processes the as coupling power
// which would correspond to an associated fictitious Born process
orderFile << "\nAlphasPower " << (asPowerLI-2) << "\n";
orderFile << "AlphaPower " << aewPowerLI << "\n";
orderFile << "\nAmplitudeType " << "LoopInduced" << "\n";
}
orderFile << (*p).second.Pstr() << "\n";
}
orderFile << flush;
}
void GoSamAmplitude::signOLP(const string& order, const string& contract) {
if(!theCodeExists){
char char_cwd[256];
getcwd(char_cwd, sizeof(char_cwd));
string cwd = string(char_cwd);
string folderMatchboxBuild = factory()->buildStorage();
folderMatchboxBuild.erase(folderMatchboxBuild.begin());
generator()->log() << "\n>>> generating GoSam amplitudes. This may take some time, please be patient.\n"
<< ">>> see " + cwd + folderMatchboxBuild + "gosam-amplitudes.log for details.\n" << flush;
string cmd = GoSamPrefix_+"/bin/gosam.py --olp --output-file=" + contract + " --config=" +
gosamSetupInFileName+".tbu" + " --destination=" + gosamSourcePath + " " + order + " > " + cwd + folderMatchboxBuild + "gosam-amplitudes.log 2>&1";
std::system(cmd.c_str());
cmd = "python "+bindir_+"/GoSamHelper.py ";
cmd += " --makelink ";
cmd += " --makelinkfrom=contract ";
cmd += " --makelinkto="+factory()->buildStorage() + name() + ".OLPContract.lh";
std::system(cmd.c_str());
}
}
bool GoSamAmplitude::checkOLPContract(string contractFileName) {
ifstream infile(contractFileName.c_str());
string line;
vector < string > contractfile;
while (std::getline(infile, line)) contractfile.push_back(line);
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ ) {
bool righttype = false;
for ( vector<string>::iterator linex = contractfile.begin() ; linex != contractfile.end() ; ++linex ) {
if ( (*linex).find("AmplitudeType ")!= std::string::npos ) {
if ( (*linex).find(" " + (*p).second.Tstr() + " ")!= std::string::npos ) {
righttype = true;
} else {
righttype = false;
}
}
if ( righttype ) {
if ( (*linex).find((*p).second.Pstr()) != std::string::npos && (*p).second.Pstr().length() == (*linex).find("|") ) {
string sub = (*linex).substr((*linex).find("|") + 1, (*linex).find("#") - (*linex).find("|") - 1); // | 1 23 # buggy??
if ( sub.find(" 1 ") != 0 )
- throw Exception() << "Failed to check contractfile. Please check the logfile.\n"
+ throw Exception() << "GoSamAmplitude: Failed to check contractfile. Please check the logfile.\n"
<< Exception::abortnow;
string subx = sub.substr(3);
int subint;
istringstream(subx) >> subint;
(*p).second.setGID(subint);
}
}
}
}
string ids = factory()->buildStorage() + "GoSam.ids.dat";
ofstream IDS(ids.c_str());
idpair.clear();
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ )
idpair.push_back(-1);
idpair.push_back(-1);
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ ) {
idpair[(*p).second.HID()]=(*p).second.GID();
IDS << (*p).second.HID() << " " << (*p).second.GID() << " " << (*p).second.Tstr() << "\n";
if ( (*p).second.GID() == -1 ) return 0;
}
IDS << flush;
return 1;
}
bool GoSamAmplitude::buildGoSam() {
if(!theCodeExists){
generator()->log() << "\n>>> compiling GoSam amplitudes. This may take some time, please be patient.\n"
<< ">>> see " + gosamSourcePath + "gosam-build.log for details.\n\n" << flush;
string cmd = "cd " + gosamSourcePath + " && sh autogen.sh FCFLAGS=-g --prefix=" +
gosamInstallPath + " --disable-static > gosam-build.log 2>&1";
std::system(cmd.c_str());
if (!gosamBuildScript.empty()) {
cmd = "cd " + gosamSourcePath + " && " + gosamBuildScript + " >> gosam-build.log 2>&1";
std::system(cmd.c_str());
}
std::system(cmd.c_str());
cmd = "cd " + gosamSourcePath + " && make install >> gosam-build.log 2>&1";
std::system(cmd.c_str());
}
theCodeExists=true;
return 1;
}
void GoSamAmplitude::getids() const {
string line = factory()->buildStorage() + "GoSam.ids.dat";
ifstream infile(line.c_str());
int hid;
int gid;
string type;
while (std::getline(infile, line)) {
idpair.push_back(-1);
idtypepair.push_back(" ");
}
infile.close();
string line2 = factory()->buildStorage() + "GoSam.ids.dat";
ifstream infile2(line2.c_str());
idpair.push_back(-1);
idtypepair.push_back(" ");
while (std::getline(infile2, line2)) {
istringstream(line2) >> hid >> gid >> type;
idpair[hid]=gid;
idtypepair[hid]=type;
}
infile.close();
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void GoSamAmplitude::evalSubProcess() const {
useMe();
double units = pow(lastSHat() / GeV2, int(mePartonData().size()) - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int pStatus = 0;
double zero = 0.0;
double as;
as = lastAlphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
}
double out[7] = { };
double acc;
if ( idpair.size() == 0 ){ getids(); }
int id = -99;
if ( olpId()[ProcessType::loopInducedME2] ) id = olpId()[ProcessType::loopInducedME2];
else if ( olpId()[ProcessType::oneLoopInterference] ) id = olpId()[ProcessType::oneLoopInterference];
else id = olpId()[ProcessType::treeME2];
int callid(idpair[id]); // If id denotes the Herwig ID, this returns the GoSam ID
string calltype(idtypepair[id]); // If id denotes the Herwig ID, this returns the amplitude type
OLP_EvalSubProcess2(&(callid), olpMomenta(), &scale, out, &acc);
double accuracyTarget = 1.0/pow(10.0,accuracyTargetNegExp());
accuracyFileTitle = name() + ".OLPAccuracy.lh";
accuracyFile = factory()->buildStorage() + accuracyFileTitle;
ofstream accuracyFileStream;
if ( Debug::level > 1 ) {
accuracyFileStream.open(accuracyFile.c_str(),ios::app);
}
if ( (olpId()[ProcessType::oneLoopInterference]||olpId()[ProcessType::loopInducedME2]) && acc > accuracyTarget ) {
if ( Debug::level > 1 ) {
vector<Lorentz5Momentum> currentpsp = lastXComb().meMomenta();
time_t rawtime;
time (&rawtime);
if (doneGoSamInit) accuracyFileStream << "READ phase: ";
else if (doneGoSamInitRun) accuracyFileStream << "RUN phase: ";
accuracyFileStream << "Sub-process with Herwig ID = " << id << " and GoSam ID = " << callid << ", " << ctime(&rawtime);
accuracyFileStream << "GoSam evaluated one-loop interference or loop induced ME2 with acc = " << acc
<< " > target accuracy = " << accuracyTarget << ", at PSP [in units of GeV]:" << endl;
for (size_t i=0; i!=currentpsp.size(); ++i) {
accuracyFileStream << "(t,x,y,z,mass;m)[" << i << "]=("
<< currentpsp[i].t()/GeV << ","
<< currentpsp[i].x()/GeV << ","
<< currentpsp[i].y()/GeV << ","
<< currentpsp[i].z()/GeV << ","
<< currentpsp[i].mass()/GeV << ";"
<< currentpsp[i].m()/GeV << ")"
<< endl;
}
accuracyFileStream << endl;
}
throw Veto(); // Dispose of PSP
}
if ( olpId()[ProcessType::oneLoopInterference] ) {
if (calculateTreeME2()) lastTreeME2(out[3] * units);
lastOneLoopInterference((out[2])* units);
lastOneLoopPoles(pair<double, double>(out[0] * units, out[1] * units));
} else if ( olpId()[ProcessType::treeME2] ) {
lastTreeME2(out[3] * units);
} else if ( olpId()[ProcessType::loopInducedME2] ) {
lastTreeME2(out[2] * units);
}
}
void GoSamAmplitude::evalColourCorrelator(pair<int, int> ) const {
double units = pow(lastSHat() / GeV2, int(mePartonData().size()) - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int pStatus = 0;
double zero = 0.0;
double as;
as = lastAlphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
}
int n = lastXComb().meMomenta().size();
colourCorrelatorResults.resize(n * (n - 1) / 2);
if ( idpair.size() == 0 ) getids();
int callid(idpair[olpId()[ProcessType::colourCorrelatedME2]]);
double acc;
OLP_EvalSubProcess2(&(callid), olpMomenta(), &scale, &colourCorrelatorResults[0], &acc);
cPDVector particles = lastXComb().matrixElement()->mePartonData();
for ( int i = 0 ; i < n ; ++i ) {
for ( int j = i + 1 ; j < n ; ++j ) {
lastColourCorrelator(make_pair(i, j), colourCorrelatorResults[i+j*(j-1)/2] * units);
}
}
}
void GoSamAmplitude::evalSpinColourCorrelator(pair<int , int > ) const {
double units = pow(lastSHat() / GeV2, int(mePartonData().size()) - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int pStatus = 0;
double zero = 0.0;
double as;
as = lastAlphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
}
int n = lastXComb().meMomenta().size();
spinColourCorrelatorResults.resize(2*n*n);
if ( idpair.size() == 0 ) getids();
double acc;
int callid(idpair[olpId()[ProcessType::spinColourCorrelatedME2]]);
OLP_EvalSubProcess2(&(callid), olpMomenta(), &scale, &spinColourCorrelatorResults[0], &acc);
for ( int i = 0; i < n; ++i ) {
for ( int j = 0; j < n; ++j ) {
Complex scc(spinColourCorrelatorResults[2*i+2*n*j]*units, spinColourCorrelatorResults[2*i+2*n*j+1]*units);
lastColourSpinCorrelator(make_pair(i,j),scc);
}
}
}
LorentzVector<Complex> GoSamAmplitude::plusPolarization(const Lorentz5Momentum& p, const Lorentz5Momentum& n, int inc) const {
double pvec[4] = {p.t()/GeV,p.x()/GeV,p.y()/GeV,p.z()/GeV};
double nvec[4] = {n.t()/GeV,n.x()/GeV,n.y()/GeV,n.z()/GeV};
double out[8] ={ };
OLP_Polvec(pvec,nvec,out);
LorentzVector<Complex> res;
Complex a(out[0],out[1]);
res.setT(a);
Complex b(out[2],out[3]);
res.setX(b);
Complex c(out[4],out[5]);
res.setY(c);
Complex d(out[6],out[7]);
res.setZ(d);
if (inc<2)
return res.conjugate();
else
return res;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void GoSamAmplitude::persistentOutput(PersistentOStream & os) const {
os << idpair << idtypepair << processmap << gosamPathInterface
<< gosamSetupInFileNameInterface << gosamBuildScript << gosamPath
<< gosamSourcePath << gosamInstallPath << gosamSetupInFileName
<< orderFileTitle << contractFileTitle
<< contractFileName << orderFileName
<< theCodeExists << theFormOpt << theNinja << isitDR << massiveParticles << theHiggsEff
<< theAccuracyTarget << theMassiveLeptons << theLoopInducedOption
<< doneGoSamInit << doneGoSamInitRun
<< bindir_ << pkgdatadir_ << GoSamPrefix_;
}
void GoSamAmplitude::persistentInput(PersistentIStream & is, int) {
is >> idpair >> idtypepair >> processmap >> gosamPathInterface
>> gosamSetupInFileNameInterface >> gosamBuildScript >> gosamPath
>> gosamSourcePath >> gosamInstallPath >> gosamSetupInFileName
>> orderFileTitle >> contractFileTitle
>> contractFileName >> orderFileName
>> theCodeExists >> theFormOpt >> theNinja >> isitDR >> massiveParticles >> theHiggsEff
>> theAccuracyTarget >> theMassiveLeptons >> theLoopInducedOption
>> doneGoSamInit >> doneGoSamInitRun
>> bindir_ >> pkgdatadir_ >> GoSamPrefix_;
}
// *** 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<GoSamAmplitude, MatchboxOLPME> describeHerwigGoSamAmplitude("Herwig::GoSamAmplitude", "HwMatchboxGoSam.so");
void GoSamAmplitude::Init() {
static ClassDocumentation<GoSamAmplitude> documentation("GoSamAmplitude implements an interface to GoSam.", "Matrix elements have been calculated using GoSam");
static Parameter<GoSamAmplitude,string> interfaceProcessPath
("ProcessPath",
"Prefix for the process source code, include files and library produced by GoSam.",
&GoSamAmplitude::gosamPathInterface, "",
false, false);
static Parameter<GoSamAmplitude,string> interfaceSetupInFilename
("SetupInFilename",
"File name of the GoSam infile (typically setup.gosam.in) to be used. If left empty a new setup.gosam.in is created in the location specified in Path",
&GoSamAmplitude::gosamSetupInFileNameInterface, "",
false, false);
static Switch<GoSamAmplitude,bool> interfaceCodeExists
("CodeExists",
"Switch on or off if Code already exists/not exists.",
&GoSamAmplitude::theCodeExists, true, false, false);
static SwitchOption interfaceCodeExistsOn
(interfaceCodeExists,
"True",
"Switch True if Code already exists.",
true);
static SwitchOption interfaceCodeExistsOff
(interfaceCodeExists,
"False",
"Switch False if Code has to be build.",
false);
static Switch<GoSamAmplitude,bool> interfaceisitDR
("isDR",
"Switch on or off DR.",
&GoSamAmplitude::isitDR, false, false, false);
static SwitchOption interfaceisitDROn
(interfaceisitDR,
"True",
"Switch True.",
true);
static SwitchOption interfaceisitDROff
(interfaceisitDR,
"False",
"Switch False.",
false);
static Switch<GoSamAmplitude,bool> interfaceFormOpt
("FormOpt",
"Switch On/Off formopt",
&GoSamAmplitude::theFormOpt, true, false, false);
static SwitchOption interfaceFormOptOn
(interfaceFormOpt,
"On",
"On",
true);
static SwitchOption interfaceFormOptOff
(interfaceFormOpt,
"Off",
"Off",
false);
static Switch<GoSamAmplitude,bool> interfaceNinja
("Ninja",
"Switch On/Off for reduction with Ninja. If Off then Samurai is used.",
&GoSamAmplitude::theNinja, true, false, false);
static SwitchOption interfaceNinjaOn
(interfaceNinja,
"On",
"On",
true);
static SwitchOption interfaceNinjaOff
(interfaceNinja,
"Off",
"Off",
false);
static Switch<GoSamAmplitude,bool> interfaceHiggsEff
("HiggsEff",
"Switch On/Off for effective higgs model.",
&GoSamAmplitude::theHiggsEff, false, false, false);
static SwitchOption interfaceHiggsEffOn
(interfaceHiggsEff,
"On",
"On",
true);
static SwitchOption interfaceHiggsEffOff
(interfaceHiggsEff,
"Off",
"Off",
false);
static Parameter<GoSamAmplitude,string> interfaceBuildScript
("BuildScript",
"File name of a custom build script, which is called between 'autogen.sh'"
"and 'make install'. It can be used for parallelization.",
&GoSamAmplitude::gosamBuildScript, "",
false, false);
static Parameter<GoSamAmplitude,int> interfaceAccuracyTarget
("AccuracyTarget",
"Integer to parametrize the threshold value for the BLHA2 acc parameter, returned by GoSam in the case of "
"sub-processes with one-loop intereference terms or loop induced sub-processes."
"If acc > 10^-AccuracyTarget the corresponding PSP is being discarded. Discarded PSPs are written to file "
"if Debug::level > 1.",
&GoSamAmplitude::theAccuracyTarget, 6, 0, 0,
false, false, Interface::lowerlim);
static Switch<GoSamAmplitude,bool> interfaceMassiveLeptons
("MassiveLeptons",
"If set to Yes, then pass on the light lepton masses - as well as the tau mass - to GoSam."
"Otherwise GoSam will use light leptons of zero mass as default, as well as its own default tau mass.",
&GoSamAmplitude::theMassiveLeptons, false, false, false);
static SwitchOption interfaceMassiveLeptonsNo
(interfaceMassiveLeptons,
"No",
"No",
false);
static SwitchOption interfaceMassiveLeptonsYes
(interfaceMassiveLeptons,
"Yes",
"Yes",
true);
static Switch<GoSamAmplitude,int> interfaceLoopInducedOption
("LoopInducedOption",
"Options for the GoSam interface, in the case that a loop induced process is being considered. The default "
"option is 0, for which only the squared one-loop amplitude in the Standard Model is being considered. All "
"other options consider additional contributions from a model with an effective interaction, which lead to "
"the same final state, such as the squared effective amplitude, or the interference term between the one- "
"loop amplitude in the Standard Model and the effective amplitude, or any additive combinations therefrom. "
"In order to use those options an appropriate model has to be used.",
&GoSamAmplitude::theLoopInducedOption, 0, false, false);
static SwitchOption interfaceLoopInducedOptionLI2
(interfaceLoopInducedOption,
"LI2",
"Only consider the squared one-loop amplitude in the Standard Model.",
0);
static SwitchOption interfaceLoopInducedOptionEff2
(interfaceLoopInducedOption,
"Eff2",
"Only consider the squared effective amplitude.",
1);
static SwitchOption interfaceLoopInducedOptionLIEffInterference
(interfaceLoopInducedOption,
"LIEffInterference",
"Only consider the interference term between the one-loop amplitude "
"in the Standard Model and the effective amplitude.",
2);
static SwitchOption interfaceLoopInducedOptionLI2plusEff2
(interfaceLoopInducedOption,
"LI2plusEff2",
"Consider the sum of the squared one-loop amplitude in the Standard "
"Model plus the squared effective amplitude.",
3);
static SwitchOption interfaceLoopInducedOptionLI2plusLIEffInterference
(interfaceLoopInducedOption,
"LI2plusEffInterference",
"Consider the sum of the squared one-loop amplitude in the Standard "
"Model plus the interference term between the one-loop amplitude in "
"the Standard Model and the effective amplitude.",
4);
static SwitchOption interfaceLoopInducedOptionEff2plusLIEffInterference
(interfaceLoopInducedOption,
"Eff2plusEffInterference",
"Consider the sum of the squared effective amplitude plus the inter- "
"ference term between the one-loop amplitude in the Standard Model "
"and the effective amplitude.",
5);
static SwitchOption interfaceLoopInducedOptionAllAdditions
(interfaceLoopInducedOption,
"AllAdditions",
"Consider the sum of the squared one-loop amplitude in the Standard "
"Model plus all other contributions, which come with the effective "
"Model.",
6);
static Parameter<GoSamAmplitude,string> interfaceBinDir
("BinDir",
"The location for the installed executable",
&GoSamAmplitude::bindir_, string(HERWIG_BINDIR),
false, false);
static Parameter<GoSamAmplitude,string> interfacePKGDATADIR
("DataDir",
"The location for the installed Herwig++ data files",
&GoSamAmplitude::pkgdatadir_, string(HERWIG_PKGDATADIR),
false, false);
static Parameter<GoSamAmplitude,string> interfaceGoSamPrefix
("GoSamPrefix",
"The prefix for the location of GoSam",
&GoSamAmplitude::GoSamPrefix_, string(GOSAM_PREFIX),
false, false);
}
diff --git a/MatrixElement/Matchbox/External/HEJ/HEJFactory.cc b/MatrixElement/Matchbox/External/HEJ/HEJFactory.cc
--- a/MatrixElement/Matchbox/External/HEJ/HEJFactory.cc
+++ b/MatrixElement/Matchbox/External/HEJ/HEJFactory.cc
@@ -1,239 +1,239 @@
// -*- C++ -*-
//
// HEJFactory.cc 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 HEJFactory class.
//
#include "HEJFactory.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.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/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "HEJMEBase.h"
using namespace Herwig;
HEJFactory::HEJFactory()
: theNGluons(20),
theJetPTMin(20.*GeV), theExtremalPTMin(15.*GeV),
theScaleChoice(1),
theFixedScale(40.*GeV), theJets(0) {}
HEJFactory::~HEJFactory() {
if ( theJets ) {
MEs().clear();
delete theJets;
theJets = 0;
}
}
IBPtr HEJFactory::clone() const {
return new_ptr(*this);
}
IBPtr HEJFactory::fullclone() const {
return new_ptr(*this);
}
void HEJFactory::makeME(cPDPtr ini, cPDPtr inj, unsigned int n) {
theHEJME->firstIncoming(ini);
theHEJME->secondIncoming(inj);
theHEJME->nGluons(n);
ostringstream mename;
mename << fullName() << "/"
<< ini->PDGName() << inj->PDGName()
<< "to"
<< ini->PDGName() << inj->PDGName()
<< n << "g";
string pname = mename.str();
Ptr<HEJMEBase>::ptr myme = theHEJME->cloneMe();
if ( ! (generator()->preinitRegister(myme,pname) ) )
- throw InitException() << "Matrix element " << pname << " already existing.";
+ throw InitException() << "HEJFactory: Matrix element " << pname << " already existing.";
myme->cloneDependencies();
myme->factory(this);
MEs().push_back(myme);
}
SGeneratorFlags HEJFactory::setup(tStdXCombPtr) const {
SGeneratorFlags flags;
if ( abs(generator()->eventHandler()->incoming().first->id()) != ParticleID::pplus ||
abs(generator()->eventHandler()->incoming().second->id()) != ParticleID::pplus )
- throw Exception() << "can only handle proton/antiproton beams so far\n"
+ throw Exception() << "HEJFactory: Can only handle proton/antiproton beams so far\n"
<< Exception::abortnow;
flags.beam[0] = generator()->eventHandler()->incoming().first->id() > 0 ? 1 : -1;
flags.beam[1] = generator()->eventHandler()->incoming().second->id() > 0 ? 1 : -1;
flags.Ebeam = generator()->maximumCMEnergy()/2./GeV;
flags.partonptmax = flags.Ebeam;
if ( theExtremalPTMin > theJetPTMin )
- throw Exception() << "Minimum jet pt in Cuts needs to be smaller than HEJFactory:JetPTMin"
+ throw Exception() << "HEJFactory: Minimum jet pt in Cuts needs to be smaller than HEJFactory:JetPTMin"
<< Exception::abortnow;
flags.jetptmin = theJetPTMin/GeV;
flags.extpartonptmin = theExtremalPTMin/GeV;
flags.scale = theFixedScale/GeV;
flags.scalesetting = theScaleChoice;
/*
cerr << "HEJFactory settings:\n"
<< "flags.Ebeam = " << flags.Ebeam << "\n"
<< "flags.jetptmin = " << flags.jetptmin << "\n"
<< "flags.extpartonptmin = " << flags.extpartonptmin << "\n"
<< "flags.scalesetting = " << flags.scalesetting << "\n"
<< flush;
*/
return flags;
}
void HEJFactory::makeCMultijet(tStdXCombPtr xc) {
theJets = new CMultijet(setup(xc));
for ( MEVector::iterator m = MEs().begin();
m != MEs().end(); ++m )
dynamic_cast<HEJMEBase&>(**m).jets(theJets);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void HEJFactory::doinit() {
SubProcessHandler::doinit();
MEs().clear();
for ( unsigned int n = 0; n <= theNGluons; ++n ) {
for ( PDVector::const_iterator pi = theIncomingFlavours.begin();
pi != theIncomingFlavours.end(); ++pi ) {
for ( PDVector::const_iterator pj = pi;
pj != theIncomingFlavours.end(); ++pj ) {
makeME(*pi,*pj,n);
if ( *pi != *pj )
makeME(*pj,*pi,n);
}
}
}
}
void HEJFactory::persistentOutput(PersistentOStream & os) const {
os << theHEJME << theIncomingFlavours << theNGluons
<< ounit(theJetPTMin,GeV) << ounit(theExtremalPTMin,GeV)
<< theScaleChoice << ounit(theFixedScale,GeV);
}
void HEJFactory::persistentInput(PersistentIStream & is, int) {
is >> theHEJME >> theIncomingFlavours >> theNGluons
>> iunit(theJetPTMin,GeV) >> iunit(theExtremalPTMin,GeV)
>> theScaleChoice >> iunit(theFixedScale,GeV);
}
// *** 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<HEJFactory,SubProcessHandler>
describeHerwigHEJFactory("Herwig::HEJFactory", "HwHEJ.so");
void HEJFactory::Init() {
static ClassDocumentation<HEJFactory> documentation
("HEJFactory sets up HEJ matrix elements.");
static Reference<HEJFactory,HEJMEBase> interfaceHEJME
("HEJME",
"The HEJ matrix element to consider",
&HEJFactory::theHEJME, false, false, true, false, false);
static RefVector<HEJFactory,ParticleData> interfaceIncomingFlavours
("IncomingFlavours",
"The incoming flavours to take into account.",
&HEJFactory::theIncomingFlavours, -1, false, false, true, false, false);
static Parameter<HEJFactory,unsigned int> interfaceNGluons
("NGluons",
"The number of additional gluons to consider.",
&HEJFactory::theNGluons, 20, 0, 0,
false, false, Interface::lowerlim);
static Parameter<HEJFactory,Energy> interfaceJetPTMin
("JetPTMin",
"The minimum jet pt of the two hardest jets.",
&HEJFactory::theJetPTMin, GeV, 20.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<HEJFactory,Energy> interfaceExtremalPTMin
("ExtremalPTMin",
"The minimum jet pt of the extremal partons.",
&HEJFactory::theExtremalPTMin, GeV, 15.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<HEJFactory,int> interfaceScaleChoice
("ScaleChoice",
"The scale setting to use.",
&HEJFactory::theScaleChoice, 1, false, false);
static SwitchOption interfaceScaleChoiceFixedScale
(interfaceScaleChoice,
"FixedScale",
"Use a fixed scale.",
0);
static SwitchOption interfaceScaleChoiceHardestPt
(interfaceScaleChoice,
"HardestPt",
"Use the pt of the hardest jet.",
1);
static SwitchOption interfaceScaleChoiceGeometricMean
(interfaceScaleChoice,
"GeometricMean",
"Use the geometric mean scale choice.",
2);
static Parameter<HEJFactory,Energy> interfaceFixedScale
("FixedScale",
"The fixed scale value, if chosen.",
&HEJFactory::theFixedScale, GeV, 40.0*GeV, 0*GeV, 0*GeV,
false, false, Interface::lowerlim);
}
diff --git a/MatrixElement/Matchbox/External/MadGraph/MadGraphAmplitude.cc b/MatrixElement/Matchbox/External/MadGraph/MadGraphAmplitude.cc
--- a/MatrixElement/Matchbox/External/MadGraph/MadGraphAmplitude.cc
+++ b/MatrixElement/Matchbox/External/MadGraph/MadGraphAmplitude.cc
@@ -1,814 +1,814 @@
// -*- C++ -*-
//
// MadGraphAmplitude.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 MadGraphAmplitude class.
//
#include "MadGraphAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
#include <cstdlib>
#include <dlfcn.h>
#include <errno.h>
#include <sstream>
using namespace Herwig;
#ifndef HERWIG_BINDIR
#error Makefile.am needs to define HERWIG_BINDIR
#endif
#ifndef HERWIG_PKGDATADIR
#error Makefile.am needs to define HERWIG_PKGDATADIR
#endif
#ifndef MADGRAPH_PREFIX
#error Makefile.am needs to define MADGRAPH_PREFIX
#endif
extern "C" void mginitproc_(char *i,int);
extern "C" void MG_Calculate_wavefunctions_virt(int* proc,double*,double*);
extern "C" void MG_Calculate_wavefunctions_born(int* proc,double*, int*);
extern "C" void MG_Jamp (int* proc,int*, double*);
extern "C" void MG_LNJamp (int* proc,int*, double*);
extern "C" void MG_Virt (int* proc,double*);
extern "C" void MG_NCol (int* proc,int*);
extern "C" void MG_vxxxxx (double* p,double* n,int* inc,double* );
extern "C" void MG_Colour (int* proc,int* i,int* j ,int* color);
MadGraphAmplitude::MadGraphAmplitude()
: theMGmodel("loop_sm"),keepinputtopmass(false),
bindir_(HERWIG_BINDIR), pkgdatadir_(HERWIG_PKGDATADIR), madgraphPrefix_(MADGRAPH_PREFIX)
{}
MadGraphAmplitude::~MadGraphAmplitude() {
}
IBPtr MadGraphAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr MadGraphAmplitude::fullclone() const {
return new_ptr(*this);
}
bool MadGraphAmplitude::initializedMad=false;
vector<string> MadGraphAmplitude::BornAmplitudes=vector<string>();
vector<string> MadGraphAmplitude::VirtAmplitudes=vector<string>();
void MadGraphAmplitude::initProcess(const cPDVector& ) {
if ( lastMatchboxXComb()->initialized() )
return;
if ( !DynamicLoader::load(mgProcLibPath()+"InterfaceMadGraph.so") )
- throw Exception() << "Failed to load MadGraph amplitudes\n"
+ throw Exception() << "MadGraphAmplitude: Failed to load MadGraph amplitudes\n"
<< DynamicLoader::lastErrorMessage
<< Exception::abortnow;
if (!initializedMad){
string mstr=(factory()->runStorage()+"MadGraphAmplitudes"+"/param_card"+((theMGmodel=="loop_sm")?"":("_"+theMGmodel))+".dat");
size_t len = mstr.size();
mginitproc_(const_cast<char*>(mstr.c_str()),len);
initializedMad=true;
}
lastMatchboxXComb()->isInitialized();
}
bool MadGraphAmplitude::writeAmplitudesDat(){
bool res=false;
string born= mgProcLibPath()+"BornAmplitudes.dat";
if ( !boost::filesystem::exists(born) ) {
ofstream borns(born.c_str());
for (vector<string>::iterator amps=BornAmplitudes.begin();amps!=BornAmplitudes.end();amps++)
borns<<*amps<<endl;
borns.close();
res=true;
}
string virt= mgProcLibPath()+"VirtAmplitudes.dat";
if ( !boost::filesystem::exists(virt) ) {
ofstream virts(virt.c_str());
for (vector<string>::iterator amps=VirtAmplitudes.begin();amps!=VirtAmplitudes.end();amps++)
virts<<*amps<<endl;
virts.flush();
virts.close();
res=true;
}
return res;
}
bool MadGraphAmplitude::checkAmplitudes(){
string born= mgProcLibPath()+"BornAmplitudes.dat";
string virt= mgProcLibPath()+"VirtAmplitudes.dat";
assert ( boost::filesystem::exists(born)|| boost::filesystem::exists(virt));
bool foundallborns=true;
for (vector<string>::iterator amps=BornAmplitudes.begin();amps!=BornAmplitudes.end();amps++){
ifstream borns(born.c_str());
string line;
bool foundthisborn=false;
while (std::getline(borns, line)) {
if(line==*amps)foundthisborn=true;
}
foundallborns&=foundthisborn;
}
bool foundallvirts=true;
for (vector<string>::iterator amps=VirtAmplitudes.begin();amps!=VirtAmplitudes.end();amps++){
ifstream virts(virt.c_str());
string line;
bool foundthisvirt=false;
while (std::getline(virts, line)) {
if(line==*amps)foundthisvirt=true;
}
foundallvirts&=foundthisvirt;
}
if (!foundallborns||!foundallvirts)
- throw Exception() << "One amplitude has no externalId. Please remove the MadGraphAmplitude-folder and rebuild.\n" << Exception::abortnow;
+ throw Exception() << "MadGraphAmplitude: One amplitude has no externalId. Please remove the MadGraphAmplitude-folder and rebuild.\n" << Exception::abortnow;
return foundallborns && foundallvirts;
}
string MadGraphAmplitude::mgProcLibPath(){
string res=theProcessPath == "" ? factory()->buildStorage()+"MadGraphAmplitudes" : theProcessPath;
if (res.at(res.length()-1) != '/') res.append("/");
return res;
}
bool MadGraphAmplitude::initializeExternal() {
if ( boost::filesystem::exists(mgProcLibPath()) ) {
if ( !boost::filesystem::is_directory(mgProcLibPath()) )
- throw Exception() << "MadGraph amplitude storage '"
+ throw Exception() << "MadGraphAmplitude: MadGraph amplitude storage '"
<< mgProcLibPath() << "' existing but not a directory."
<< Exception::abortnow;
} else {
boost::filesystem::create_directories(mgProcLibPath());
}
string runAmplitudes = factory()->runStorage() + "/MadGraphAmplitudes";
if ( boost::filesystem::exists(runAmplitudes) ) {
if ( !boost::filesystem::is_directory(runAmplitudes) )
- throw Exception() << "MadGraph amplitude storage '"
+ throw Exception() << "MadGraphAmplitude: MadGraph amplitude storage '"
<< runAmplitudes << "' existing but not a directory."
<< Exception::abortnow;
} else {
boost::filesystem::create_directories(runAmplitudes);
}
//EW-consistency check:
Energy MW=getParticleData(ParticleID::Wplus)->hardProcessMass();
Energy MZ=getParticleData(ParticleID::Z0)->hardProcessMass();
if( MW!= sqrt(MZ*MZ/2.0+sqrt(MZ*MZ*MZ*MZ/4.0-Constants::pi*SM().alphaEMMZ()*MZ*MZ/ sqrt(2.0)/SM().fermiConstant()))){
generator()->log()<<"\n\n-----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-----";
generator()->log() << "\nYou are using a EW scheme which is inconsistent with the MadGraph parametisation:\n\n"
<<MW/GeV<< " GeV==MW!= sqrt(MZ^2/2+sqrt(MZ^4/4.0-pi*alphaEMMZ*MZ^2/ sqrt(2)/G_f))=="<<
sqrt(MZ*MZ/2.0+sqrt(MZ*MZ*MZ*MZ/4.0-Constants::pi*SM().alphaEMMZ()*MZ*MZ/ sqrt(2.0)/SM().fermiConstant()))/GeV
<<" GeV\n\n-----!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-----\n";
}
string para= factory()->runStorage()+"/MadGraphAmplitudes"+"/MG-Parameter.dat";
ofstream params(para.c_str());
params<<"$WZ$ " <<std::setiosflags(ios::scientific) <<getParticleData(ParticleID::Z0)->hardProcessWidth() /GeV;
params<<"\n$WW$ " <<std::setiosflags(ios::scientific) <<getParticleData(ParticleID::Wplus)->hardProcessWidth()/GeV;
params<<"\n$alphas$ " <<std::setiosflags(ios::scientific) <<SM().alphaS();
params<<"\n$GF$ " <<std::setiosflags(ios::scientific) <<SM().fermiConstant()*GeV2 ;
params<<"\n$alphaMZ$ " <<std::setiosflags(ios::scientific) <<1/SM().alphaEMMZ();
params<<"\n$MZ$ " <<std::setiosflags(ios::scientific) <<getParticleData(ParticleID::Z0)->hardProcessMass() /GeV<<flush;
params<<"\n$MW$ " <<std::setiosflags(ios::scientific) <<getParticleData(ParticleID::Wplus)->hardProcessMass() /GeV<<flush;
params<<"\n$sw2$ " <<std::setiosflags(ios::scientific) << SM().sin2ThetaW() <<flush;
if(theMGmodel=="heft"&&!keepinputtopmass){
if ( factory()->initVerbose() ) {
generator()->log()<<"\n---------------------------------------------------------------";
generator()->log()<<"\n---------------------------------------------------------------";
generator()->log()<<"\nNote: You are using the Higgs Effective model (heft) in ";
generator()->log()<<"\n Madgraph. We assume you try to calculate NLO with ";
generator()->log()<<"\n the GoSam virtual amplitudes. To match the models we ";
generator()->log()<<"\n therefore set the topmass to 10000000 GeV.";
generator()->log()<<"\n\n For more information see the \\tau parameter in:";
generator()->log()<<"\n https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Models/HiggsEffective";
generator()->log()<<"\n\n The Effective Higgs model in Gosam is using mT=infinity";
generator()->log()<<"\n\n\n If you want to use the LO matrixelements of MadGraph with finite' topmass you need to add: ";
generator()->log()<<"\n\n set Madgraph:KeepInputTopMass True";
generator()->log()<<"\n\n to your input file.";
generator()->log()<<"\n---------------------------------------------------------------";
generator()->log()<<"\n---------------------------------------------------------------\n";
}
params<<"\n$MT$ 10000000." <<flush;
}else{
params<<"\n$MT$ " <<std::setiosflags(ios::scientific) << getParticleData(ParticleID::t)->hardProcessMass() /GeV <<flush;
}
params<<"\n$WT$ " <<std::setiosflags(ios::scientific) << getParticleData(ParticleID::t)->hardProcessWidth() /GeV <<flush;
params<<"\n$MB$ " <<std::setiosflags(ios::scientific) << getParticleData(ParticleID::b)->hardProcessMass() /GeV <<flush;
params<<"\n$MH$ " <<std::setiosflags(ios::scientific) << getParticleData(ParticleID::h0)->hardProcessMass() /GeV <<flush;
params<<"\n$WH$ " <<std::setiosflags(ios::scientific) << getParticleData(ParticleID::h0)->hardProcessWidth() /GeV <<flush;
params<<"\n$MTA$ " <<std::setiosflags(ios::scientific) << getParticleData(ParticleID::tauplus)->hardProcessMass() /GeV <<flush;
string cmd = "python " + bindir_ + "/mg2Matchbox.py ";
cmd +=" --buildpath "+mgProcLibPath();
cmd +=" --model "+theMGmodel;
cmd +=" --runpath "+factory()->runStorage()+"/MadGraphAmplitudes ";
cmd +=" --datadir "+pkgdatadir_;
std::stringstream as,aem;
as << factory()->orderInAlphaS();
cmd +=" --orderas "+as.str() ;
aem <<factory()->orderInAlphaEW();
cmd +=" --orderew "+aem.str();
// TODO move to boost::system
writeAmplitudesDat();
if (boost::filesystem::exists(mgProcLibPath()+"InterfaceMadGraph.so") ){
//set the parameters
checkAmplitudes();
std::system(cmd.c_str());
ranMadGraphInitializeExternal = true;
return true;
}
char cwd[1024];
if ( !getcwd(cwd,sizeof(cwd)) )
- throw Exception() << "failed to determine current working directory\n"
+ throw Exception() << "MadGraphAmplitude: failed to determine current working directory\n"
<< Exception::abortnow;
cmd +=" --madgraph " + madgraphPrefix_ + "/bin " ;
cmd +="--build > ";
cmd += mgProcLibPath()+"MG.log 2>&1";
generator()->log() << "\n>>> Compiling MadGraph amplitudes. This may take some time -- please be patient.\n"
<< ">>> In case of problems see " << mgProcLibPath() << "MG.log for details.\n\n"
<< flush;
std::system(cmd.c_str());
cmd = "python " + bindir_ + "/mg2Matchbox.py ";
cmd +=" --buildpath "+mgProcLibPath();
cmd +=" --model "+theMGmodel;
cmd +=" --runpath "+factory()->runStorage()+"/MadGraphAmplitudes ";
cmd +=" --datadir "+pkgdatadir_;
as.clear();
aem.clear();
as << factory()->orderInAlphaS();
cmd +=" --orderas "+as.str() ;
aem <<factory()->orderInAlphaEW();
cmd +=" --orderew "+aem.str();
std::system(cmd.c_str());
ranMadGraphInitializeExternal = true;
return boost::filesystem::exists(mgProcLibPath()+"InterfaceMadGraph.so");
}
int MadGraphAmplitude::externalId(const cPDVector& proc) {
for (int i=0;i<100;i++){
colourindex.push_back(-2);
}
assert(!BornAmplitudes.empty()||!VirtAmplitudes.empty());
writeAmplitudesDat();
int res=0;
string amp="";
int k=0;
for (cPDVector::const_iterator it=proc.begin();it!=proc.end();it++,k++){
amp+=boost::lexical_cast<string>( (*it)->id())+" ";if (k==1)amp+=" > ";
}
string born= mgProcLibPath()+"BornAmplitudes.dat";
string virt= mgProcLibPath()+"VirtAmplitudes.dat";
assert ( boost::filesystem::exists(born)|| boost::filesystem::exists(virt));
ifstream borns(born.c_str());
string line;
while (std::getline(borns, line)) {
res+=1;
if(line==amp)return res;
}
ifstream virts(virt.c_str());
while (std::getline(virts, line)) {
res+=1;
if(line==amp)return res;
}
- throw Exception() << "One amplitude has no externalId. Please remove the MadGraphAmplitude-folder and rebuild.\n" << Exception::abortnow;
+ throw Exception() << "MadGraphAmplitude: One amplitude has no externalId. Please remove the MadGraphAmplitude-folder and rebuild.\n" << Exception::abortnow;
return res;
}
bool MadGraphAmplitude::ranMadGraphInitializeExternal = false;
void MadGraphAmplitude::doinit() {
if ( !ranMadGraphInitializeExternal ) {
initializeExternal();
}
MatchboxAmplitude::doinit();
}
void MadGraphAmplitude::doinitrun() {
if ( !ranMadGraphInitializeExternal ) {
initializeExternal();
}
MatchboxAmplitude::doinitrun();
}
bool MadGraphAmplitude::canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr factory,
bool virt) const {
if ( factory->processData()->diagramMap().find(p) !=
factory->processData()->diagramMap().end() )
return true;
vector<Ptr<Tree2toNDiagram>::ptr> diags =
factory->diagramGenerator()->generate(p,orderInGs(),orderInGem());
if ( diags.empty() )
return false;
factory->processData()->diagramMap()[p] = diags;
string amp="";
int k=0;
for (PDVector::const_iterator it=p.begin();it!=p.end();it++,k++){
amp+=boost::lexical_cast<string>( (*it)->id())+" ";if (k==1)amp+=" > ";
}
if (virt && factory->highestVirt()>=p.size()){
VirtAmplitudes.push_back(amp);
}else{
BornAmplitudes.push_back(amp);
}
return true;
}
void MadGraphAmplitude::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
useMe();
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
if (colourindex.empty()) {
for (int i=0;i<100;i++){
colourindex.push_back(-2);
}
}
lastMatchboxXComb()->clearheljamp();
lastMatchboxXComb()->clearhelLNjamp();
initProcess(mePartonData());
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MadGraphAmplitude::evaluate(size_t i, const vector<int>& hel, Complex& largeN) {
//find the colourline:
int ii = -1;
int xx=lastMatchboxXComb()->externalId();
if(colourindex[i]!=-2){
ii = colourindex[i];
if (ii==-1) {
largeN = Complex(0.0);
return Complex(0.0);
}
} else {
set<vector<size_t> > a = colourOrdering(i);
int ncol=-1;
MG_NCol(&xx,&ncol);
assert(ncol!=-1);
for( int it = 0; it < ncol; it++ ){
int n = 0;
for ( cPDVector::const_iterator nx = mePartonData().begin();
nx != mePartonData().end(); nx++ )
if ( (*nx)->coloured() ) n++;
set<vector<size_t> > tmpset;
vector<size_t> tmpvek;
for ( int it2 = 0; it2 < n; it2++ ) {
int ret=-2;
MG_Colour(&xx,&it,&it2,&ret);
assert(ret !=-2);
if (ret== -1)
break;
if ( ret == 0 ) {
n++;
tmpset.insert(tmpvek);
tmpvek.clear();
} else {
tmpvek.push_back(ret-1);
}
if( it2 == n-1 ) tmpset.insert(tmpvek);
}
bool found_all = true;
for ( set<vector<size_t> >::iterator it3 = a.begin(); it3 != a.end(); it3++ ) {
bool found_it3=false;
for ( set<vector<size_t> >::iterator it4 = tmpset.begin(); it4 != tmpset.end(); it4++ ) {
vector<size_t> it3tmp = gluonsFirst(*it3);
vector<size_t> it4tmp = (*it4);
if ( it3tmp.size() != it4tmp.size() ) continue;
if ( it3tmp == it4tmp ) found_it3 = true;
}
found_all = found_all && found_it3;
}
if ( found_all ) {
colourindex[i]=it;
ii=it;
}
}
}
if ( ii == -1 ){
colourindex[i]=ii;
largeN = Complex(0.0);
return Complex(0.0);
}
const map<vector<int>,vector < complex<double> > >& tmp = lastMatchboxXComb()->heljamp();
const map<vector<int>,vector < complex<double> > >& tmpLN = lastMatchboxXComb()->helLNjamp();
if( tmp.find(hel) != tmp.end()) {
largeN = tmpLN.find(hel)->second[ii];
return tmp.find(hel)->second[ii];;
}
double units = pow(sqrt(lastSHat())/GeV,int(hel.size())-4);
int heltmp[10];
for(size_t j=0;j<hel.size();j++){
int cross=crossingMap()[j];
if( (cross>1&&j<=1)||(cross<=1&&j>1)){
heltmp[cross]=-1*hel[j];}
else{heltmp[cross]=hel[j];}
}
vector<Lorentz5Momentum> reshuffled = meMomenta();
if ( !reshuffleMasses().empty() && reshuffled.size() > 3 ) {
const cPDVector& pdata = mePartonData();
const map<long,Energy>& masses = reshuffleMasses();
lastMatchboxXComb()->reshuffle(reshuffled,pdata,masses);
}
double momenta[50];
size_t j=0;
for (size_t i=0;i<mePartonData().size();i++){
momenta[j]=abs(reshuffled[i].e()/GeV)<1.e-13?0.:double(reshuffled[i].e()/GeV);
momenta[j+1]=abs(reshuffled[i].x()/GeV)<1.e-13?0.:double(reshuffled[i].x()/GeV);
momenta[j+2]=abs(reshuffled[i].y()/GeV)<1.e-13?0.:double(reshuffled[i].y()/GeV);
momenta[j+3]=abs(reshuffled[i].z()/GeV)<1.e-13?0.:double(reshuffled[i].z()/GeV);
j+=4;
}
MG_Calculate_wavefunctions_born(&xx, &momenta[0], &heltmp[0]);
int ncol=-1;
MG_NCol(&xx,&ncol);
Complex res;
Complex resLN;
for( int it = 0; it < ncol; it++ ){
double dd[2];
MG_Jamp(&xx,&it,&dd[0]);
Complex d(dd[0],dd[1]);
if(it==ii)res=d*units;
lastMatchboxXComb()->pushheljamp(hel,d*units);
double ddLN[2];
MG_LNJamp(&xx,&it,&ddLN[0]);
Complex dLN(ddLN[0],ddLN[1]);
if(it==ii)resLN=dLN*units;
lastMatchboxXComb()->pushhelLNjamp(hel,dLN*units);
}
largeN = resLN;
return res;
}
vector<unsigned int> MadGraphAmplitude::physicalHelicities(const vector<int>& hel) const {
vector<unsigned int> res(hel.size(),0);
for ( size_t j = 0; j < hel.size(); ++j ) {
int cross = crossingMap()[j];
int xhel = 0;
if ( (cross > 1 && j <= 1) || (cross <= 1 && j > 1) )
xhel = -1*hel[j];
else
xhel = hel[j];
if ( mePartonData()[cross]->iSpin() == PDT::Spin1Half )
res[cross] = (xhel == -1 ? 0 : 1);
else if ( mePartonData()[cross]->iSpin() == PDT::Spin1 )
res[cross] = (unsigned int)(xhel + 1);
else assert(false);
}
return res;
}
LorentzVector<Complex> MadGraphAmplitude::plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int i) const {
int tmp=i;
double pg[4],ng[4],poltmp[8];
pg[0]=p.e()/GeV;pg[1]=p.x()/GeV;pg[2]=p.y()/GeV;pg[3]=p.z()/GeV;
ng[0]=n.e()/GeV;ng[1]=n.x()/GeV;ng[2]=n.y()/GeV;ng[3]=n.z()/GeV;
MG_vxxxxx(&pg[0],&ng[0],&tmp,&poltmp[0]);
complex<double> pol[6];
pol[0]=Complex(poltmp[0],poltmp[1]);
pol[1]=Complex(poltmp[2],poltmp[3]);
pol[2]=Complex(poltmp[4],poltmp[5]);
pol[3]=Complex(poltmp[6],poltmp[7]);
LorentzVector<Complex> polarization(pol[1],pol[2],pol[3],pol[0]);
return polarization.conjugate();
}
bool equalsModulo(unsigned int i, const vector<int>& a, const vector<int>& b) {
assert(a.size()==b.size());
if ( a[i] == b[i] )
return false;
for ( unsigned int k = 0; k < a.size(); ++k ) {
if ( k == i )
continue;
if ( a[k] != b[k] )
return false;
}
return true;
}
vector<size_t> MadGraphAmplitude::gluonsFirst(vector<size_t> vec) {
vector<size_t> vecout;
for(vector<size_t>::iterator it= vec.begin();it!= vec.end();++it)
if ( mePartonData()[crossingMap()[*it]]->id()==21)
vecout.push_back(crossingMap()[*it]);
for(vector<size_t>::iterator it= vec.begin();it!= vec.end();++it)
if ( mePartonData()[crossingMap()[*it]]->id()!=21)
vecout.push_back(crossingMap()[*it]);
return vecout;
}
double MadGraphAmplitude::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
vector<Lorentz5Momentum> reshuffled = meMomenta();
if ( !reshuffleMasses().empty() && reshuffled.size() > 3 ) {
const cPDVector& pdata = mePartonData();
const map<long,Energy>& masses = reshuffleMasses();
lastMatchboxXComb()->reshuffle(reshuffled,pdata,masses);
}
Lorentz5Momentum p = reshuffled[ij.first];
Lorentz5Momentum n = reshuffled[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
colourCorrelatedME2(ij)*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
int iCrossed = crossingMap()[ij.first];
iCrossed = ij.first;
for ( unsigned int k = 0; k < crossingMap().size(); ++k )
if ( crossingMap()[k] == ij.first ) {
iCrossed = k;
break;
}
Complex csCorr = 0.0;
if ( calculateColourSpinCorrelator(ij) ) {
set<const CVector*> done;
for ( AmplitudeConstIterator a = lastAmplitudes().begin();
a != lastAmplitudes().end(); ++a ) {
if ( done.find(&(a->second)) != done.end() )
continue;
AmplitudeConstIterator b = lastAmplitudes().begin();
while ( !equalsModulo(iCrossed,a->first,b->first) )
if ( ++b == lastAmplitudes().end() )
break;
if ( b == lastAmplitudes().end() || done.find(&(b->second)) != done.end() )
continue;
done.insert(&(a->second)); done.insert(&(b->second));
if ( a->first[iCrossed] == 1 )
swap(a,b);
csCorr -= colourBasis()->colourCorrelatedInterference(ij,mePartonData(),a->second,b->second);
}
lastColourSpinCorrelator(ij,csCorr);
} else {
csCorr = lastColourSpinCorrelator(ij);
}
double corr =
2.*real(csCorr*sqr(pFactor));
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
( avg +(c.scale() > ZERO ? 1. : -1.)*corr/cfac);
}
void MadGraphAmplitude::prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr ){
assert(false);
}
double MadGraphAmplitude::oneLoopInterference() const {
if ( !calculateOneLoopInterference() )
return lastOneLoopInterference();
evaloneLoopInterference();
return lastOneLoopInterference();
}
void MadGraphAmplitude::evaloneLoopInterference() const {
double units = pow(lastSHat()/GeV2,int(mePartonData().size())-4);
vector<Lorentz5Momentum> reshuffled = meMomenta();
if ( !reshuffleMasses().empty() && reshuffled.size() > 3 ) {
const cPDVector& pdata = mePartonData();
const map<long,Energy>& masses = reshuffleMasses();
lastMatchboxXComb()->reshuffle(reshuffled,pdata,masses);
}
double virt[20];
double momenta[50];
size_t j=0;
for (size_t i=0;i<mePartonData().size();i++){
momenta[j]=abs(reshuffled[i].e()/GeV)<1.e-13?0.:double(reshuffled[i].e()/GeV);
momenta[j+1]=abs(reshuffled[i].x()/GeV)<1.e-13?0.:double(reshuffled[i].x()/GeV);
momenta[j+2]=abs(reshuffled[i].y()/GeV)<1.e-13?0.:double(reshuffled[i].y()/GeV);
momenta[j+3]=abs(reshuffled[i].z()/GeV)<1.e-13?0.:double(reshuffled[i].z()/GeV);
j+=4;
}
int xx=lastMatchboxXComb()->externalId();
MG_Calculate_wavefunctions_virt(&xx,&momenta[0],&virt[0]);
double ifact = 1.;
ifact = 1./4.;
if (lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3bar )
ifact /= SM().Nc();
else if ( lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour8 )
ifact /= (SM().Nc()*SM().Nc()-1.);
if ( lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3bar )
ifact /= SM().Nc();
else if ( mePartonData()[1]->iColour() == PDT::Colour8 )
ifact /= (SM().Nc()*SM().Nc()-1.);
ifact *= lastMatchboxXComb()->matchboxME()->finalStateSymmetry();
lastOneLoopInterference(virt[1]/ifact*units);
lastOneLoopPoles(pair<double, double>(virt[2]/ifact*units,virt[3]/ifact*units));
}
void MadGraphAmplitude::persistentOutput(PersistentOStream & os) const {
os << theOrderInGs << theOrderInGem << BornAmplitudes << VirtAmplitudes
<< colourindex<<crossing << theProcessPath << theMGmodel << bindir_
<< pkgdatadir_ << madgraphPrefix_;
}
void MadGraphAmplitude::persistentInput(PersistentIStream & is, int) {
is >> theOrderInGs >> theOrderInGem >> BornAmplitudes >> VirtAmplitudes
>> colourindex>>crossing >> theProcessPath >> theMGmodel >> bindir_
>> pkgdatadir_ >> madgraphPrefix_;
}
// *** 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<MadGraphAmplitude,MatchboxAmplitude>
describeHerwigMadGraphAmplitude("Herwig::MadGraphAmplitude", "HwMatchboxMadGraph.so");
void MadGraphAmplitude::Init() {
static ClassDocumentation<MadGraphAmplitude> documentation ("MadGraphAmplitude","Matrix elements have been calculated using MadGraph5");
static Parameter<MadGraphAmplitude,string> interfaceProcessPath
("ProcessPath",
"The Process Path.",
&MadGraphAmplitude::theProcessPath, "",false, false);
static Parameter<MadGraphAmplitude,string> interfaceModel
("Model",
"The MadGraph-Model.",
&MadGraphAmplitude::theMGmodel, "loop_sm",false, false);
static Switch<MadGraphAmplitude,bool> interfacekeepinputtopmass
("KeepInputTopMass",
"Switch On/Off formopt",
&MadGraphAmplitude::keepinputtopmass, false, false, false);
static SwitchOption interfacekeepinputtopmassTrue
(interfacekeepinputtopmass,
"On",
"On",
true);
static SwitchOption interfacekeepinputtopmassFalse
(interfacekeepinputtopmass,
"Off",
"Off",
false);
static Parameter<MadGraphAmplitude,string> interfaceBinDir
("BinDir",
"The location for the installed executable",
&MadGraphAmplitude::bindir_, string(HERWIG_BINDIR),
false, false);
static Parameter<MadGraphAmplitude,string> interfacePKGDATADIR
("DataDir",
"The location for the installed Herwig++ data files",
&MadGraphAmplitude::pkgdatadir_, string(HERWIG_PKGDATADIR),
false, false);
static Parameter<MadGraphAmplitude,string> interfaceMadgraphPrefix
("MadgraphPrefix",
"The prefix for the location of MadGraph",
&MadGraphAmplitude::madgraphPrefix_, string(MADGRAPH_PREFIX),
false, false);
}
diff --git a/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc b/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc
--- a/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc
+++ b/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc
@@ -1,299 +1,299 @@
// -*- C++ -*-
//
// NJetsAmplitude.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 NJetsAmplitude class.
//
#include "NJetsAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.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/Utilities/DynamicLoader.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include "njet.h"
#include <cstdlib>
#ifndef NJET_PREFIX
#error Makefile.am needs to define NJET_PREFIX
#endif
#ifndef NJET_LIBS
#error Makefile.am needs to define NJET_LIBS
#endif
using namespace Herwig;
NJetsAmplitude::NJetsAmplitude() : NJetsPrefix_(NJET_PREFIX),
NJetsLibs_(NJET_LIBS) {}
NJetsAmplitude::~NJetsAmplitude() {}
IBPtr NJetsAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr NJetsAmplitude::fullclone() const {
return new_ptr(*this);
}
void NJetsAmplitude::signOLP(const string& order, const string& contract) {
string cmd = NJetsPrefix_+"/bin/njet.py -o " + contract + " " + order;
std::system(cmd.c_str());
}
void NJetsAmplitude::startOLP(const string& contract, int& status) {
NJet::LH_OLP::OLP_Start(contract.c_str(), &status);
if ( status != 1 )
return;
status = 0;
static double zero = 0.0;
double param = 0.0;
param = SM().alphaEMMZ();
NJet::LH_OLP::OLP_SetParameter("alpha",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
NJet::LH_OLP::OLP_SetParameter("mass(23)",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV;
NJet::LH_OLP::OLP_SetParameter("mass(24)",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Z0)->hardProcessWidth()/GeV;
NJet::LH_OLP::OLP_SetParameter("width(23)",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Wplus)->hardProcessWidth()/GeV;
NJet::LH_OLP::OLP_SetParameter("width(24)",&param,&zero,&status);
if ( status != 1 )
return;
param = SM().sin2ThetaW();
NJet::LH_OLP::OLP_SetParameter("sw2",&param,&zero,&status);
didStartOLP() = true;
}
void NJetsAmplitude::loadNJET() {
if ( ! (DynamicLoader::load(NJetsLibs_+"/libnjet2.so") ||
DynamicLoader::load("libnjet2.so") ) )
- throw Exception() << "failed to load libnjet2.so\n"
+ throw Exception() << "NJetsAmplitude: Failed to load libnjet2.so\n"
<< DynamicLoader::lastErrorMessage
<< Exception::abortnow;
}
bool NJetsAmplitude::startOLP(const map<pair<Process,int>,int>& procs) {
loadNJET();
// TODO throw exception on massive leptons in procs
string orderFileName = factory()->buildStorage() + name() + ".OLPOrder.lh";
ofstream orderFile(orderFileName.c_str());
olpOrderFileHeader(orderFile);
orderFile << "NJetReturnAccuracy yes\n"
<< "NJetRenormalize yes\n"
<< "NJetNf " << factory()->nLight() << "\n";
olpOrderFileProcesses(orderFile,procs);
orderFile << flush;
orderFile.close();
string contractFileName = factory()->buildStorage() + name() + ".OLPContract.lh";
signOLP(orderFileName, contractFileName);
int status = -1;
startOLP(contractFileName,status);
if ( status != 1 )
return false;
return true;
}
LorentzVector<Complex> NJetsAmplitude::plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int inc) const {
double pvec[4] = {p.t()/GeV,p.x()/GeV,p.y()/GeV,p.z()/GeV};
double nvec[4] = {n.t()/GeV,n.x()/GeV,n.y()/GeV,n.z()/GeV};
double out[8] ={ };
NJet::LH_OLP::OLP_Polvec(pvec,nvec,out);
LorentzVector<Complex> res;
Complex a(out[0],out[1]);
res.setT(a);
Complex b(out[2],out[3]);
res.setX(b);
Complex c(out[4],out[5]);
res.setY(c);
Complex d(out[6],out[7]);
res.setZ(d);
if (inc<2)
return res.conjugate();
else
return res;
}
void NJetsAmplitude::evalSubProcess() const {
useMe();
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double as;
if (!hasRunningAlphaS()) as = SM().alphaS();
else if (hasRunningAlphaS()) as = lastAlphaS();
double scale = sqrt(mu2()/GeV2);
double out[7]={};
int id =
olpId()[ProcessType::oneLoopInterference] ?
olpId()[ProcessType::oneLoopInterference] :
olpId()[ProcessType::treeME2];
NJet::LH_OLP::OLP_EvalSubProcess(id, olpMomenta(), scale, &as, out);
if ( olpId()[ProcessType::oneLoopInterference] ) {
if(calculateTreeME2())lastTreeME2(out[3]*units);
lastOneLoopInterference(out[2]*units);
lastOneLoopPoles(pair<double,double>(out[0]*units,out[1]*units));
} else if ( olpId()[ProcessType::treeME2] ) {
lastTreeME2(out[0]*units);
} else assert(false);
}
void NJetsAmplitude::evalColourCorrelator(pair<int,int>) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double as;
if (!hasRunningAlphaS()) as = SM().alphaS();
else if (hasRunningAlphaS()) as = lastAlphaS();
double scale = sqrt(mu2()/GeV2);
int n = lastXComb().meMomenta().size();
colourCorrelatorResults.resize(n*(n-1)/2);
NJet::LH_OLP::OLP_EvalSubProcess(olpId()[ProcessType::colourCorrelatedME2],
olpMomenta(), scale, &as, &colourCorrelatorResults[0]);
for ( int i = 0; i < n; ++i )
for ( int j = i+1; j < n; ++j ) {
lastColourCorrelator(make_pair(i,j),colourCorrelatorResults[i+j*(j-1)/2]*units);
}
}
void NJetsAmplitude::evalSpinColourCorrelator(pair<int,int>) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double as;
if (!hasRunningAlphaS()) as = SM().alphaS();
else if (hasRunningAlphaS()) as = lastAlphaS();
double scale = sqrt(mu2()/GeV2);
int n = lastXComb().meMomenta().size();
spinColourCorrelatorResults.resize(2*n*n);
NJet::LH_OLP::OLP_EvalSubProcess(olpId()[ProcessType::spinColourCorrelatedME2],
olpMomenta(), scale, &as, &spinColourCorrelatorResults[0]);
for ( int i = 0; i < n; ++i )
for ( int j = 0; j < n; ++j ) {
if ( i == j || mePartonData()[i]->id() != 21 )
continue;
Complex scc(spinColourCorrelatorResults[2*i+2*n*j]*units,
spinColourCorrelatorResults[2*i+2*n*j+1]*units);
lastColourSpinCorrelator(make_pair(i,j),scc);
}
}
void NJetsAmplitude::doinit() {
loadNJET();
MatchboxOLPME::doinit();
}
void NJetsAmplitude::doinitrun() {
loadNJET();
MatchboxOLPME::doinitrun();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void NJetsAmplitude::persistentOutput(PersistentOStream & os) const {
os << colourCorrelatorResults << spinColourCorrelatorResults
<< NJetsPrefix_ << NJetsLibs_;
}
void NJetsAmplitude::persistentInput(PersistentIStream & is, int) {
is >> colourCorrelatorResults >> spinColourCorrelatorResults
>> NJetsPrefix_ >> NJetsLibs_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<NJetsAmplitude,MatchboxOLPME>
describeHerwigNJetsAmplitude("Herwig::NJetsAmplitude", "HwMatchboxNJet.so");
void NJetsAmplitude::Init() {
static ClassDocumentation<NJetsAmplitude> documentation
("NJetsAmplitude implements an interface to NJets.",
"Matrix elements have been calculated using NJet.");
static Parameter<NJetsAmplitude,string> interfaceNJetsPrefix
("NJetsPrefix",
"The prefix for the location of NJets",
&NJetsAmplitude::NJetsPrefix_, string(NJET_PREFIX),
false, false);
static Parameter<NJetsAmplitude,string> interfaceNJetsLibs
("NJetsLibs",
"The location of the NJets library",
&NJetsAmplitude::NJetsLibs_, string(NJET_LIBS),
false, false);
}
diff --git a/MatrixElement/Matchbox/External/OpenLoops/OpenLoopsAmplitude.cc b/MatrixElement/Matchbox/External/OpenLoops/OpenLoopsAmplitude.cc
--- a/MatrixElement/Matchbox/External/OpenLoops/OpenLoopsAmplitude.cc
+++ b/MatrixElement/Matchbox/External/OpenLoops/OpenLoopsAmplitude.cc
@@ -1,453 +1,453 @@
// -*- C++ -*-
//
// OpenLoopsAmplitude.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 OpenLoopsAmplitude class.
//
#include "OpenLoopsAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Utilities/DynamicLoader.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib>
using namespace Herwig;
#ifndef OPENLOOPSLIBS
#error Makefile.am needs to define OPENLOOPSLIBS
#endif
#ifndef OPENLOOPSPREFIX
#error Makefile.am needs to define OPENLOOPSPREFIX
#endif
OpenLoopsAmplitude::OpenLoopsAmplitude() :
use_cms(true),psp_tolerance(12),
OpenLoopsLibs_(OPENLOOPSLIBS), OpenLoopsPrefix_(OPENLOOPSPREFIX) {
}
OpenLoopsAmplitude::~OpenLoopsAmplitude() {
}
IBPtr OpenLoopsAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr OpenLoopsAmplitude::fullclone() const {
return new_ptr(*this);
}
extern "C" void OLP_Start(const char*, int* i);
extern "C" void OLP_SetParameter(const char* ,double* ,double*,int*);
extern "C" void ol_setparameter_string(const char*, const char*);
extern "C" void OLP_PrintParameter(const char*);
extern "C" void OLP_EvalSubProcess(int*, double*, double*, double*, double*);
extern "C" void OLP_EvalSubProcess2(int*, double*, double*, double*, double*);
// id ps-point emitter polvec res
extern "C" void ol_evaluate_sc(int, double*, int, double*, double*);
extern "C" void OLP_Polvec(double*,double*,double*);
void OpenLoopsAmplitude::doinitrun() {
MatchboxOLPME::doinitrun();
}
void OpenLoopsAmplitude::startOLP(const string& contract, int& status) {
string tempcontract=contract;
if ( ! (DynamicLoader::load(OpenLoopsLibs_+"/libopenloops.so") ||
DynamicLoader::load(OpenLoopsPrefix_+"/lib/libopenloops.so") ||
DynamicLoader::load("libopenloops.so") ) ) {
- throw Exception() << "Failed to load libopenloops.so/dylib\n"
+ throw Exception() << "OpenLoopsAmplitude::startOLP(): Failed to load libopenloops.so/dylib\n"
<< DynamicLoader::lastErrorMessage
<< Exception::abortnow;
}
string stabilityPrefix = factory()->runStorage() + "OpenLoops.StabilityLog";
assert(stabilityPrefix.size() < 256);
ol_setparameter_string("stability_logdir",stabilityPrefix.c_str());
ol_setparameter_string("install_path",OpenLoopsPrefix_.c_str());
int a=0;double null=0.0;double one=1.0;
int part[10]={1,2,3,4,5,6,15,23,24,25};string stri;
for (int i=0;i<10;i++){
map<long,Energy>::const_iterator it=reshuffleMasses().find(part[i]);
double mass;
if(it==reshuffleMasses().end())
mass = getParticleData(part[i])->hardProcessMass()/GeV;
else
mass = it->second/GeV;
double width=getParticleData(part[i])->hardProcessWidth()/GeV;
std::stringstream ss;
ss << part[i];
string str = ss.str();
stri="mass("+str+")";
OLP_SetParameter(stri.c_str(),&mass,&null,&a);
stri="width("+str+")";
OLP_SetParameter(stri.c_str(),&width,&null,&a);
}
stri="alphas";
one=SM().alphaS();
OLP_SetParameter( stri.c_str(),&one ,&null,&a);
stri="alpha";
one=SM().alphaEMMZ();
OLP_SetParameter(stri.c_str(),&one ,&null,&a);
OLP_Start(tempcontract.c_str(), &status);
didStartOLP() = true;
}
void OpenLoopsAmplitude::fillOrderFile(const map<pair<Process, int>, int>& procs) {
string orderFileName = factory()->buildStorage() + name() + ".OLPContract.lh";
ofstream orderFile(orderFileName.c_str());
size_t asPower = 100;
size_t minlegs = 100;
size_t maxlegs = 0;
for ( map<pair<Process, int>, int>::const_iterator t = procs.begin() ; t != procs.end() ; ++t ) {
asPower = min(asPower, static_cast<size_t>(t->first.first.orderInAlphaS));
minlegs = min(minlegs, static_cast<size_t>(t->first.first.legs.size()));
maxlegs = max(maxlegs, static_cast<size_t>(t->first.first.legs.size()));
}
orderFile << "# OLP order file created by Herwig++/Matchbox for OpenLoops\n\n";
orderFile << "CorrectionType QCD\n";
orderFile << "IRregularization " << (isDR() ? "DRED" : "CDR") << "\n";
orderFile << "extra answerfile " << (factory()->buildStorage() + name() + ".OLPAnswer.lh") << "\n";
orderFile << "extra psp_tolerance "<<psp_tolerance<<"\n";
orderFile << "extra use_cms "<<(use_cms?"1":"0")<< "\n";
orderFile << "\n";
if (extraOpenLoopsPath!="")
orderFile << "Extra OpenLoopsPath " << extraOpenLoopsPath << "\n";
for ( map<pair<Process, int>, int>::const_iterator p = procs.begin() ; p != procs.end() ; ++p ) {
std::stringstream Processstr;
std::stringstream Typestr;
Processstr << (*p).first.first.legs[0]->id() << " " << (*p).first.first.legs[1]->id() << " -> ";
for ( PDVector::const_iterator o = (*p).first.first.legs.begin() + 2 ; o != (*p).first.first.legs.end() ; ++o )
Processstr << (**o).id() << " ";
if ( (*p).first.second == ProcessType::treeME2 ) {
Typestr << "Tree";
} else if ( (*p).first.second == ProcessType::colourCorrelatedME2 ) {
Typestr << "ccTree";
} else if ( (*p).first.second == ProcessType::spinColourCorrelatedME2 ) {
Typestr << "sctree_polvect";
} else if ( (*p).first.second == ProcessType::oneLoopInterference ) {
Typestr << "Loop";
}
OpenLoopsProcInfo pro = OpenLoopsProcInfo((*p).second, -1, Processstr.str(), Typestr.str());
pro.setOAs(p->first.first.orderInAlphaS);
processmap[(*p).second] = pro;
}
vector < string > types;
types.push_back("Tree");
types.push_back("ccTree");
types.push_back("sctree_polvect");
types.push_back("Loop");
for ( size_t i = asPower ; i != asPower + maxlegs - minlegs + 1 ; i++ ) {
orderFile << "\n\nCouplingPower QCD " << i;
orderFile << "\n\n#AlphasPower " << i;
for ( vector<string>::iterator it = types.begin() ; it != types.end() ; it++ ) {
for ( map<int, OpenLoopsProcInfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p )
if ( (*p).second.Tstr() == *it && i == (unsigned int) (*p).second.orderAs() ) {
orderFile << "\nAmplitudeType " << *it << "\n";
break;
}
for ( map<int, OpenLoopsProcInfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p )
if ( (*p).second.Tstr() == *it && i == (unsigned int) (*p).second.orderAs() ) {
orderFile << (*p).second.Pstr() << "\n";
}
}
}
orderFile << flush;
}
bool OpenLoopsAmplitude::checkOLPContract() {
string contractFileName = factory()->buildStorage() + name() + ".OLPAnswer.lh";
ifstream infile(contractFileName.c_str());
string line;
vector < string > contractfile;
while (std::getline(infile, line)) {
contractfile.push_back(line);
}
for ( map<int, OpenLoopsProcInfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ ) {
bool righttype = false;
for ( vector<string>::iterator linex = contractfile.begin() ; linex != contractfile.end() ; ++linex ) {
if ( (*linex).find("AmplitudeType ")!= std::string::npos ) {
if ( (*linex).find(" " + (*p).second.Tstr() + " ")!= std::string::npos ) {
righttype = true;
} else {
righttype = false;
}
}
if ( righttype ) {
if ( (*linex).find((*p).second.Pstr()) != std::string::npos ){
if( (*p).second.Pstr().length() == (*linex).find("|") ) {
string sub = (*linex).substr((*linex).find("|") + 1, (*linex).find("#") - (*linex).find("|") - 1); // | 1 23 # buggy??
int subint;
int subint2;
istringstream(sub) >> subint >> subint2;
assert(subint==1);
(*p).second.setGID(subint2);
}
}
}
}
}
string ids = factory()->buildStorage() + "OpenLoops.ids.dat";
ofstream IDS(ids.c_str());
for ( map<int, OpenLoopsProcInfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ ) {
idpair.insert ( std::pair<int,int>((*p).second.HID(),(*p).second.GID()) );
IDS << (*p).second.HID() << " " << (*p).second.GID() << "\n";
if ( (*p).second.GID() == -1 ) return 0;
}
IDS << flush;
return 1;
}
void OpenLoopsAmplitude::getids() const{
string line = factory()->buildStorage() + "OpenLoops.ids.dat";
ifstream infile(line.c_str());
int hid;
int gid;
while (std::getline(infile, line)) {
istringstream(line) >> hid>>gid;
idpair.insert ( std::pair<int,int>(hid,gid) );
}
}
bool OpenLoopsAmplitude::startOLP(const map<pair<Process, int>, int>& procs) {
string contractFileName = factory()->buildStorage() + name() + ".OLPAnswer.lh";
string orderFileName = factory()->buildStorage() + name() + ".OLPContract.lh";
fillOrderFile(procs);
int status = -1;
startOLP(orderFileName, status);
if ( !checkOLPContract() ) {
return false;
}
if ( status != 1 ) return false;
return true;
}
void OpenLoopsAmplitude::evalSubProcess() const {
useMe();
double units = pow(lastSHat() / GeV2, mePartonData().size() - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double acc ;
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int a=0;double null=0.0;double one=1.0;
string stri="alphas";
one=lastAlphaS();
OLP_SetParameter( stri.c_str(),&one ,&null,&a);
}
double out[7]={};
int id = olpId()[ProcessType::oneLoopInterference] ? olpId()[ProcessType::oneLoopInterference] : olpId()[ProcessType::treeME2];
if ( idpair.size() == 0 ) {
getids();
if ( Debug::level > 1 ) {
string parfile=factory()->runStorage() + name() + ".Parameters.dat";
OLP_PrintParameter(parfile.c_str());
}
}
OLP_EvalSubProcess2(&((*(idpair.find(id))).second), olpMomenta(), &scale, out,&acc );
if ( olpId()[ProcessType::oneLoopInterference] ) {
if(calculateTreeME2())lastTreeME2(out[3] * units);
lastOneLoopInterference((out[2])* units);
lastOneLoopPoles(pair<double, double>(out[0] * units, out[1] * units));
} else if ( olpId()[ProcessType::treeME2] ) {
lastTreeME2(out[0] * units);
}
}
void OpenLoopsAmplitude::evalColourCorrelator(pair<int, int> ) const {
double units = pow(lastSHat() / GeV2, mePartonData().size() - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double acc ;
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int a=0;double null=0.0;double one=1.0;
string stri="alphas";
one=lastAlphaS();
OLP_SetParameter( stri.c_str(),&one ,&null,&a);
}
int n = lastXComb().meMomenta().size();
colourCorrelatorResults.resize(n * (n - 1) / 2);
if ( idpair.size() == 0 ) {
getids();
if ( Debug::level > 1 ) {
string parfile=factory()->runStorage() + name() + ".Parameters.dat";
OLP_PrintParameter(parfile.c_str());
}
}
int id = olpId()[ProcessType::colourCorrelatedME2];
OLP_EvalSubProcess2(&((*(idpair.find(id))).second), olpMomenta(), &scale, &colourCorrelatorResults[0],&acc );
for ( int i = 0 ; i < n ; ++i ){
for ( int j = i + 1 ; j < n ; ++j ) {
lastColourCorrelator(make_pair(i, j), colourCorrelatorResults[i+j*(j-1)/2] * units);
}
}
}
void OpenLoopsAmplitude::evalSpinColourCorrelator(pair<int , int > ) const {
assert(false);
}
double OpenLoopsAmplitude::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const{
double units = pow(lastSHat() / GeV2, mePartonData().size() - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
if (hasRunningAlphaS()) {
int a=0;double null=0.0;double one=1.0;
string stri="alphas";
one=lastAlphaS();
OLP_SetParameter( stri.c_str(),&one ,&null,&a);
}
int emitter=ij.first+1;
int n = lastXComb().meMomenta().size();
if ( idpair.size() == 0 ) {
getids();
if ( Debug::level > 1 ) {
string parfile=factory()->runStorage() + name() + ".Parameters.dat";
OLP_PrintParameter(parfile.c_str());
}
}
int id = (*(idpair.find(olpId()[ProcessType::spinColourCorrelatedME2]))).second;
//double * outx =new double[n];
spinColourCorrelatorResults.resize(n);
double polvec[4];
polvec[0]=c.momentum().e()/GeV;
polvec[1]=c.momentum().x()/GeV;
polvec[2]=c.momentum().y()/GeV;
polvec[3]=c.momentum().z()/GeV;
double avg= colourCorrelatedME2(ij)*(-c.diagonal());
ol_evaluate_sc(id, olpMomenta(),emitter,polvec,&spinColourCorrelatorResults[0]);
double corr =-1.*units * spinColourCorrelatorResults[ij.second]/c.scale()*c.momentum().dot(c.momentum());
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
avg + corr/cfac;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void OpenLoopsAmplitude::persistentOutput(PersistentOStream & os) const {
os << idpair << OpenLoopsLibs_ << OpenLoopsPrefix_;
}
void OpenLoopsAmplitude::persistentInput(PersistentIStream & is, int) {
is >> idpair >> OpenLoopsLibs_ >> OpenLoopsPrefix_;
}
// *** 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<OpenLoopsAmplitude, MatchboxOLPME> describeHerwigOpenLoopsAmplitude("Herwig::OpenLoopsAmplitude", "HwMatchboxOpenLoops.so");
void OpenLoopsAmplitude::Init() {
static ClassDocumentation<OpenLoopsAmplitude> documentation("OpenLoopsAmplitude implements an interface to OpenLoops.","Matrix elements have been calculated using OpenLoops.");
static Switch<OpenLoopsAmplitude,bool> interfaceUseComplMass
("ComplexMassScheme",
"Switch on or off if Compex Masses.",
&OpenLoopsAmplitude::use_cms, true, false, false);
static SwitchOption interfaceUseComplMassOn
(interfaceUseComplMass,
"True",
"True for Complex Masses.",
true);
static SwitchOption interfaceUseComplMassOff
(interfaceUseComplMass,
"False",
"False for no Complex Masses.",
false);
static Parameter<OpenLoopsAmplitude,int> interfacepsp_tolerance
("PSP_tolerance",
"(Debug)Phase Space Tolerance. Better use e.g.: set OpenLoops:Massless 13",
&OpenLoopsAmplitude::psp_tolerance, 12, 0, 0,
false, false, Interface::lowerlim);
static Parameter<OpenLoopsAmplitude,string> interfaceOpenLoopsLibs
("OpenLoopsLibs",
"The location of OpenLoops libraries",
&OpenLoopsAmplitude::OpenLoopsLibs_, string(OPENLOOPSLIBS),
false, false);
static Parameter<OpenLoopsAmplitude,string> interfaceOpenLoopsPrefix
("OpenLoopsPrefix",
"The location of OpenLoops libraries",
&OpenLoopsAmplitude::OpenLoopsPrefix_, string(OPENLOOPSPREFIX),
false, false);
}
diff --git a/MatrixElement/Matchbox/External/VBFNLO/VBFNLOAmplitude.cc b/MatrixElement/Matchbox/External/VBFNLO/VBFNLOAmplitude.cc
--- a/MatrixElement/Matchbox/External/VBFNLO/VBFNLOAmplitude.cc
+++ b/MatrixElement/Matchbox/External/VBFNLO/VBFNLOAmplitude.cc
@@ -1,457 +1,457 @@
// -*- C++ -*-
//
// VBFNLOAmplitude.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 VBFNLOAmplitude class.
//
#include "VBFNLOAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Utilities/DynamicLoader.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include <cstdlib>
#include "VBFNLO/utilities/BLHAinterface.h"
#define DEFSTR(s) CPPSTR(s)
#define CPPSTR(s) #s
using namespace Herwig;
VBFNLOAmplitude::VBFNLOAmplitude()
: theRanHelSum(false), theAnomCoupl(false), VBFNLOlib_(DEFSTR(VBFNLOLIB))
{}
VBFNLOAmplitude::~VBFNLOAmplitude() {}
IBPtr VBFNLOAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr VBFNLOAmplitude::fullclone() const {
return new_ptr(*this);
}
void VBFNLOAmplitude::signOLP(const string& order, const string& contract) {
int status = 0;
OLP_Order(const_cast<char*>(order.c_str()),
const_cast<char*>(contract.c_str()),&status);
if ( status != 1 )
- throw Exception() << "Failed to sign contract with VBFNLO"
+ throw Exception() << "VBFNLOAmplitude: Failed to sign contract with VBFNLO"
<< Exception::abortnow;
}
void VBFNLOAmplitude::setOLPParameter(const string& name, double value) const {
int pStatus = 0;
double zero = 0.0;
OLP_SetParameter(const_cast<char*>(name.c_str()),&value,&zero,&pStatus);
if ( !pStatus )
- throw Exception() << "VBFNLO failed to set parameter '"
+ throw Exception() << "VBFNLOAmplitude: VBFNLO failed to set parameter '"
<< name << "' to " << value << "\n"
<< Exception::abortnow;
}
void VBFNLOAmplitude::startOLP(const string& contract, int& status) {
OLP_Start(const_cast<char*>(contract.c_str()), &status);
map<long,Energy>::const_iterator it=reshuffleMasses().find(ParticleID::b);
double bmass;
if(it==reshuffleMasses().end())
bmass = getParticleData(ParticleID::b)->hardProcessMass()/GeV;
else
bmass = it->second/GeV;
setOLPParameter("mass(5)",bmass);
setOLPParameter("mass(6)",getParticleData(ParticleID::t)->hardProcessMass()/GeV);
setOLPParameter("mass(23)",getParticleData(ParticleID::Z0)->hardProcessMass()/GeV);
setOLPParameter("mass(24)",getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV);
setOLPParameter("mass(25)",getParticleData(ParticleID::h0)->hardProcessMass()/GeV);
setOLPParameter("width(23)",getParticleData(ParticleID::Z0)->hardProcessWidth()/GeV);
setOLPParameter("width(24)",getParticleData(ParticleID::Wplus)->hardProcessWidth()/GeV);
setOLPParameter("width(25)",getParticleData(ParticleID::h0)->hardProcessWidth()/GeV);
setOLPParameter("alpha",SM().alphaEMMZ());
setOLPParameter("sw2",SM().sin2ThetaW());
setOLPParameter("Gf",SM().fermiConstant()*GeV2);
setOLPParameter("Nf",factory()->nLight());
setOLPParameter("alphas",SM().alphaS());
setOLPParameter("ranhelsum",theRanHelSum);
setOLPParameter("anomcoupl",theAnomCoupl);
didStartOLP() = true;
}
void VBFNLOAmplitude::loadVBFNLO() {
if ( ! (DynamicLoader::load(VBFNLOlib_+"/libVBFNLO.so") ||
DynamicLoader::load("libVBFNLO.so") ) )
- throw Exception() << "failed to load libVBFNLO.so/dylib\n"
+ throw Exception() << "VBFNLOAmplitude: failed to load libVBFNLO.so/dylib\n"
<< DynamicLoader::lastErrorMessage
<< Exception::abortnow;
}
bool VBFNLOAmplitude::startOLP(const map<pair<Process,int>,int>& procs) {
loadVBFNLO();
string orderFileName = factory()->buildStorage() + name() + ".OLPOrder.lh";
ofstream orderFile(orderFileName.c_str());
olpOrderFileHeader(orderFile);
// add VBFNLO specifics here
olpOrderFileProcesses(orderFile,procs);
orderFile << flush;
orderFile.close();
string contractFileName = factory()->buildStorage() + name() + ".OLPContract.lh";
signOLP(orderFileName, contractFileName);
int status = -1;
startOLP(contractFileName,status);
if ( status != 1 )
return false;
return true;
}
LorentzVector<Complex> VBFNLOAmplitude::plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int inc) const {
// shamelessly stolen from the GoSam interface; mind that we can
// always cast eq (5.7) in the manual into a form that it only uses
// <M-||M_+> and then switch bvetween eps_+ for an outgoing and
// eps_- for an incoming gluon.
double pvec[4] = {p.t()/GeV,p.x()/GeV,p.y()/GeV,p.z()/GeV};
double nvec[4] = {n.t()/GeV,n.x()/GeV,n.y()/GeV,n.z()/GeV};
double out[8] ={ };
OLP_Polvec(pvec,nvec,out);
LorentzVector<Complex> res;
Complex a(out[0],out[1]);
res.setT(a);
Complex b(out[2],out[3]);
res.setX(b);
Complex c(out[4],out[5]);
res.setY(c);
Complex d(out[6],out[7]);
res.setZ(d);
if (inc<2)
return res.conjugate();
else
return res;
}
void VBFNLOAmplitude::evalSubProcess() const {
useMe();
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2()/GeV2);
if (hasRunningAlphaS()) setOLPParameter("alphas",lastAlphaS());
double acc = -1.0;
double out[4]={};
int id =
olpId()[ProcessType::oneLoopInterference] ?
olpId()[ProcessType::oneLoopInterference] :
olpId()[ProcessType::treeME2];
if (theRanHelSum) {
vector<double> helicityrn = amplitudeRandomNumbers();
if (helicityrn.size()>0) {
setOLPParameter("HelicityRN",helicityrn[0]);
}
}
OLP_EvalSubProcess2(&id, olpMomenta(), &scale, out, &acc);
if ( olpId()[ProcessType::oneLoopInterference] ) {
lastTreeME2(out[3]*units);
lastOneLoopInterference(out[2]*units);
lastOneLoopPoles(pair<double,double>(out[0]*units,out[1]*units));
} else if ( olpId()[ProcessType::treeME2] ) {
lastTreeME2(out[0]*units);
} else assert(false);
}
void VBFNLOAmplitude::evalColourCorrelator(pair<int,int>) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2()/GeV2);
if (hasRunningAlphaS()) setOLPParameter("alphas",lastAlphaS());
double acc = -1.0;
int n = lastXComb().meMomenta().size();
colourCorrelatorResults.resize(n*(n-1)/2);
int id = olpId()[ProcessType::colourCorrelatedME2];
if ( theRanHelSum ) {
if ( lastHeadMatchboxXComb() ) {
vector<double> helicityrn = lastHeadMatchboxXComb()->amplitudeRandomNumbers();
if (helicityrn.size()>0) {
setOLPParameter("HelicityRN",helicityrn[0]);
}
} else if ( amplitudeRandomNumbers().size() > 0 ) {
vector<double> helicityrn = amplitudeRandomNumbers();
if (helicityrn.size()>0) {
setOLPParameter("HelicityRN",helicityrn[0]);
}
}
}
OLP_EvalSubProcess2(&id, olpMomenta(), &scale, &colourCorrelatorResults[0], &acc);
for ( int i = 0; i < n; ++i )
for ( int j = i+1; j < n; ++j ) {
lastColourCorrelator(make_pair(i,j),colourCorrelatorResults[i+j*(j-1)/2]*units);
}
}
void VBFNLOAmplitude::evalSpinColourCorrelator(pair<int,int>) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2()/GeV2);
if (hasRunningAlphaS()) setOLPParameter("alphas",lastAlphaS());
double acc = -1.0;
int n = lastXComb().meMomenta().size();
spinColourCorrelatorResults.resize(2*n*n);
int id = olpId()[ProcessType::spinColourCorrelatedME2];
if (theRanHelSum && lastHeadMatchboxXComb()) {
vector<double> helicityrn = lastHeadMatchboxXComb()->amplitudeRandomNumbers();
if (helicityrn.size()>0) {
setOLPParameter("HelicityRN",helicityrn[0]);
}
}
OLP_EvalSubProcess2(&id, olpMomenta(), &scale, &spinColourCorrelatorResults[0], &acc);
for ( int i = 0; i < n; ++i )
for ( int j = 0; j < n; ++j ) {
if ( i == j || mePartonData()[i]->id() != 21 )
continue;
Complex scc(spinColourCorrelatorResults[2*i+2*n*j]*units,
spinColourCorrelatorResults[2*i+2*n*j+1]*units);
lastColourSpinCorrelator(make_pair(i,j),scc);
}
}
double VBFNLOAmplitude::largeNME2(Ptr<ColourBasis>::tptr cptr) const {
if ( calculateLargeNME2() )
evalLargeNSubProcess(cptr);
return lastLargeNME2();
}
void VBFNLOAmplitude::evalLargeNSubProcess(Ptr<ColourBasis>::tptr) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2()/GeV2);
if (hasRunningAlphaS()) setOLPParameter("alphas",lastAlphaS());
double acc = -1.0;
double out[4]={};
int id =
olpId()[ProcessType::oneLoopInterference] ?
olpId()[ProcessType::oneLoopInterference] :
olpId()[ProcessType::treeME2];
if (theRanHelSum) {
vector<double> helicityrn = amplitudeRandomNumbers();
if (helicityrn.size()>0) {
setOLPParameter("HelicityRN",helicityrn[0]);
}
}
setOLPParameter("Nc",-1); // large-N limit
OLP_EvalSubProcess2(&id, olpMomenta(), &scale, out, &acc);
setOLPParameter("Nc",generator()->standardModel()->Nc());
if ( olpId()[ProcessType::oneLoopInterference] ) {
lastLargeNME2(out[3]*units);
lastOneLoopInterference(out[2]*units);
lastOneLoopPoles(pair<double,double>(out[0]*units,out[1]*units));
} else if ( olpId()[ProcessType::treeME2] ) {
lastLargeNME2(out[0]*units);
} else assert(false);
}
double VBFNLOAmplitude::largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr cptr) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = Nc/2.;
} else assert(false);
if ( calculateLargeNColourCorrelator(ij) )
evalLargeNColourCorrelator(ij,cptr);
return lastLargeNColourCorrelator(ij)/cfac;
}
void VBFNLOAmplitude::evalLargeNColourCorrelator(pair<int,int>,
Ptr<ColourBasis>::tptr) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2()/GeV2);
if (hasRunningAlphaS()) setOLPParameter("alphas",lastAlphaS());
double acc = -1.0;
int n = lastXComb().meMomenta().size();
colourCorrelatorResults.resize(n*(n-1)/2);
int id = olpId()[ProcessType::colourCorrelatedME2];
if (theRanHelSum && lastHeadMatchboxXComb()) {
vector<double> helicityrn = lastHeadMatchboxXComb()->amplitudeRandomNumbers();
if (helicityrn.size()>0) {
setOLPParameter("HelicityRN",helicityrn[0]);
}
}
setOLPParameter("Nc",-1); // large-N limit
OLP_EvalSubProcess2(&id, olpMomenta(), &scale, &colourCorrelatorResults[0], &acc);
setOLPParameter("Nc",generator()->standardModel()->Nc());
for ( int i = 0; i < n; ++i )
for ( int j = i+1; j < n; ++j ) {
lastLargeNColourCorrelator(make_pair(i,j),colourCorrelatorResults[i+j*(j-1)/2]*units);
}
}
void VBFNLOAmplitude::doinit() {
loadVBFNLO();
MatchboxOLPME::doinit();
}
void VBFNLOAmplitude::doinitrun() {
loadVBFNLO();
MatchboxOLPME::doinitrun();
}
void VBFNLOAmplitude::persistentOutput(PersistentOStream & os) const {
os << colourCorrelatorResults << spinColourCorrelatorResults << theRanHelSum << theAnomCoupl << VBFNLOlib_;
}
void VBFNLOAmplitude::persistentInput(PersistentIStream & is, int) {
is >> colourCorrelatorResults >> spinColourCorrelatorResults >> theRanHelSum >> theAnomCoupl >> VBFNLOlib_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<VBFNLOAmplitude,MatchboxOLPME>
describeHerwigVBFNLOAmplitude("Herwig::VBFNLOAmplitude", "HwMatchboxVBFNLO.so");
void VBFNLOAmplitude::Init() {
static ClassDocumentation<VBFNLOAmplitude> documentation
("VBFNLOAmplitude implements an interface to VBFNLO.",
"Matrix elements have been calculated using VBFNLO "
"(Ref.~\\cite{VBFNLO} and process-specific references)\n",
"%\\cite{VBFNLO}\n"
"\\bibitem{Arnold:2008rz}\n"
"K.~Arnold, M.~Bahr, G.~Bozzi, F.~Campanario, C.~Englert, T.~Figy, "
"N.~Greiner and C.~Hackstein {\\it et al.},\n"
"``VBFNLO: A Parton level Monte Carlo for processes with electroweak bosons,''\n"
"Comput.\\ Phys.\\ Commun.\\ {\\bf 180} (2009) 1661\n"
"[arXiv:0811.4559 [hep-ph]];\n"
"%%CITATION = ARXIV:0811.4559;%%\n"
"J.~Baglio, J.~Bellm, F.~Campanario, B.~Feigl, J.~Frank, T.~Figy, "
"M.~Kerner and L.~D.~Ninh {\\it et al.},\n"
"``Release Note - VBFNLO 2.7.0,''\n"
"arXiv:1404.3940 [hep-ph].\n"
"%%CITATION = ARXIV:1404.3940;%%\n");
static Switch<VBFNLOAmplitude,bool> interfaceRandomHelicitySummation
("RandomHelicitySummation", "Switch for random helicity summation of leptons and photons",
&VBFNLOAmplitude::theRanHelSum, false, false, false);
static SwitchOption interfaceRandomHelicitySummationTrue
(interfaceRandomHelicitySummation,
"True",
"Perform random helicity summation",
true);
static SwitchOption interfaceRandomHelicitySummationFalse
(interfaceRandomHelicitySummation,
"False",
"Sum over all helicity combinations",
false);
static Switch<VBFNLOAmplitude,bool> interfaceAnomalousCouplings
("AnomalousCouplings", "Switch for anomalous couplings",
&VBFNLOAmplitude::theAnomCoupl, false, false, false);
static SwitchOption interfaceAnomalousCouplingsTrue
(interfaceAnomalousCouplings,
"On",
"Switch anomalous couplings on",
true);
static SwitchOption interfaceAnomalousCouplingsFalse
(interfaceAnomalousCouplings,
"Off",
"Switch anomalous couplings off",
false);
}
diff --git a/MatrixElement/Matchbox/External/VBFNLO/VBFNLOPhasespace.cc b/MatrixElement/Matchbox/External/VBFNLO/VBFNLOPhasespace.cc
--- a/MatrixElement/Matchbox/External/VBFNLO/VBFNLOPhasespace.cc
+++ b/MatrixElement/Matchbox/External/VBFNLO/VBFNLOPhasespace.cc
@@ -1,257 +1,257 @@
// -*- C++ -*-
//
// VBFNLOPhasespace.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 VBFNLOPhasespace class.
//
#include "VBFNLOPhasespace.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.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 "Herwig++/Utilities/GSLBisection.h"
#include "ThePEG/Utilities/DynamicLoader.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "VBFNLO/utilities/BLHAinterface.h"
#define DEFSTR(s) CPPSTR(s)
#define CPPSTR(s) #s
using namespace Herwig;
VBFNLOPhasespace::VBFNLOPhasespace() :
lastSqrtS(0*GeV), needToReshuffle(false), VBFNLOlib_(DEFSTR(VBFNLOLIB))
{}
void VBFNLOPhasespace::loadVBFNLO() {
if ( ! (DynamicLoader::load(VBFNLOlib_+"/libVBFNLO.so") ||
DynamicLoader::load("libVBFNLO.so") ) )
- throw Exception() << "failed to load libVBFNLO.so/dylib\n"
+ throw Exception() << "VBFNLOPhasespace::loadVBFNLO(): Failed to load libVBFNLO.so/dylib\n"
<< DynamicLoader::lastErrorMessage
<< Exception::abortnow;
}
VBFNLOPhasespace::~VBFNLOPhasespace() {}
IBPtr VBFNLOPhasespace::clone() const {
return new_ptr(*this);
}
IBPtr VBFNLOPhasespace::fullclone() const {
return new_ptr(*this);
}
void VBFNLOPhasespace::setXComb(tStdXCombPtr xco) {
MatchboxPhasespace::setXComb(xco);
// test for resuffling
needToReshuffle = false;
if ( xco ) {
for ( cPDVector::const_iterator d = mePartonData().begin();
d != mePartonData().end(); ++d ) {
// Higgs is massive -> does not need reshuffling
if ( ( (**d).id() != ParticleID::h0 ) && ( (**d).hardProcessMass() != ZERO ) ) {
needToReshuffle = true;
break;
}
}
}
// set CMS energy
int pStatus = 0;
double zero = 0.0;
double value = sqrt(lastXCombPtr()->lastS())/GeV;
if (value && (value != lastSqrtS/GeV)) {
lastSqrtS = value*GeV;
string name = "sqrtS";
OLP_SetParameter(const_cast<char*>(name.c_str()),&value,&zero,&pStatus);
if ( !pStatus )
- throw Exception() << "VBFNLO failed to set parameter '"
+ throw Exception() << "VBFNLOPhasespace::setXComb(): VBFNLO failed to set parameter '"
<< name << "' to " << value << "\n"
<< Exception::abortnow;
}
}
double VBFNLOPhasespace::generateTwoToNKinematics(const double* random,
vector<Lorentz5Momentum>& momenta) {
double weight;
int id =
olpId()[ProcessType::oneLoopInterference] ?
olpId()[ProcessType::oneLoopInterference] :
olpId()[ProcessType::treeME2];
double* p = new double[4*momenta.size()];
OLP_PhaseSpacePoint(&id, const_cast<double*>(random), const_cast<double*>(random+1), p, &weight);
if (weight < 0) {
- throw Exception() << "negative weight in VBFNLOPhaseSpace\n"
+ throw Exception() << "VBFNLOPhasespace::generateTwoToNKinematics(): Negative weight in VBFNLOPhaseSpace\n"
<< Exception::abortnow;
}
if (weight == 0) {
delete p;
return 0;
}
for ( size_t i = 0; i < momenta.size(); ++i ) {
momenta[i].setT(p[4*i] *GeV);
momenta[i].setX(p[4*i+1]*GeV);
momenta[i].setY(p[4*i+2]*GeV);
momenta[i].setZ(p[4*i+3]*GeV);
}
delete p;
Energy beamenergy = sqrt(lastXCombPtr()->lastS())/2.;
double x1 = momenta[0].e()/beamenergy;
double x2 = momenta[1].e()/beamenergy;
Energy2 thisSHat = (momenta[0] + momenta[1]).m2();
// reshuffle so that particles have correct mass
// boost final-state into partonic CMS
Boost toCMS = (momenta[0]+momenta[1]).findBoostToCM();
for ( size_t i = 2; i < momenta.size(); ++i ) {
momenta[i].boost(toCMS);
}
// copied from MatchboxRambo phasespace
if ( needToReshuffle ) {
double xi;
ReshuffleEquation solve(sqrt(thisSHat),mePartonData().begin()+2,mePartonData().end(),
momenta.begin()+2,momenta.end());
GSLBisection solver(1e-10,1e-8,10000);
try {
xi = solver.value(solve,0.0,1.1);
} catch (GSLBisection::GSLerror) {
return 0.;
} catch (GSLBisection::IntervalError) {
return 0.;
}
weight *= pow(xi,3.*(momenta.size()-3.));
Energy num = ZERO;
Energy den = ZERO;
cPDVector::const_iterator d = mePartonData().begin()+2;
for ( vector<Lorentz5Momentum>::iterator k = momenta.begin()+2;
k != momenta.end(); ++k, ++d ) {
num += (*k).vect().mag2()/(*k).t();
Energy q = (*k).t();
(*k).setT(sqrt(sqr((**d).hardProcessMass())+xi*xi*sqr((*k).t())));
(*k).setVect(xi*(*k).vect());
weight *= q/(*k).t();
den += (*k).vect().mag2()/(*k).t();
(*k).setMass((**d).hardProcessMass());
}
}
// unboost
for ( size_t i = 2; i < momenta.size(); ++i ) {
momenta[i].boost(-toCMS);
}
if ( !matchConstraints(momenta) )
return 0.;
lastXCombPtr()->lastX1X2(make_pair(x1,x2));
lastXCombPtr()->lastSHat(thisSHat);
weight /= pow(thisSHat/GeV2,momenta.size()-4);
weight /= x1*x2;
fillDiagramWeights();
return weight;
}
int VBFNLOPhasespace::nDimPhasespace(int nFinal) const {
return 3*nFinal;
//get this from within VBFNLO
int pStatus = 0;
double value, zero;
string name = "PSdimension";
OLP_GetParameter(const_cast<char*>(name.c_str()),&value,&zero,&pStatus);
if ( pStatus != 1) {
- throw Exception() << "cannot get phasespace dimension in VBFNLOPhaseSpace\n"
+ throw Exception() << "VBFNLOPhasespace::nDimPhasespace(): Cannot get phasespace dimension in VBFNLOPhaseSpace\n"
<< "error code: " << pStatus << "\n"
<< Exception::abortnow;
}
// one additional number (first) needed for channel selection
// one additional number (last) needed for global phi integration
return value+2;
}
Energy VBFNLOPhasespace::ReshuffleEquation::operator() (double xi) const {
cPDVector::const_iterator d = dataBegin;
vector<Lorentz5Momentum>::const_iterator p = momentaBegin;
Energy res = -w;
for ( ; d != dataEnd; ++d, ++p ) {
res += sqrt(sqr((**d).hardProcessMass()) +
xi*xi*sqr(p->t()));
}
return res;
}
void VBFNLOPhasespace::doinit() {
loadVBFNLO();
MatchboxPhasespace::doinit();
}
void VBFNLOPhasespace::doinitrun() {
loadVBFNLO();
MatchboxPhasespace::doinitrun();
}
void VBFNLOPhasespace::persistentOutput(PersistentOStream & os) const {
os << needToReshuffle << theLastXComb;
}
void VBFNLOPhasespace::persistentInput(PersistentIStream & is, int) {
is >> needToReshuffle >> theLastXComb;
}
// *** 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<VBFNLOPhasespace,MatchboxPhasespace>
describeHerwigVBFNLOPhasespace("Herwig::VBFNLOPhasespace", "HwMatchboxVBFNLO.so");
void VBFNLOPhasespace::Init() {
static ClassDocumentation<VBFNLOPhasespace> documentation
("VBFNLOPhasespace is an interface to the internal phasespace generator "
"of VBFNLO. It uses the information passed via the BLHA interface to "
"obtain information on the required channels.");
}
diff --git a/MatrixElement/Matchbox/InsertionOperators/DipoleMIOperator.cc b/MatrixElement/Matchbox/InsertionOperators/DipoleMIOperator.cc
--- a/MatrixElement/Matchbox/InsertionOperators/DipoleMIOperator.cc
+++ b/MatrixElement/Matchbox/InsertionOperators/DipoleMIOperator.cc
@@ -1,771 +1,771 @@
// -*- C++ -*-
//
// DipoleMIOperator.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 DipoleMIOperator class.
//
#include "DipoleMIOperator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/Throw.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig++/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "ThePEG/PDT/DecayMode.h"
#include "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include <gsl/gsl_sf_dilog.h>
using namespace Herwig;
using Constants::pi;
DipoleMIOperator::DipoleMIOperator()
: MatchboxInsertionOperator(),
CA(-1.0), CF(-1.0),
gammaQuark(-1.0), gammaGluon(-1.0),
betaZero(-1.),
KQuark(-1.0), KGluon(-1.0) {}
DipoleMIOperator::~DipoleMIOperator() {}
IBPtr DipoleMIOperator::clone() const {
return new_ptr(*this);
}
IBPtr DipoleMIOperator::fullclone() const {
return new_ptr(*this);
}
//////////////////////////////////////////////////////////////////////
bool DipoleMIOperator::apply(const cPDVector& pd) const {
// DipoleMIOperator should apply as soon as massive
// partons can occur in the overall process.
// DipoleIOperator should not apply then.
// A gluon in the Born final state can give rise to
// a splitting g->Q\bar{Q} in the real radiation.
// This can happen if massive partons are specified
// inside the jet (aka if the Born process does not
// exclude accompanying subprocesses with light par
// tons).
bool mFSet = false;
if ( NHeavyJetVec().size() != 0 ) {
mFSet = true;
}
// Partons in the initial state are massless in the CS
// approach:
// The following loop checks for at least one existing
// combination (note that the single apply function is
// not checking for massless condition) 'n in addition
// for at least one massive parton in the final state,
// 'n for only massless partons in the initial state.
bool first = false;
bool second = false;
bool finalmass = false;
bool initialmass = false;
int idp = 0;
for ( cPDVector::const_iterator p = pd.begin();
p != pd.end(); ++p, ++idp ) {
if ( (*p)->coloured() && (*p)->hardProcessMass()!=ZERO && idp > 1 ) {
finalmass = true;
}
if ( (*p)->coloured() && (*p)->hardProcessMass()!=ZERO && idp < 2 ) {
initialmass = true;
}
if ( !first ) {
if ( apply(*p) ) {
first = true;
}
} else {
if ( apply(*p) ) {
second = true;
}
}
}
if ( first && second && (finalmass || mFSet) && !initialmass &&
(factory()->alphaParameter() < 1.) ) {
Repository::clog() << "DipoleMIOperator: Warning: The alpha parameter will be set to 1.";
Repository::clog() << " The massive I Operator does not support alpha.";
factory()->setAlphaParameter(1.);
}
return first && second && (finalmass || mFSet) && !initialmass;
}
bool DipoleMIOperator::apply(tcPDPtr pd) const {
return
(abs(pd->id()) < 7 || pd->id() == ParticleID::g);
}
void DipoleMIOperator::setXComb(tStdXCombPtr xc) {
MatchboxInsertionOperator::setXComb(xc);
if ( CA < 0. ) {
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.0)/(2.*SM().Nc());
gammaQuark = (3./2.)*CF;
// gammaGluon = (11./6.)*CA - (1./3.)*NLightJetVec().size();
// betaZero = (11./6.)*CA - (1./3.)*(NLightJetVec().size()+NHeavyJetVec().size());
gammaGluon = (11./6.)*CA - (1./3.)*lastBorn()->nLightJetVec().size();
betaZero = (11./6.)*CA - (1./3.)*(lastBorn()->nLightJetVec().size()+lastBorn()->nHeavyJetVec().size());
KQuark = (7./2.-sqr(pi)/6.)*CF;
// KGluon = (67./18.-sqr(pi)/6.)*CA-(5./9.)*NLightJetVec().size();
KGluon = (67./18.-sqr(pi)/6.)*CA-(5./9.)*lastBorn()->nLightJetVec().size();
}
}
//////////////////////////////////////////////////////////////////////
vector<int> DipoleMIOperator::NLightJetVec() const {
// const map<string,PDVector>& theParticleGroups = MatchboxFactory::currentFactory()->particleGroups();
const map<string,PDVector>& theParticleGroups = factory()->particleGroups();
map<string,PDVector>::const_iterator theIt = theParticleGroups.find("j");
if ( theIt == theParticleGroups.end() )
throw Exception() << "DipoleMIOperator::NLightJetVec(): Could not find a jet particle group named 'j'" << Exception::abortnow;
const PDVector& theJetConstitutents = theIt->second;
vector<int> theNLightJetVec;
for ( PDVector::const_iterator theP = theJetConstitutents.begin();
theP != theJetConstitutents.end(); ++theP ) {
if ( (**theP).id() > 0 && (**theP).id() < 7 && (**theP).hardProcessMass() == ZERO )
theNLightJetVec.push_back( (**theP).id() );
}
return theNLightJetVec;
}
vector<int> DipoleMIOperator::NHeavyJetVec() const {
// const map<string,PDVector>& theParticleGroups = MatchboxFactory::currentFactory()->particleGroups();
const map<string,PDVector>& theParticleGroups = factory()->particleGroups();
map<string,PDVector>::const_iterator theIt = theParticleGroups.find("j");
if ( theIt == theParticleGroups.end() )
throw Exception() << "DipoleMIOperator::NHeavyJetVec(): Could not find a jet particle group named 'j'" << Exception::abortnow;
const PDVector& theJetConstitutents = theIt->second;
vector<int> theNHeavyJetVec;
for ( PDVector::const_iterator theP = theJetConstitutents.begin();
theP != theJetConstitutents.end(); ++theP ) {
if ( (**theP).id() > 0 && (**theP).id() < 7 && (**theP).hardProcessMass() != ZERO )
theNHeavyJetVec.push_back( (**theP).id() );
}
return theNHeavyJetVec;
}
vector<int> DipoleMIOperator::NLightBornVec() const {
// For the moment just count all quark and antiquark
// constituents in the Born process.
vector<int> theNLightBornVec;
for ( cPDVector::const_iterator j = mePartonData().begin();
j != mePartonData().end(); ++j ) {
if ( abs((**j).id()) < 7 && (**j).hardProcessMass() == ZERO )
theNLightBornVec.push_back( (**j).id() );
}
return theNLightBornVec;
}
vector<int> DipoleMIOperator::NHeavyBornVec() const {
// For the moment just count all quark and antiquark
// constituents in the Born process.
vector<int> theNHeavyBornVec;
for ( cPDVector::const_iterator j = mePartonData().begin();
j != mePartonData().end(); ++j ) {
if ( abs((**j).id()) < 7 && (**j).hardProcessMass() != ZERO )
theNHeavyBornVec.push_back( (**j).id() );
}
return theNHeavyBornVec;
}
vector<int> DipoleMIOperator::NLightProtonVec() const {
// const map<string,PDVector>& theParticleGroups = MatchboxFactory::currentFactory()->particleGroups();
const map<string,PDVector>& theParticleGroups = factory()->particleGroups();
map<string,PDVector>::const_iterator theIt = theParticleGroups.find("p");
if ( theIt == theParticleGroups.end() )
throw Exception() << "DipoleMIOperator::NLightProtonVec(): Could not find a proton particle group named 'p'" << Exception::abortnow;
const PDVector& theProtonConstitutents = theIt->second;
vector<int> theNLightProtonVec;
for ( PDVector::const_iterator theP = theProtonConstitutents.begin();
theP != theProtonConstitutents.end(); ++theP ) {
if ( (**theP).id() > 0 && (**theP).id() < 7 && (**theP).hardProcessMass() == ZERO )
theNLightProtonVec.push_back( (**theP).id() );
}
return theNLightProtonVec;
}
//////////////////////////////////////////////////////////////////////
double DipoleMIOperator::me2() const {
if ( !isExpanded() )
- throw InitException() << "DipoleMIOperator only implemented in the expanded convention.";
+ throw InitException() << "DipoleMIOperator: Only implemented in the expanded convention.";
if ( isDR() )
- throw InitException() << "DipoleMIOperator not implemented for dimensional reduction.";
+ throw InitException() << "DipoleMIOperator: Not implemented for dimensional reduction.";
Energy2 mu2 = lastBorn()->mu2();
double kappa=0.;
bool appendixB = true;
// Note: We are using a parametrization where we keep s_{ja'}=2p_jp_a' fixed,
// rather than s_{ja}=2p_jp_a, due to the substitution \eta->x/z and the sub-
// sequent shift of the z-dependence from the hard Born ME into the PDF.
// Thus we need to make sure to keep the right kinematic variable fixed while
// performig the z-integration, i.e. s_{ja'} in our case. This is partly des-
// cribed in appendix B of the massive CS paper, but also in the last term of
// eq. (6.55) in the massive CS paper we need to consider that s_{ja'} is our
// fixed variable and not s_{ja}.
// This also means that in the sum over heavy quark flavours, in the g->QQbar
// contributions, we need to sum over N_F and not just N_F^{ja} (see appendix
// B in the massive CS paper, last sentence on p. 51 in arXiv:hep-ph/0201036)
// which is important for the massive I operator here but especially for the
// massive PK operator.
double res = 0.;
int idj = 0; int idk = 0;
// j is emitter, k is spectator
for ( cPDVector::const_iterator j = mePartonData().begin();
j != mePartonData().end(); ++j, ++idj ) {
if ( !apply(*j) ) {
continue;
}
if ( apply(*j) && idj < 2 && (**j).hardProcessMass() != ZERO )
throw InitException() << "DipoleMIOperator: Initial state partons must not be massive!";
idk = 0;
for ( cPDVector::const_iterator k = mePartonData().begin();
k != mePartonData().end(); ++k, ++idk ) {
if ( !apply(*k) ) {
continue;
}
if ( j == k || lastBorn()->noDipole(idj,idk) ) {
continue;
}
if ( apply(*k) && idk < 2 && (**k).hardProcessMass() != ZERO )
throw InitException() << "DipoleMIOperator: Initial state partons must not be massive!";
double delta = 0.0;
Energy2 sjk = 2.*meMomenta()[idj]*meMomenta()[idk];
if ( idj > 1 ) { // Involves idk > 1 as well as idk < 2
delta +=
( ((**j).id() == ParticleID::g ? CA : CF) *
( Vj(**j,**k,sjk,kappa,appendixB) - sqr(pi)/3. ) +
((**j).id() == ParticleID::g ? GammaGluon() : GammaQuark(**j)) +
((**j).id() == ParticleID::g ? gammaGluon : gammaQuark) * (1 + log(mu2/sjk)) +
((**j).id() == ParticleID::g ? KGluon : KQuark) );
}
if ( idj < 2 && idk > 1 ) {
delta +=
( ((**j).id() == ParticleID::g ? CA : CF) *
( Vj(**j,**k,sjk,2./3.,appendixB,true) - sqr(pi)/3. ) +
((**j).id() == ParticleID::g ? gammaGluon : gammaQuark) * (1 + log(mu2/sjk)) +
((**j).id() == ParticleID::g ? KGluon : KQuark) );
}
// If j and k are incoming, same contribution as in DipoleIOperator.
// Master apply prevents the DipoleIOperator though from applying in
// case of at least one massive parton in the overall process.
// So, need to add the expanded finite term for initial-initial cor-
// relations here (DipoleMIOperator) as well.
if ( idj < 2 && idk < 2 ) {
delta += ( ((**j).id() == ParticleID::g ? CA : CF) * ( -1.*sqr(pi)/3. + 1./2.*log(mu2/sjk)*log(mu2/sjk) ) +
((**j).id() == ParticleID::g ? gammaGluon : gammaQuark) * ( 1. + log(mu2/sjk) ) +
((**j).id() == ParticleID::g ? KGluon : KQuark) );
}
delta *= lastBorn()->colourCorrelatedME2(make_pair(idj,idk));
res += delta;
}
}
// NOTE: In the following we account for the full scale restoration
// if \mu of the OLP differs from \mu_R - same as in massless case.
// Note: In the GoSam OLP interface, it is possible to directly set
// \mu = \mu_R, via the switch SetMuToMuR (for debugging purposes).
if ( !lastBorn()->hasRunningAlphaS() ) {
Energy2 muR2 =
lastBorn()->renormalizationScale()*
sqr(lastBorn()->renormalizationScaleFactor());
if ( muR2 != mu2 ) {
res -=
betaZero *
lastBorn()->orderInAlphaS() * log(muR2/mu2) *
lastBorn()->me2();
}
}
// // include the finite renormalization for DR here; ATTENTION this
// // has to be mentioned in the manual! see hep-ph/9305239 for
// // details; this guarantees an expansion in alpha_s^\bar{MS} when
// // using dimensional reduction
// if ( isDR() && isDRbar() )
// res -= (CA/6.)*lastBorn()->orderInAlphaS()*lastBorn()->me2();
res *= ( - lastBorn()->lastAlphaS() / (2.*pi) );
return res;
}
double DipoleMIOperator::oneLoopDoublePole() const {
if ( !isExpanded() )
- throw InitException() << "DipoleMIOperator only implemented in the expanded convention.";
+ throw InitException() << "DipoleMIOperator: Only implemented in the expanded convention.";
if ( isDR() )
- throw InitException() << "DipoleMIOperator not implemented for dimensional reduction.";
+ throw InitException() << "DipoleMIOperator: Not implemented for dimensional reduction.";
double res = 0.;
int idj = 0; int idk = 0;
// j is emitter, k is spectator
for ( cPDVector::const_iterator j = mePartonData().begin();
j != mePartonData().end(); ++j, ++idj ) {
if ( !apply(*j) ) {
continue;
}
if ( apply(*j) && idj < 2 && (**j).hardProcessMass() != ZERO )
throw InitException() << "DipoleMIOperator: Initial state partons must not be massive!";
idk = 0;
for ( cPDVector::const_iterator k = mePartonData().begin();
k != mePartonData().end(); ++k, ++idk ) {
if ( !apply(*k) ) {
continue;
}
if ( j == k || lastBorn()->noDipole(idj,idk) ) {
continue;
}
if ( apply(*k) && idk < 2 && (**k).hardProcessMass() != ZERO )
throw InitException() << "DipoleMIOperator: Initial state partons must not be massive!";
double delta = 0.0;
if (idj>1) { // Involves idk > 1 as well as idk < 2
delta += ( (**j).id() == ParticleID::g ? CA : CF ) * VsDoublePole(**j,**k);
}
else if (idj<2 && idk>1) {
delta += ( (**j).id() == ParticleID::g ? CA : CF ) * VsDoublePole(**j,**k);
}
else if (idj<2 && idk<2) {
delta += ( (**j).id() == ParticleID::g ? CA : CF );
}
delta *= lastBorn()->colourCorrelatedME2(make_pair(idj,idk));
res += delta;
}
}
res *= ( - lastBorn()->lastAlphaS() / (2.*pi) );
return res;
}
double DipoleMIOperator::oneLoopSinglePole() const {
if ( !isExpanded() )
- throw InitException() << "DipoleMIOperator only implemented in the expanded convention.";
+ throw InitException() << "DipoleMIOperator: Only implemented in the expanded convention.";
if ( isDR() )
- throw InitException() << "DipoleMIOperator not implemented for dimensional reduction.";
+ throw InitException() << "DipoleMIOperator: Not implemented for dimensional reduction.";
Energy2 mu2 = lastBorn()->mu2();
double res = 0.;
int idj = 0; int idk = 0;
// j is emitter, k is spectator
for ( cPDVector::const_iterator j = mePartonData().begin();
j != mePartonData().end(); ++j, ++idj ) {
if ( !apply(*j) ) {
continue;
}
if ( apply(*j) && idj < 2 && (**j).hardProcessMass() != ZERO )
throw InitException() << "DipoleMIOperator: Initial state partons must not be massive!";
idk = 0;
for ( cPDVector::const_iterator k = mePartonData().begin();
k != mePartonData().end(); ++k, ++idk ) {
if ( !apply(*k) ) {
continue;
}
if ( j == k || lastBorn()->noDipole(idj,idk) ) {
continue;
}
if ( apply(*k) && idk < 2 && (**k).hardProcessMass() != ZERO )
throw InitException() << "DipoleMIOperator: Initial state partons must not be massive!";
double delta = 0.0;
Energy2 sjk = 2.*meMomenta()[idj]*meMomenta()[idk];
if (idj>1) { // Involves idk > 1 as well as idk < 2
delta += ( (**j).id() == ParticleID::g ? CA : CF ) * VsSinglePole(**j,**k,sjk);
delta += ( (**j).id() == ParticleID::g ? GammaGluonSinglePole() : GammaQuarkSinglePole(**j) );
}
else if (idj<2 && idk>1) {
delta += ( (**j).id() == ParticleID::g ? CA : CF ) * VsSinglePole(**j,**k,sjk);
delta += ( (**j).id() == ParticleID::g ? gammaGluon : gammaQuark );
}
else if (idj<2 && idk<2) {
delta += ( (**j).id() == ParticleID::g ? CA : CF ) * log(mu2/sjk);
delta += ( (**j).id() == ParticleID::g ? gammaGluon : gammaQuark );
}
delta *= lastBorn()->colourCorrelatedME2(make_pair(idj,idk));
res += delta;
}
}
res *= ( - lastBorn()->lastAlphaS() / (2.*pi) );
return res;
}
//////////////////////////////////////////////////////////////////////
double DipoleMIOperator::Vj(const ParticleData& j, const ParticleData& k,
Energy2 sjk, double kappa, bool appendixB,
bool mFSetEmpty) const {
Energy2 mu2 = lastBorn()->mu2();
double res = 0.;
// sjk is being handed over as input parameter to DipoleMIOperator::Vj()
// kappa is being handed over as input parameter to DipoleMIOperator::Vj()
Energy2 mj2 = sqr(j.hardProcessMass()), mk2 = sqr(k.hardProcessMass());
Energy mj = j.hardProcessMass(), mk = k.hardProcessMass();
Energy2 Qjk2 = sjk + mj2 + mk2;
Energy Qjk = sqrt(Qjk2);
double vjk = rootOfKallen(Qjk2,mj2,mk2) / sjk;
double rho = sqrt( abs(1.-vjk)/(1.+vjk) ); // abs() because for small mass 1.-vjk can get O(-1.e-16)
double rhoj = sqrt( ( 1. - vjk + 2.*mj2/Qjk2 / (1.-mj2/Qjk2-mk2/Qjk2) ) /
( 1. + vjk + 2.*mj2/Qjk2 / (1.-mj2/Qjk2-mk2/Qjk2) ) );
double rhok = sqrt( ( 1. - vjk + 2.*mk2/Qjk2 / (1.-mj2/Qjk2-mk2/Qjk2) ) /
( 1. + vjk + 2.*mk2/Qjk2 / (1.-mj2/Qjk2-mk2/Qjk2) ) );
//////////////////////////////////////
// Finite terms of S part (6.20) //
// Expanded convention //
//////////////////////////////////////
ParticleData l = ( mj2 == ZERO ? k : j );
// both masses zero
if( mj2 == ZERO && mk2 == ZERO ) {
res += 0.0;
// Expanded
res += 1./2.*log(mu2/sjk)*log(mu2/sjk);
}
// one mass zero
else if( mj2 == ZERO || mk2 == ZERO ) {
Energy2 m2 = sqr(l.hardProcessMass());
res += -1./4.*sqr(log(m2/sjk)) - sqr(pi)/12. -
1./2.*log(m2/sjk)*log(sjk/Qjk2) - 1./2.*log(m2/Qjk2)*log(sjk/Qjk2);
// Expanded
res += 1./2.*log(mu2/sjk)*log(m2/sjk) +
1./4.*log(mu2/sjk)*log(mu2/sjk);
}
// no mass zero
else if( mj2 != ZERO && mk2 != ZERO ) {
res += 1./vjk * ( -1./4.*sqr(log(rhoj*rhoj)) - 1./4.*sqr(log(rhok*rhok)) -
sqr(pi)/6. + ( rho==0. ? 0. : log(rho)*log(Qjk2/sjk) ) );
// Expanded
res += 1./vjk * ( rho==0. ? 0. : log(rho)*log(mu2/sjk) );
}
//////////////////////////////////////
// NS part (6.21)-(6.26) //
//////////////////////////////////////
// V_q (j is quark)
// j is massive quark
if( mj2 != ZERO ) {
assert( abs(j.id()) < 7);
// common part iff j is massive quark and k either massive quark
// or massless parton (6.21),(6.22)
res += gammaQuark/CF * log(sjk/Qjk2);
// k is massive quark (6.21)
if( mk2 != ZERO ) {
assert( abs(k.id()) < 7);
res += 1./vjk * ( ( rho==0. ? 0. : log(rho*rho)*log(1.+rho*rho) ) + 2.*gsl_sf_dilog(rho*rho) -
gsl_sf_dilog(1.-rhoj*rhoj) - gsl_sf_dilog(1.-rhok*rhok) - sqr(pi)/6. ) +
log((Qjk-mk)/Qjk) - 2.*log((sqr(Qjk-mk)-mj2)/Qjk2) - 2.*mj2/sjk*log(mj/(Qjk-mk)) -
mk/(Qjk-mk) + 2.*mk*(2.*mk-Qjk)/sjk + sqr(pi)/2.;
}
// k is massless parton (6.22)
else {
res += sqr(pi)/6. - gsl_sf_dilog(sjk/Qjk2) -
2.*log(sjk/Qjk2) - mj2/sjk*log(mj2/Qjk2);
}
}
// V_j (j either massless quark (6.23) or gluon (6.24),(6.26))
else {
// k is massless parton
if( mk == ZERO ) {
// only contributes if j is gluon (6.26)
if( j.id() == ParticleID::g ) {
// sum over all quark flavours
if( !mFSetEmpty )
// for( size_t f=0; f<NHeavyJetVec().size(); ++f ) { // only heavy quarks in jet (aka g->QQbar at NLO)
// Energy2 mF2 = sqr( getParticleData(NHeavyJetVec()[f])->hardProcessMass() );
for( size_t f=0; f<lastBorn()->nHeavyJetVec().size(); ++f ) { // only heavy quarks in jet (aka g->QQbar at NLO)
Energy2 mF2 = sqr( getParticleData(lastBorn()->nHeavyJetVec()[f])->hardProcessMass() );
// sum only over quarks which meet special condition
// but not if method of appendix B is used (see note
// at the end of appendix B)
if( !appendixB && sjk <= 4.*sqrt(mF2)*(sqrt(mF2)+mk) )
continue;
double rho1 = sqrt( 1. - 4.*mF2 / sqr(Qjk-mk) );
res += 2./3./CA * ( log((1.+rho1)/2.) - rho1/3.*(3.+sqr(rho1)) - 0.5*log(mF2/sjk) );
}
// The last term with Q_{aux} in (6.26) cancels against a similar term in GammaGluon().
}
}
// k is massive quark
else {
assert( abs(k.id()) < 7);
// part common to j massless quark or gluon (6.23),(6.24)
res += sqr(pi)/6. - gsl_sf_dilog(sjk/Qjk2);
// j is massless quark (6.23)
if( abs(j.id()) < 7)
res += gammaQuark/CF * ( log(sjk/Qjk2) - 2.*log((Qjk-mk)/Qjk) - 2.*mk/(Qjk+mk) );
// j is gluon (6.24)
else if( j.id() == ParticleID::g ) {
// part independent of other heavy quark flavours
res += gammaGluon/CA * ( log(sjk/Qjk2) - 2.*log((Qjk-mk)/Qjk) - 2.*mk/(Qjk+mk) ) +
// (kappa-2./3.) * mk2/sjk * (1./CA*NLightJetVec().size()-1.) * log(2.*mk/(Qjk+mk));
(kappa-2./3.) * mk2/sjk * (1./CA*lastBorn()->nLightJetVec().size()-1.) * log(2.*mk/(Qjk+mk));
// part containing other heavy quark flavours
if( !mFSetEmpty )
// for( size_t f=0; f<NHeavyJetVec().size(); ++f ) { // only heavy quarks in jet (aka g->QQbar at NLO)
// Energy2 mF2 = sqr( getParticleData(NHeavyJetVec()[f])->hardProcessMass() );
for( size_t f=0; f<lastBorn()->nHeavyJetVec().size(); ++f ) { // only heavy quarks in jet (aka g->QQbar at NLO)
Energy2 mF2 = sqr( getParticleData(lastBorn()->nHeavyJetVec()[f])->hardProcessMass() );
// sum only over quarks which meet special condition
// but not if method of appendix B is used (see note
// at the end of appendix B)
if( !appendixB && sjk <= 4.*sqrt(mF2)*(sqrt(mF2)+mk) )
continue;
double rho1 = sqrt( 1. - 4.*mF2 / sqr(Qjk-mk) );
double rho2 = sqrt( 1. - 4.*mF2 / (Qjk2-mk2) );
res += 2./3./CA * ( log((Qjk-mk)/Qjk) + mk*rho1*rho1*rho1/(Qjk+mk) + log((1.+rho1)/2.) -
rho1/3.*(3.+sqr(rho1)) - 1./2.*log(mF2/Qjk2) ) +
1./CA * ( rho2*rho2*rho2*log((rho2-rho1)/(rho2+rho1)) - log((1.-rho1)/(1.+rho1)) -
8.*rho1*mF2/sjk ) * (kappa-2./3.) * mk2/sjk;
}
// The term with Q_{aux} in (6.24) cancels against a similar term in GammaGluon().
}
}
}
return res;
}
double DipoleMIOperator::VsDoublePole(const ParticleData& j, const ParticleData& k) const {
double res = 0.;
////////////////////////////////////////////////
// Double pole coefficient of S part (6.20) //
// Expanded convention //
////////////////////////////////////////////////
Energy2 mj2 = sqr(j.hardProcessMass()), mk2 = sqr(k.hardProcessMass());
// both masses zero
if( mj2 == ZERO && mk2 == ZERO ) {
res += 1.0;
}
// one mass zero
else if( mj2 == ZERO || mk2 == ZERO ) {
res += 1./2.;
}
// no mass zero
else if( mj2 != ZERO && mk2 != ZERO ) {
res += 0.0;
}
return res;
}
double DipoleMIOperator::VsSinglePole(const ParticleData& j, const ParticleData& k,
Energy2 sjk) const {
Energy2 mu2 = lastBorn()->mu2();
double res = 0.;
// sjk is being handed over as input parameter to DipoleMIOperator::VsDoublePole()
Energy2 mj2 = sqr(j.hardProcessMass()), mk2 = sqr(k.hardProcessMass());
Energy2 Qjk2 = sjk + mj2 + mk2;
double vjk = rootOfKallen(Qjk2,mj2,mk2) / sjk;
double rho = sqrt( abs(1.-vjk)/(1.+vjk) ); // abs() because for small mass 1.-vjk can get O(-1.e-16)
////////////////////////////////////////////////
// Single pole coefficient of S part (6.20) //
// Expanded convention //
////////////////////////////////////////////////
ParticleData l = ( mj2 == ZERO ? k : j );
// both masses zero
if( mj2 == ZERO && mk2 == ZERO ) {
res += log(mu2/sjk);
}
// one mass zero
else if( mj2 == ZERO || mk2 == ZERO ) {
Energy2 m2 = sqr(l.hardProcessMass());
res += 1./2.*(log(mu2/sjk) + log(m2/sjk));
}
// no mass zero
else if( mj2 != ZERO && mk2 != ZERO ) {
res += 1./vjk * ( rho==0. ? 0. : log(rho) );
}
return res;
}
double DipoleMIOperator::GammaQuark(const ParticleData& j) const {
if ( j.hardProcessMass() == ZERO )
return 0.;
Energy2 mu2 = lastBorn()->mu2();
return CF * ( 0.5*log(sqr(j.hardProcessMass())/mu2) - 2. );
}
double DipoleMIOperator::GammaGluon() const {
// Finite contribution cancels with similar contribution in VjNS.
return 0.;
}
double DipoleMIOperator::GammaQuarkSinglePole(const ParticleData& j) const {
if ( j.hardProcessMass() == ZERO ) {
return gammaQuark;
}
return CF;
}
double DipoleMIOperator::GammaGluonSinglePole() const {
return gammaGluon;
}
//////////////////////////////////////////////////////////////////////
void DipoleMIOperator::persistentOutput(PersistentOStream & os) const {
os << CA << CF << gammaQuark << gammaGluon << betaZero
<< KQuark << KGluon;
}
void DipoleMIOperator::persistentInput(PersistentIStream & is, int) {
is >> CA >> CF >> gammaQuark >> gammaGluon >> betaZero
>> KQuark >> KGluon;
}
// *** 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<DipoleMIOperator,MatchboxInsertionOperator>
describeHerwigDipoleMIOperator("Herwig::DipoleMIOperator", "Herwig.so");
void DipoleMIOperator::Init() {
static ClassDocumentation<DipoleMIOperator> documentation
("DipoleMIOperator");
DipoleRepository::registerInsertionIOperator<0,DipoleMIOperator>("MassiveIOperator");
}
diff --git a/MatrixElement/Matchbox/MatchboxFactory.cc b/MatrixElement/Matchbox/MatchboxFactory.cc
--- a/MatrixElement/Matchbox/MatchboxFactory.cc
+++ b/MatrixElement/Matchbox/MatchboxFactory.cc
@@ -1,1882 +1,1878 @@
// -*- C++ -*-
//
// MatchboxFactory.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 MatchboxFactory class.
//
#include "MatchboxFactory.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Utilities/StringUtils.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Handlers/SamplerBase.h"
#include "Herwig++/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig++/MatrixElement/Matchbox/Utility/SU2Helper.h"
#include "Herwig++/Utilities/RunDirectories.h"
#include <boost/progress.hpp>
#include <boost/filesystem.hpp>
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
using std::ostream_iterator;
MatchboxFactory::MatchboxFactory()
: SubProcessHandler(), theNLight(0),
theOrderInAlphaS(0), theOrderInAlphaEW(0),
theBornContributions(true), theVirtualContributions(true),
theRealContributions(true), theIndependentVirtuals(false),
theIndependentPKs(false),
theSubProcessGroups(false),
theFactorizationScaleFactor(1.0), theRenormalizationScaleFactor(1.0),
theFixedCouplings(false), theFixedQEDCouplings(false), theVetoScales(false),
theDipoleSet(0), theVerbose(false), theDiagramWeightVerbose(false),
theDiagramWeightVerboseNBins(200),
theInitVerbose(false),
theSubtractionData(""), theSubtractionPlotType(1), theSubtractionScatterPlot(false),
thePoleData(""), theRealEmissionScales(false), theAllProcesses(false),
theMECorrectionsOnly(false), theLoopSimCorrections(false), ranSetup(false),
theFirstPerturbativePDF(true), theSecondPerturbativePDF(true),
inProductionMode(false), theSpinCorrelations(false),theAlphaParameter(1.) {}
MatchboxFactory::~MatchboxFactory() {}
bool& MatchboxFactory::theIsMatchboxRun() {
static bool flag = false;
return flag;
}
IBPtr MatchboxFactory::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxFactory::fullclone() const {
return new_ptr(*this);
}
void MatchboxFactory::prepareME(Ptr<MatchboxMEBase>::ptr me) {
Ptr<MatchboxAmplitude>::ptr amp =
dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>((*me).amplitude());
me->matchboxAmplitude(amp);
me->factory(this);
if ( phasespace() && !me->phasespace() )
me->phasespace(phasespace());
if ( scaleChoice() && !me->scaleChoice() )
me->scaleChoice(scaleChoice());
if ( !reweighters().empty() ) {
for ( vector<ReweightPtr>::const_iterator rw = reweighters().begin();
rw != reweighters().end(); ++rw )
me->addReweighter(*rw);
}
if ( !preweighters().empty() ) {
for ( vector<ReweightPtr>::const_iterator rw = preweighters().begin();
rw != preweighters().end(); ++rw )
me->addPreweighter(*rw);
}
}
string pid(const PDVector& key) {
ostringstream res;
res << "[" << key[0]->PDGName() << ","
<< key[1]->PDGName() << "->";
for ( PDVector::const_iterator k =
key.begin() + 2; k != key.end(); ++k )
res << (**k).PDGName() << (k != --key.end() ? "," : "");
res << "]";
return res.str();
}
vector<Ptr<MatchboxMEBase>::ptr> MatchboxFactory::
makeMEs(const vector<string>& proc, unsigned int orderas, bool virt) {
generator()->log() << "determining subprocesses for ";
copy(proc.begin(),proc.end(),ostream_iterator<string>(generator()->log()," "));
generator()->log() << "\n" << flush;
map<Ptr<MatchboxAmplitude>::ptr,set<Process> > ampProcs;
map<Process,set<Ptr<MatchboxAmplitude>::ptr> > procAmps;
set<PDVector> processes = makeSubProcesses(proc);
vector<Ptr<MatchboxAmplitude>::ptr> matchAmplitudes;
unsigned int lowestAsOrder =
allProcesses() ? 0 : orderas;
unsigned int highestAsOrder = orderas;
unsigned int lowestAeOrder =
allProcesses() ? 0 : orderInAlphaEW();
unsigned int highestAeOrder = orderInAlphaEW();
for ( unsigned int oas = lowestAsOrder; oas <= highestAsOrder; ++oas ) {
for ( unsigned int oae = lowestAeOrder; oae <= highestAeOrder; ++oae ) {
for ( vector<Ptr<MatchboxAmplitude>::ptr>::const_iterator amp
= amplitudes().begin(); amp != amplitudes().end(); ++amp ) {
if ( !theSelectedAmplitudes.empty() ) {
if ( find(theSelectedAmplitudes.begin(),theSelectedAmplitudes.end(),*amp)
== theSelectedAmplitudes.end() )
continue;
}
if ( !theDeselectedAmplitudes.empty() ) {
if ( find(theDeselectedAmplitudes.begin(),theDeselectedAmplitudes.end(),*amp)
!= theDeselectedAmplitudes.end() )
continue;
}
(**amp).orderInGs(oas);
(**amp).orderInGem(oae);
if ( (**amp).orderInGs() != oas ||
(**amp).orderInGem() != oae ) {
continue;
}
matchAmplitudes.push_back(*amp);
}
}
}
size_t combinations = processes.size()*matchAmplitudes.size();
size_t procCount = 0;
generator()->log() << "building matrix elements." << flush;
boost::progress_display * progressBar =
new boost::progress_display(combinations,generator()->log());
for ( unsigned int oas = lowestAsOrder; oas <= highestAsOrder; ++oas ) {
for ( unsigned int oae = lowestAeOrder; oae <= highestAeOrder; ++oae ) {
for ( vector<Ptr<MatchboxAmplitude>::ptr>::const_iterator amp
= matchAmplitudes.begin(); amp != matchAmplitudes.end(); ++amp ) {
(**amp).orderInGs(oas);
(**amp).orderInGem(oae);
for ( set<PDVector>::const_iterator p = processes.begin();
p != processes.end(); ++p ) {
++(*progressBar);
if ( !(**amp).canHandle(*p,this,virt) )
continue;
if ( (**amp).isExternal() )
externalAmplitudes().insert(*amp);
++procCount;
Process proc(*p,oas,oae);
ampProcs[*amp].insert(proc);
procAmps[proc].insert(*amp);
}
}
}
}
delete progressBar;
generator()->log() << flush;
bool clash = false;
for ( map<Process,set<Ptr<MatchboxAmplitude>::ptr> >::const_iterator check =
procAmps.begin(); check != procAmps.end(); ++check ) {
if ( check->second.size() > 1 ) {
clash = true;
generator()->log() << "Several different amplitudes have been found for: "
<< check->first.legs[0]->PDGName() << " "
<< check->first.legs[1]->PDGName() << " -> ";
for ( PDVector::const_iterator p = check->first.legs.begin() + 2;
p != check->first.legs.end(); ++p )
generator()->log() << (**p).PDGName() << " ";
generator()->log() << "at alpha_s^" << check->first.orderInAlphaS
<< " and alpha_ew^" << check->first.orderInAlphaEW
<< "\n";
generator()->log() << "The following amplitudes claim responsibility:\n";
for ( set<Ptr<MatchboxAmplitude>::ptr>::const_iterator a = check->second.begin();
a != check->second.end(); ++a ) {
generator()->log() << (**a).name() << " ";
}
generator()->log() << "\n";
}
}
if ( clash ) {
- throw InitException()
- << "Ambiguous amplitude setup - please check your input files.\n"
+ throw InitException() << "MatchboxFactory: Ambiguous amplitude setup - please check your input files.\n"
<< "To avoid this problem use the SelectAmplitudes or DeselectAmplitudes interfaces.\n";
}
bool canDoSpinCorrelations = true;
vector<Ptr<MatchboxMEBase>::ptr> res;
for ( map<Ptr<MatchboxAmplitude>::ptr,set<Process> >::const_iterator
ap = ampProcs.begin(); ap != ampProcs.end(); ++ap ) {
canDoSpinCorrelations &= ap->first->canFillRhoMatrix();
for ( set<Process>::const_iterator m = ap->second.begin();
m != ap->second.end(); ++m ) {
Ptr<MatchboxMEBase>::ptr me = ap->first->makeME(m->legs);
me->subProcess() = *m;
me->amplitude(ap->first);
me->matchboxAmplitude(ap->first);
prepareME(me);
string pname = "ME" + ap->first->name() + pid(m->legs);
if ( ! (generator()->preinitRegister(me,pname) ) )
- throw InitException() << "Matrix element " << pname << " already existing.";
+ throw InitException() << "MatchboxFactory: Matrix element " << pname << " already existing.";
if ( me->diagrams().empty() )continue;
res.push_back(me);
if ( theFirstPerturbativePDF )
theIncoming.insert(m->legs[0]->id());
if ( theSecondPerturbativePDF )
theIncoming.insert(m->legs[1]->id());
}
}
if ( spinCorrelations() && !canDoSpinCorrelations ) {
generator()->log() << "Warning: Spin correlations have been requested, but no amplitude is "
<< "capable of performing these.\n";
theSpinCorrelations = false;
}
generator()->log() << "created "
<< procCount << " subprocesses.\n";
generator()->log() << "--------------------------------------------------------------------------------\n"
<< flush;
return res;
}
int MatchboxFactory::orderOLPProcess(const Process& proc,
Ptr<MatchboxAmplitude>::tptr amp,
int type) {
map<pair<Process,int>,int>& procs =
olpProcesses()[amp];
map<pair<Process,int>,int>::const_iterator it =
procs.find(make_pair(proc,type));
if ( it != procs.end() )
return it->second;
int id = procs.size();
procs[make_pair(proc,type)] = id + 1;
return id + 1;
}
void MatchboxFactory::productionMode() {
if ( inProductionMode )
return;
if ( !bornContributions() && !virtualContributions() && !realContributions() )
- throw Exception()
- << "At least one cross section contribution needs to be enabled.\n"
+ throw InitException() << "MatchboxFactory: At least one cross section contribution needs to be enabled.\n"
<< "Please check your setup.\n"
<< Exception::abortnow;
bool needTrueVirtuals =
virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections();
for ( vector<Ptr<MatchboxAmplitude>::ptr>::iterator amp
= amplitudes().begin(); amp != amplitudes().end(); ++amp ) {
if ( !needTrueVirtuals && (**amp).oneLoopAmplitude() ) {
Repository::clog() << "One-loop contributions from '"
<< (**amp).name()
<< "' are not required and will be disabled.\n"
<< flush;
(**amp).disableOneLoop();
}
}
if ( showerApproximation() && !virtualContributions() && !realContributions() ) {
Repository::clog() << "Warning: Matching requested for LO run. Matching disabled.\n" << flush;
showerApproximation(Ptr<ShowerApproximation>::tptr());
}
if ( showerApproximation() && (subtractionData() != "" || subProcessGroups()) ) {
Repository::clog() << "Warning: Matching requested for plain NLO run. Matching disabled.\n" << flush;
showerApproximation(Ptr<ShowerApproximation>::tptr());
}
if ( showerApproximation() ) {
if ( spinCorrelations() && !showerApproximation()->hasSpinCorrelations() ) {
Repository::clog() << "Warning: Spin correlations have been requested but the matching "
<< "object is not capable of these. Spin correlations will be turned of.\n"
<< flush;
theSpinCorrelations = false;
}
}
inProductionMode = true;
}
void MatchboxFactory::setup() {
useMe();
if ( !ranSetup ) {
if ( !inProductionMode )
- throw Exception() << "The MatchboxFactory object '"
- << name() << "' has not been switched to production mode.\n"
- << "Did you use 'do "
- << name() << ":ProductionMode' before isolating the event generator?\n"
- << Exception::abortnow;
+ throw InitException() << "MatchboxFactory: The MatchboxFactory object '"
+ << name() << "' has not been switched to production mode.\n"
+ << "Did you use 'do "
+ << name() << ":ProductionMode' before isolating the event generator?\n"
+ << Exception::abortnow;
olpProcesses().clear();
externalAmplitudes().clear();
theHighestVirtualsize = 0;
theIncoming.clear();
bool needTrueVirtuals =
virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections();
for ( vector<Ptr<MatchboxAmplitude>::ptr>::iterator amp
= amplitudes().begin(); amp != amplitudes().end(); ++amp )
(**amp).factory(this);
if ( bornMEs().empty() ) {
if ( particleGroups().find("j") == particleGroups().end() )
- throw InitException() << "Could not find a jet particle group named 'j'";
+ throw InitException() << "MatchboxFactory: Could not find a jet particle group named 'j'";
// rebind the particle data objects
for ( map<string,PDVector>::iterator g = particleGroups().begin();
g != particleGroups().end(); ++g )
for ( PDVector::iterator p = g->second.begin();
p != g->second.end(); ++p ) {
#ifndef NDEBUG
long checkid = (**p).id();
#endif
*p = getParticleData((**p).id());
assert((**p).id() == checkid);
}
const PDVector& partons = particleGroups()["j"];
unsigned int nl = 0;
for ( PDVector::const_iterator p = partons.begin();
p != partons.end(); ++p ) {
if ( abs((**p).id()) < 7 && (**p).hardProcessMass() == ZERO )
++nl;
if ( (**p).id() > 0 && (**p).id() < 7 && (**p).hardProcessMass() == ZERO )
nLightJetVec( (**p).id() );
if ( (**p).id() > 0 && (**p).id() < 7 && (**p).hardProcessMass() != ZERO )
nHeavyJetVec( (**p).id() );
}
nLight(nl/2);
const PDVector& partonsInP = particleGroups()["p"];
for ( PDVector::const_iterator pip = partonsInP.begin();
pip != partonsInP.end(); ++pip ) {
if ( (**pip).id() > 0 && (**pip).id() < 7 && (**pip).hardProcessMass() == ZERO )
nLightProtonVec( (**pip).id() );
}
vector<Ptr<MatchboxMEBase>::ptr> mes;
for ( vector<vector<string> >::const_iterator p = processes.begin();
p != processes.end(); ++p ) {
if( needTrueVirtuals ) {
theHighestVirtualsize = max(theHighestVirtualsize,(int((*p).size())));
}
mes = makeMEs(*p,orderInAlphaS(),needTrueVirtuals);
copy(mes.begin(),mes.end(),back_inserter(bornMEs()));
if ( (realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()))
&& realEmissionMEs().empty() ) {
if ( realEmissionProcesses.empty() ) {
vector<string> rproc = *p;
rproc.push_back("j");
mes = makeMEs(rproc,orderInAlphaS()+1,false);
copy(mes.begin(),mes.end(),back_inserter(realEmissionMEs()));
}
}
}
if ( (realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()))
&& realEmissionMEs().empty() ) {
if ( !realEmissionProcesses.empty() ) {
for ( vector<vector<string> >::const_iterator q =
realEmissionProcesses.begin(); q != realEmissionProcesses.end(); ++q ) {
mes = makeMEs(*q,orderInAlphaS()+1,false);
copy(mes.begin(),mes.end(),back_inserter(realEmissionMEs()));
}
}
}
}
if ( loopInducedMEs().empty() ) {
for ( vector<vector<string> >::const_iterator p = loopInducedProcesses.begin();
p != loopInducedProcesses.end(); ++p ) {
vector<Ptr<MatchboxMEBase>::ptr> mes = makeMEs(*p,orderInAlphaS(),false);
copy(mes.begin(),mes.end(),back_inserter(loopInducedMEs()));
}
}
if( bornMEs().empty() && realEmissionMEs().empty() && loopInducedMEs().empty() )
- throw InitException() << "No matrix elements have been found.\n\
+ throw InitException() << "MatchboxFactory: No matrix elements have been found.\n\
Please check if your order of Alpha_s and Alpha_ew have the right value.\n";
// check if we have virtual contributions
bool haveVirtuals = true;
// check DR conventions of virtual contributions
bool virtualsAreDR = false;
bool virtualsAreCDR = false;
// check finite term conventions of virtual contributions
bool virtualsAreCS = false;
bool virtualsAreBDK = false;
bool virtualsAreExpanded = false;
// renormalization scheme
bool virtualsAreDRbar = false;
// check and prepare the Born and virtual matrix elements
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
prepareME(*born);
haveVirtuals &= (**born).haveOneLoop();
if ( needTrueVirtuals ) {
if ( (**born).haveOneLoop() ) {
virtualsAreDRbar |= (**born).isDRbar();
virtualsAreDR |= (**born).isDR();
virtualsAreCDR |= !(**born).isDR();
virtualsAreCS |= (**born).isCS();
virtualsAreBDK |= (**born).isBDK();
virtualsAreExpanded |= (**born).isExpanded();
}
}
}
// prepare the loop induced matrix elements
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator looped
= loopInducedMEs().begin(); looped != loopInducedMEs().end(); ++looped ) {
prepareME(*looped);
}
if ( needTrueVirtuals ) {
// check the additional insertion operators
if ( !virtuals().empty() )
haveVirtuals = true;
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= virtuals().begin(); virt != virtuals().end(); ++virt ) {
virtualsAreDRbar |= (**virt).isDRbar();
virtualsAreDR |= (**virt).isDR();
virtualsAreCDR |= !(**virt).isDR();
virtualsAreCS |= (**virt).isCS();
virtualsAreBDK |= (**virt).isBDK();
virtualsAreExpanded |= (**virt).isExpanded();
}
// check for consistent conventions on virtuals, if we are to include them
if ( virtualContributions() ) {
if ( !haveVirtuals ) {
- throw InitException() << "Could not find amplitudes for all virtual contributions needed.\n";
+ throw InitException() << "MatchboxFactory: Could not find amplitudes for all virtual contributions needed.\n";
}
if ( virtualsAreDR && virtualsAreCDR ) {
- throw InitException() << "Virtual corrections use inconsistent regularization schemes.\n";
+ throw InitException() << "MatchboxFactory: Virtual corrections use inconsistent regularization schemes.\n";
}
if ( (virtualsAreCS && virtualsAreBDK) ||
(virtualsAreCS && virtualsAreExpanded) ||
(virtualsAreBDK && virtualsAreExpanded) ||
(!virtualsAreCS && !virtualsAreBDK && !virtualsAreExpanded) ) {
- throw InitException() << "Virtual corrections use inconsistent conventions on finite terms.\n";
+ throw InitException() << "MatchboxFactory: Virtual corrections use inconsistent conventions on finite terms.\n";
}
}
// prepare dipole insertion operators
if ( virtualContributions() ) {
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionIOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionIOperators(dipoleSet()).end(); ++virt ) {
(**virt).factory(this);
if ( virtualsAreDRbar )
(**virt).useDRbar();
if ( virtualsAreDR )
(**virt).useDR();
else
(**virt).useCDR();
if ( virtualsAreCS )
(**virt).useCS();
if ( virtualsAreBDK )
(**virt).useBDK();
if ( virtualsAreExpanded )
(**virt).useExpanded();
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionPKOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionPKOperators(dipoleSet()).end(); ++virt ) {
(**virt).factory(this);
if ( virtualsAreDRbar )
(**virt).useDRbar();
if ( virtualsAreDR )
(**virt).useDR();
else
(**virt).useCDR();
if ( virtualsAreCS )
(**virt).useCS();
if ( virtualsAreBDK )
(**virt).useBDK();
if ( virtualsAreExpanded )
(**virt).useExpanded();
}
}
}
// prepare the real emission matrix elements
if ( realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()) ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator real
= realEmissionMEs().begin(); real != realEmissionMEs().end(); ++real ) {
prepareME(*real);
}
}
// start creating matrix elements
MEs().clear();
// setup born and virtual contributions
if ( bornContributions() || virtualContributions() ) {
generator()->log() << "preparing Born"
<< (virtualContributions() ? " and virtual" : "")
<< " matrix elements.\n" << flush;
}
if ( (bornContributions() && !virtualContributions()) ||
(bornContributions() && virtualContributions() && independentVirtuals()) ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
if ( (**born).onlyOneLoop() )
continue;
Ptr<MatchboxMEBase>::ptr bornme = (**born).cloneMe();
string pname = fullName() + "/" + (**born).name();
if ( virtualContributions() && independentVirtuals() )
pname += ".Born";
if ( ! (generator()->preinitRegister(bornme,pname) ) )
- throw InitException() << "Matrix element " << pname << " already existing.";
+ throw InitException() << "MatchboxFactory: Matrix element " << pname << " already existing.";
if ( bornme->isOLPTree() ) {
int id = orderOLPProcess(bornme->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::treeME2);
bornme->olpProcess(ProcessType::treeME2,id);
}
bornme->needsNoCorrelations();
bornme->cloneDependencies();
MEs().push_back(bornme);
}
}
if ( bornContributions() && !loopInducedMEs().empty() ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator looped
= loopInducedMEs().begin(); looped != loopInducedMEs().end(); ++looped ) {
Ptr<MatchboxMEBase>::ptr loopme = (**looped).cloneMe();
string pname = fullName() + "/" + (**looped).name() + ".LoopInduced";
if ( ! (generator()->preinitRegister(loopme,pname) ) )
- throw InitException() << "Matrix element " << pname << " already existing.";
+ throw InitException() << "MatchboxFactory: Matrix element " << pname << " already existing.";
if ( loopme->isOLPTree() ) {
int id = orderOLPProcess(loopme->subProcess(),
(**looped).matchboxAmplitude(),
ProcessType::loopInducedME2);
loopme->olpProcess(ProcessType::loopInducedME2,id);
}
loopme->needsNoCorrelations();
loopme->cloneDependencies();
MEs().push_back(loopme);
}
}
if ( needTrueVirtuals ) {
bornVirtualMEs().clear();
boost::progress_display * progressBar =
new boost::progress_display(bornMEs().size(),generator()->log());
if ( thePoleData != "" )
if ( thePoleData[thePoleData.size()-1] != '/' )
thePoleData += "/";
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
Ptr<MatchboxMEBase>::ptr nlo = (**born).cloneMe();
string pname = fullName() + "/" + (**born).name();
if ( !independentVirtuals() && !(!bornContributions() && virtualContributions()) )
pname += ".BornVirtual";
else if ( independentPKs() && !nlo->onlyOneLoop() )
pname += ".VirtualVI";
else
pname += ".Virtual";
if ( ! (generator()->preinitRegister(nlo,pname) ) )
- throw InitException() << "NLO ME " << pname << " already existing.";
+ throw InitException() << "MatchboxFactory: NLO ME " << pname << " already existing.";
nlo->virtuals().clear();
if ( !nlo->onlyOneLoop() ) {
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= virtuals().begin(); virt != virtuals().end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlo->virtuals().push_back(*virt);
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionIOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionIOperators(dipoleSet()).end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlo->virtuals().push_back(*virt);
}
if ( !independentVirtuals() || ( independentVirtuals() && !independentPKs() ) ) {
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionPKOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionPKOperators(dipoleSet()).end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlo->virtuals().push_back(*virt);
}
}
if ( nlo->virtuals().empty() )
- throw InitException() << "No insertion operators have been found for "
+ throw InitException() << "MatchboxFactory: No insertion operators have been found for "
<< (**born).name() << "\n";
if ( checkPoles() ) {
if ( !virtualsAreExpanded ) {
- throw InitException() << "Cannot check epsilon poles if virtuals are not in `expanded' convention.\n";
+ throw InitException() << "MatchboxFactory: Cannot check epsilon poles if virtuals are not in `expanded' convention.\n";
}
}
}
if ( !bornContributions() || independentVirtuals() ) {
nlo->doOneLoopNoBorn();
} else {
nlo->doOneLoop();
}
if ( nlo->isOLPLoop() ) {
int id = orderOLPProcess(nlo->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::oneLoopInterference);
nlo->olpProcess(ProcessType::oneLoopInterference,id);
if ( !nlo->onlyOneLoop() && nlo->needsOLPCorrelators() ) {
id = orderOLPProcess(nlo->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
nlo->olpProcess(ProcessType::colourCorrelatedME2,id);
}
}
nlo->needsCorrelations();
nlo->cloneDependencies();
bornVirtualMEs().push_back(nlo);
MEs().push_back(nlo);
if ( independentVirtuals() && independentPKs() && !nlo->onlyOneLoop() ) {
Ptr<MatchboxMEBase>::ptr nlopk = (**born).cloneMe();
string pnamepk = fullName() + "/" + (**born).name();
pnamepk += ".VirtualPK";
if ( ! (generator()->preinitRegister(nlopk,pnamepk) ) )
- throw InitException() << "NLO ME " << pnamepk << " already existing.";
+ throw InitException() << "MatchboxFactory: NLO ME " << pnamepk << " already existing.";
nlopk->virtuals().clear();
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionPKOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionPKOperators(dipoleSet()).end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlopk->virtuals().push_back(*virt);
}
if ( !nlopk->virtuals().empty() ) {
nlopk->doOneLoopNoBorn();
nlopk->doOneLoopNoLoops();
if ( nlopk->isOLPLoop() ) {
int id = orderOLPProcess(nlopk->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::treeME2);
nlopk->olpProcess(ProcessType::treeME2,id);
if ( nlopk->needsOLPCorrelators() ) {
id = orderOLPProcess(nlopk->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
nlopk->olpProcess(ProcessType::colourCorrelatedME2,id);
}
}
nlopk->needsCorrelations();
nlopk->cloneDependencies();
bornVirtualMEs().push_back(nlopk);
MEs().push_back(nlopk);
}
}
++(*progressBar);
}
delete progressBar;
generator()->log() << "--------------------------------------------------------------------------------\n"
<< flush;
}
theSplittingDipoles.clear();
set<cPDVector> bornProcs;
if ( showerApproximation() ) {
if ( showerApproximation()->needsSplittingGenerator() ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born )
for ( MEBase::DiagramVector::const_iterator d = (**born).diagrams().begin();
d != (**born).diagrams().end(); ++d )
bornProcs.insert((**d).partons());
}
}
if ( realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()) ) {
generator()->log() << "preparing subtracted matrix elements.\n" << flush;
if ( theSubtractionData != "" )
if ( theSubtractionData[theSubtractionData.size()-1] != '/' )
theSubtractionData += "/";
subtractedMEs().clear();
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
if ( (**born).onlyOneLoop() )
continue;
(**born).needsCorrelations();
if ( (**born).isOLPTree() ) {
int id = orderOLPProcess((**born).subProcess(),
(**born).matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
(**born).olpProcess(ProcessType::colourCorrelatedME2,id);
bool haveGluon = false;
for ( PDVector::const_iterator p = (**born).subProcess().legs.begin();
p != (**born).subProcess().legs.end(); ++p )
if ( (**p).id() == 21 ) {
haveGluon = true;
break;
}
if ( haveGluon ) {
id = orderOLPProcess((**born).subProcess(),
(**born).matchboxAmplitude(),
ProcessType::spinColourCorrelatedME2);
(**born).olpProcess(ProcessType::spinColourCorrelatedME2,id);
}
if ( showerApproximation() ) {
id = orderOLPProcess((**born).subProcess(),
(**born).matchboxAmplitude(),
ProcessType::treeME2);
(**born).olpProcess(ProcessType::treeME2,id);
}
}
}
boost::progress_display * progressBar =
new boost::progress_display(realEmissionMEs().size(),generator()->log());
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator real
= realEmissionMEs().begin(); real != realEmissionMEs().end(); ++real ) {
Ptr<SubtractedME>::ptr sub = new_ptr(SubtractedME());
string pname = fullName() + "/" + (**real).name() + ".SubtractedReal";
if ( ! (generator()->preinitRegister(sub,pname) ) )
- throw InitException() << "Subtracted ME " << pname << " already existing.";
+ throw InitException() << "MatchboxFactory: Subtracted ME " << pname << " already existing.";
sub->factory(this);
(**real).needsNoCorrelations();
if ( (**real).isOLPTree() ) {
int id = orderOLPProcess((**real).subProcess(),
(**real).matchboxAmplitude(),
ProcessType::treeME2);
(**real).olpProcess(ProcessType::treeME2,id);
}
sub->head(*real);
sub->dependent().clear();
sub->getDipoles();
if ( sub->dependent().empty() ) {
// finite real contribution
if ( realContributions() ) {
Ptr<MatchboxMEBase>::ptr fme =
dynamic_ptr_cast<Ptr<MatchboxMEBase>::ptr>(sub->head())->cloneMe();
string qname = fullName() + "/" + (**real).name() + ".FiniteReal";
if ( ! (generator()->preinitRegister(fme,qname) ) )
- throw InitException() << "ME " << qname << " already existing.";
+ throw InitException() << "MatchboxFactory: ME " << qname << " already existing.";
MEs().push_back(fme);
finiteRealMEs().push_back(fme);
}
sub->head(tMEPtr());
++(*progressBar);
continue;
}
if ( realEmissionScales() )
sub->doRealEmissionScales();
subtractedMEs().push_back(sub);
if ( realContributions() )
if ( !showerApproximation() || (showerApproximation() && showerApproximation()->hasHEvents()) )
MEs().push_back(sub);
if ( showerApproximation() ) {
if ( virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections() ) {
Ptr<SubtractedME>::ptr subv = new_ptr(*sub);
string vname = sub->fullName() + ".SubtractionIntegral";
if ( ! (generator()->preinitRegister(subv,vname) ) )
- throw InitException() << "Subtracted ME " << vname << " already existing.";
+ throw InitException() << "MatchboxFactory: Subtracted ME " << vname << " already existing.";
subv->cloneDependencies(vname);
subv->doVirtualShowerSubtraction();
subtractedMEs().push_back(subv);
MEs().push_back(subv);
}
if ( loopSimCorrections() ) {
Ptr<SubtractedME>::ptr subv = new_ptr(*sub);
string vname = sub->fullName() + ".SubtractionIntegral";
if ( ! (generator()->preinitRegister(subv,vname) ) )
- throw InitException() << "Subtracted ME " << vname << " already existing.";
+ throw InitException() << "MatchboxFactory: Subtracted ME " << vname << " already existing.";
subv->cloneDependencies(vname);
subv->doLoopSimSubtraction();
subtractedMEs().push_back(subv);
MEs().push_back(subv);
}
sub->doRealShowerSubtraction();
if ( showerApproximation()->needsSplittingGenerator() )
for ( set<cPDVector>::const_iterator p = bornProcs.begin();
p != bornProcs.end(); ++p ) {
vector<Ptr<SubtractionDipole>::ptr> sdip = sub->splitDipoles(*p);
set<Ptr<SubtractionDipole>::ptr>& dips = theSplittingDipoles[*p];
copy(sdip.begin(),sdip.end(),inserter(dips,dips.begin()));
}
}
++(*progressBar);
}
delete progressBar;
generator()->log() << "--------------------------------------------------------------------------------\n"
<< flush;
}
if ( !theSplittingDipoles.empty() ) {
map<Ptr<SubtractionDipole>::ptr,Ptr<SubtractionDipole>::ptr> cloneMap;
for ( map<cPDVector,set<Ptr<SubtractionDipole>::ptr> >::const_iterator sd = theSplittingDipoles.begin();
sd != theSplittingDipoles.end(); ++sd ) {
for ( set<Ptr<SubtractionDipole>::ptr>::const_iterator d = sd->second.begin();
d != sd->second.end(); ++d ) {
cloneMap[*d] = Ptr<SubtractionDipole>::ptr();
}
}
for ( map<Ptr<SubtractionDipole>::ptr,Ptr<SubtractionDipole>::ptr>::iterator cd =
cloneMap.begin(); cd != cloneMap.end(); ++cd ) {
Ptr<SubtractionDipole>::ptr cloned = cd->first->cloneMe();
string dname = cd->first->fullName() + ".splitting";
if ( ! (generator()->preinitRegister(cloned,dname)) )
- throw InitException() << "Dipole '" << dname << "' already existing.";
+ throw InitException() << "MatchboxFactory: Dipole '" << dname << "' already existing.";
cloned->cloneDependencies();
cloned->showerApproximation(Ptr<ShowerApproximation>::tptr());
cloned->doSplitting();
cd->second = cloned;
}
for ( map<cPDVector,set<Ptr<SubtractionDipole>::ptr> >::iterator sd = theSplittingDipoles.begin();
sd != theSplittingDipoles.end(); ++sd ) {
set<Ptr<SubtractionDipole>::ptr> cloned;
for ( set<Ptr<SubtractionDipole>::ptr>::iterator d = sd->second.begin();
d != sd->second.end(); ++d ) {
cloned.insert(cloneMap[*d]);
}
sd->second = cloned;
}
}
if ( !externalAmplitudes().empty() ) {
generator()->log() << "Initializing external amplitudes.\n" << flush;
for ( set<Ptr<MatchboxAmplitude>::tptr>::const_iterator ext =
externalAmplitudes().begin(); ext != externalAmplitudes().end(); ++ext ) {
if ( !(**ext).initializeExternal() ) {
- throw InitException()
- << "error: failed to initialize amplitude '" << (**ext).name() << "'\n";
+ throw InitException() << "Failed to initialize amplitude '" << (**ext).name() << "'\n";
}
}
generator()->log() << "--------------------------------------------------------------------------------\n"
<< flush;
}
if ( !olpProcesses().empty() ) {
generator()->log() << "Initializing one-loop provider(s).\n" << flush;
map<Ptr<MatchboxAmplitude>::tptr,map<pair<Process,int>,int> > olps;
for ( map<Ptr<MatchboxAmplitude>::tptr,map<pair<Process,int>,int> >::const_iterator
oit = olpProcesses().begin(); oit != olpProcesses().end(); ++oit ) {
olps[oit->first] = oit->second;
}
for ( map<Ptr<MatchboxAmplitude>::tptr,map<pair<Process,int>,int> >::const_iterator
olpit = olps.begin(); olpit != olps.end(); ++olpit ) {
if ( !olpit->first->startOLP(olpit->second) ) {
- throw InitException()
- << "error: failed to start OLP for amplitude '" << olpit->first->name() << "'\n";
+ throw InitException() << "MatchboxFactory: Failed to start OLP for amplitude '" << olpit->first->name() << "'\n";
}
}
generator()->log() << "--------------------------------------------------------------------------------\n"
<< flush;
}
generator()->log() << "Process setup finished.\n" << flush;
ranSetup = true;
}
}
void MatchboxFactory::SplittingChannel::print(ostream& os) const {
os << "--- SplittingChannel setup -----------------------------------------------------\n";
os << " Born process ";
const StandardXComb& bxc = *bornXComb;
os << bxc.mePartonData()[0]->PDGName() << " "
<< bxc.mePartonData()[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = bxc.mePartonData().begin() + 2;
p != bxc.mePartonData().end(); ++p ) {
os << (**p).PDGName() << " ";
}
os << "\n";
os << " to real emission process ";
const StandardXComb& rxc = *realXComb;
os << rxc.mePartonData()[0]->PDGName() << " "
<< rxc.mePartonData()[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = rxc.mePartonData().begin() + 2;
p != rxc.mePartonData().end(); ++p ) {
os << (**p).PDGName() << " ";
}
os << "\n";
os << " with dipole:\n";
dipole->print(os);
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
list<MatchboxFactory::SplittingChannel>
MatchboxFactory::getSplittingChannels(tStdXCombPtr xcptr) const {
if ( xcptr->lastProjector() )
xcptr = xcptr->lastProjector();
const StandardXComb& xc = *xcptr;
cPDVector proc = xc.mePartonData();
map<cPDVector,set<Ptr<SubtractionDipole>::ptr> >::const_iterator splitEntries
= splittingDipoles().find(proc);
list<SplittingChannel> res;
if ( splitEntries == splittingDipoles().end() )
return res;
const set<Ptr<SubtractionDipole>::ptr>& splitDipoles = splitEntries->second;
SplittingChannel channel;
if ( !splitDipoles.empty() ) {
Ptr<MatchboxMEBase>::tptr bornME =
const_ptr_cast<Ptr<MatchboxMEBase>::tptr>((**splitDipoles.begin()).underlyingBornME());
channel.bornXComb =
bornME->makeXComb(xc.maxEnergy(),xc.particles(),xc.eventHandlerPtr(),
const_ptr_cast<tSubHdlPtr>(xc.subProcessHandler()),
xc.pExtractor(),xc.CKKWHandler(),
xc.partonBins(),xc.cuts(),xc.diagrams(),xc.mirror(),
PartonPairVec());
}
for ( set<Ptr<SubtractionDipole>::ptr>::const_iterator sd =
splitDipoles.begin(); sd != splitDipoles.end(); ++sd ) {
channel.dipole = *sd;
vector<StdXCombPtr> realXCombs = (**sd).makeRealXCombs(channel.bornXComb);
for ( vector<StdXCombPtr>::const_iterator rxc = realXCombs.begin();
rxc != realXCombs.end(); ++rxc ) {
channel.realXComb = *rxc;
if ( showerApproximation()->needsTildeXCombs() ) {
channel.tildeXCombs.clear();
assert(!channel.dipole->partnerDipoles().empty());
for ( vector<Ptr<SubtractionDipole>::tptr>::const_iterator p =
channel.dipole->partnerDipoles().begin();
p != channel.dipole->partnerDipoles().end(); ++p ) {
StdXCombPtr txc = channel.dipole->makeBornXComb(channel.realXComb);
if ( txc )
channel.tildeXCombs.push_back(txc);
}
}
res.push_back(channel);
}
}
if ( initVerbose() ) {
generator()->log()
<< "--- MatchboxFactory splitting channels ----------------------------------------------\n";
const StandardXComb& bxc = *xcptr;
generator()->log() << " hard process handled is: ";
generator()->log() << bxc.mePartonData()[0]->PDGName() << " "
<< bxc.mePartonData()[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = bxc.mePartonData().begin() + 2;
p != bxc.mePartonData().end(); ++p ) {
generator()->log() << (**p).PDGName() << " ";
}
generator()->log() << "\n";
for ( list<MatchboxFactory::SplittingChannel>::const_iterator sp =
res.begin(); sp != res.end(); ++sp ) {
sp->print(generator()->log());
}
generator()->log()
<< "-------------------------------------------------------------------------------------\n"
<< flush;
}
return res;
}
void MatchboxFactory::print(ostream& os) const {
os << "--- MatchboxFactory setup -----------------------------------------------------------\n";
if ( !amplitudes().empty() ) {
os << " generated Born matrix elements:\n";
for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator m = bornMEs().begin();
m != bornMEs().end(); ++m ) {
(**m).print(os);
}
os << flush;
os << " generated real emission matrix elements:\n";
for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator m = realEmissionMEs().begin();
m != realEmissionMEs().end(); ++m ) {
(**m).print(os);
}
os << flush;
}
os << " generated Born+virtual matrix elements:\n";
for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator bv
= bornVirtualMEs().begin(); bv != bornVirtualMEs().end(); ++bv ) {
(**bv).print(os);
}
os << " generated subtracted matrix elements:\n";
for ( vector<Ptr<SubtractedME>::ptr>::const_iterator sub
= subtractedMEs().begin(); sub != subtractedMEs().end(); ++sub ) {
os << " '" << (**sub).name() << "'\n";
}
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void MatchboxFactory::doinit() {
theIsMatchboxRun() = true;
if ( RunDirectories::empty() )
RunDirectories::pushRunId(generator()->runName());
setup();
if ( theShowerApproximation )
theShowerApproximation->init();
if ( initVerbose() && !ranSetup )
print(Repository::clog());
Ptr<StandardEventHandler>::tptr eh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
assert(eh);
SubProcessHandler::doinit();
}
void MatchboxFactory::doinitrun() {
theIsMatchboxRun() = true;
if ( theShowerApproximation )
theShowerApproximation->initrun();
Ptr<StandardEventHandler>::tptr eh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
assert(eh);
SubProcessHandler::doinitrun();
}
const string& MatchboxFactory::buildStorage() {
return RunDirectories::buildStorage();
}
const string& MatchboxFactory::runStorage() {
return RunDirectories::runStorage();
}
void MatchboxFactory::persistentOutput(PersistentOStream & os) const {
os << theDiagramGenerator << theProcessData
<< theNLight
<< theNLightJetVec << theNHeavyJetVec << theNLightProtonVec
<< theOrderInAlphaS << theOrderInAlphaEW
<< theBornContributions << theVirtualContributions
<< theRealContributions << theIndependentVirtuals << theIndependentPKs
<< theSubProcessGroups
<< thePhasespace << theScaleChoice
<< theFactorizationScaleFactor << theRenormalizationScaleFactor
<< theFixedCouplings << theFixedQEDCouplings << theVetoScales
<< theAmplitudes
<< theBornMEs << theVirtuals << theRealEmissionMEs << theLoopInducedMEs
<< theBornVirtualMEs << theSubtractedMEs << theFiniteRealMEs
<< theVerbose<<theDiagramWeightVerbose
<<theDiagramWeightVerboseNBins
<< theInitVerbose << theSubtractionData << theSubtractionPlotType
<< theSubtractionScatterPlot << thePoleData
<< theParticleGroups << processes << loopInducedProcesses << realEmissionProcesses
<< theShowerApproximation << theSplittingDipoles
<< theRealEmissionScales << theAllProcesses
<< theOLPProcesses << theExternalAmplitudes
<< theSelectedAmplitudes << theDeselectedAmplitudes
<< theDipoleSet << theReweighters << thePreweighters
<< theMECorrectionsOnly<< theLoopSimCorrections<<theHighestVirtualsize << ranSetup
<< theIncoming << theFirstPerturbativePDF << theSecondPerturbativePDF
<< inProductionMode << theSpinCorrelations<<theAlphaParameter;
}
void MatchboxFactory::persistentInput(PersistentIStream & is, int) {
is >> theDiagramGenerator >> theProcessData
>> theNLight
>> theNLightJetVec >> theNHeavyJetVec >> theNLightProtonVec
>> theOrderInAlphaS >> theOrderInAlphaEW
>> theBornContributions >> theVirtualContributions
>> theRealContributions >> theIndependentVirtuals >> theIndependentPKs
>> theSubProcessGroups
>> thePhasespace >> theScaleChoice
>> theFactorizationScaleFactor >> theRenormalizationScaleFactor
>> theFixedCouplings >> theFixedQEDCouplings >> theVetoScales
>> theAmplitudes
>> theBornMEs >> theVirtuals >> theRealEmissionMEs >> theLoopInducedMEs
>> theBornVirtualMEs >> theSubtractedMEs >> theFiniteRealMEs
>> theVerbose >> theDiagramWeightVerbose
>> theDiagramWeightVerboseNBins
>> theInitVerbose >> theSubtractionData >> theSubtractionPlotType
>> theSubtractionScatterPlot >> thePoleData
>> theParticleGroups >> processes >> loopInducedProcesses >> realEmissionProcesses
>> theShowerApproximation >> theSplittingDipoles
>> theRealEmissionScales >> theAllProcesses
>> theOLPProcesses >> theExternalAmplitudes
>> theSelectedAmplitudes >> theDeselectedAmplitudes
>> theDipoleSet >> theReweighters >> thePreweighters
>> theMECorrectionsOnly>> theLoopSimCorrections>>theHighestVirtualsize >> ranSetup
>> theIncoming >> theFirstPerturbativePDF >> theSecondPerturbativePDF
>> inProductionMode >> theSpinCorrelations>>theAlphaParameter;
}
string MatchboxFactory::startParticleGroup(string name) {
particleGroupName = StringUtils::stripws(name);
particleGroup.clear();
return "";
}
string MatchboxFactory::endParticleGroup(string) {
if ( particleGroup.empty() )
- throw InitException() << "Empty particle group.";
+ throw InitException() << "MatchboxFactory: Empty particle group.";
particleGroups()[particleGroupName] = particleGroup;
particleGroup.clear();
return "";
}
vector<string> MatchboxFactory::parseProcess(string in) {
vector<string> process = StringUtils::split(in);
if ( process.size() < 3 )
- throw InitException() << "Invalid process.";
+ throw InitException() << "MatchboxFactory: Invalid process.";
for ( vector<string>::iterator p = process.begin();
p != process.end(); ++p ) {
*p = StringUtils::stripws(*p);
}
vector<string> pprocess;
for ( vector<string>::const_iterator p = process.begin();
p != process.end(); ++p ) {
if ( *p == "->" )
continue;
pprocess.push_back(*p);
}
return pprocess;
}
string MatchboxFactory::doProcess(string in) {
processes.push_back(parseProcess(in));
return "";
}
string MatchboxFactory::doLoopInducedProcess(string in) {
loopInducedProcesses.push_back(parseProcess(in));
return "";
}
string MatchboxFactory::doSingleRealProcess(string in) {
realEmissionProcesses.push_back(parseProcess(in));
return "";
}
struct SortPID {
inline bool operator()(PDPtr a, PDPtr b) const {
return a->id() < b->id();
}
};
set<PDVector> MatchboxFactory::
makeSubProcesses(const vector<string>& proc) const {
if ( proc.empty() )
- throw InitException() << "No process specified.";
+ throw InitException() << "MatchboxFactory: No process specified.";
vector<PDVector> groups;
typedef map<string,PDVector>::const_iterator GroupIterator;
for ( vector<string>::const_iterator gr = proc.begin();
gr != proc.end(); ++gr ) {
GroupIterator git = particleGroups().find(*gr);
if ( git == particleGroups().end() ) {
- throw InitException() << "particle group '"
+ throw InitException() << "MatchboxFactory: Particle group '"
<< *gr << "' not defined.";
}
groups.push_back(git->second);
}
vector<size_t> counts(groups.size(),0);
PDVector proto(groups.size());
set<PDVector> allProcs;
/*
cerr << "using the groups:\n";
for ( size_t k = 0; k < groups.size(); ++k ) {
cerr << k << " : ";
for ( PDVector::const_iterator p = groups[k].begin();
p != groups[k].end(); ++p )
cerr << (**p).PDGName() << " ";
cerr << "\n" << flush;
}
*/
while ( true ) {
for ( size_t k = 0; k < groups.size(); ++k )
proto[k] = groups[k][counts[k]];
/*
cerr << "trying : ";
for ( vector<size_t>::const_iterator c = counts.begin();
c != counts.end(); ++c )
cerr << *c << " ";
cerr << "\n" << flush;
for ( size_t k = 0; k < groups.size(); ++k )
cerr << groups[k][counts[k]]->PDGName() << " ";
cerr << "\n" << flush;
*/
int charge = -proto[0]->iCharge() -proto[1]->iCharge();
for ( size_t k = 2; k < proto.size(); ++k )
charge += proto[k]->iCharge();
if ( charge == 0 ) {
sort(proto.begin()+2,proto.end(),SortPID());
allProcs.insert(proto);
}
vector<size_t>::reverse_iterator c = counts.rbegin();
vector<PDVector>::const_reverse_iterator g = groups.rbegin();
while ( c != counts.rend() ) {
if ( ++(*c) == g->size() ) {
*c = 0;
++c; ++g;
} else {
break;
}
}
if ( c == counts.rend() )
break;
}
return allProcs;
}
void MatchboxFactory::Init() {
static ClassDocumentation<MatchboxFactory> documentation
("MatchboxFactory",
"NLO QCD corrections have been calculated "
"using Matchbox \\cite{Platzer:2011bc}",
"%\\cite{Platzer:2011bc}\n"
"\\bibitem{Platzer:2011bc}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Dipole Showers and Automated NLO Matching in Herwig++,''\n"
"arXiv:1109.6256 [hep-ph].\n"
"%%CITATION = ARXIV:1109.6256;%%");
static Reference<MatchboxFactory,Tree2toNGenerator> interfaceDiagramGenerator
("DiagramGenerator",
"Set the diagram generator.",
&MatchboxFactory::theDiagramGenerator, false, false, true, true, false);
static Reference<MatchboxFactory,ProcessData> interfaceProcessData
("ProcessData",
"Set the process data object to be used.",
&MatchboxFactory::theProcessData, false, false, true, true, false);
static Parameter<MatchboxFactory,unsigned int> interfaceOrderInAlphaS
("OrderInAlphaS",
"The order in alpha_s to consider.",
&MatchboxFactory::theOrderInAlphaS, 0, 0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxFactory,unsigned int> interfaceOrderInAlphaEW
("OrderInAlphaEW",
"The order in alpha_EW",
&MatchboxFactory::theOrderInAlphaEW, 2, 0, 0,
false, false, Interface::lowerlim);
static Switch<MatchboxFactory,bool> interfaceBornContributions
("BornContributions",
"Switch on or off the Born contributions.",
&MatchboxFactory::theBornContributions, true, false, false);
static SwitchOption interfaceBornContributionsOn
(interfaceBornContributions,
"On",
"Switch on Born contributions.",
true);
static SwitchOption interfaceBornContributionsOff
(interfaceBornContributions,
"Off",
"Switch off Born contributions.",
false);
static Switch<MatchboxFactory,bool> interfaceVirtualContributions
("VirtualContributions",
"Switch on or off the virtual contributions.",
&MatchboxFactory::theVirtualContributions, true, false, false);
static SwitchOption interfaceVirtualContributionsOn
(interfaceVirtualContributions,
"On",
"Switch on virtual contributions.",
true);
static SwitchOption interfaceVirtualContributionsOff
(interfaceVirtualContributions,
"Off",
"Switch off virtual contributions.",
false);
static Switch<MatchboxFactory,bool> interfaceRealContributions
("RealContributions",
"Switch on or off the real contributions.",
&MatchboxFactory::theRealContributions, true, false, false);
static SwitchOption interfaceRealContributionsOn
(interfaceRealContributions,
"On",
"Switch on real contributions.",
true);
static SwitchOption interfaceRealContributionsOff
(interfaceRealContributions,
"Off",
"Switch off real contributions.",
false);
static Switch<MatchboxFactory,bool> interfaceIndependentVirtuals
("IndependentVirtuals",
"Switch on or off virtual contributions as separate subprocesses.",
&MatchboxFactory::theIndependentVirtuals, true, false, false);
static SwitchOption interfaceIndependentVirtualsOn
(interfaceIndependentVirtuals,
"On",
"Switch on virtual contributions as separate subprocesses.",
true);
static SwitchOption interfaceIndependentVirtualsOff
(interfaceIndependentVirtuals,
"Off",
"Switch off virtual contributions as separate subprocesses.",
false);
static Switch<MatchboxFactory,bool> interfaceIndependentPKs
("IndependentPKOperators",
"Switch on or off PK oeprators as separate subprocesses.",
&MatchboxFactory::theIndependentPKs, true, false, false);
static SwitchOption interfaceIndependentPKsOn
(interfaceIndependentPKs,
"On",
"Switch on PK operators as separate subprocesses.",
true);
static SwitchOption interfaceIndependentPKsOff
(interfaceIndependentPKs,
"Off",
"Switch off PK operators as separate subprocesses.",
false);
static Switch<MatchboxFactory,bool> interfaceSubProcessGroups
("SubProcessGroups",
"Switch on or off production of sub-process groups.",
&MatchboxFactory::theSubProcessGroups, false, false, false);
static SwitchOption interfaceSubProcessGroupsOn
(interfaceSubProcessGroups,
"On",
"On",
true);
static SwitchOption interfaceSubProcessGroupsOff
(interfaceSubProcessGroups,
"Off",
"Off",
false);
static Reference<MatchboxFactory,MatchboxPhasespace> interfacePhasespace
("Phasespace",
"Set the phasespace generator.",
&MatchboxFactory::thePhasespace, false, false, true, true, false);
static Reference<MatchboxFactory,MatchboxScaleChoice> interfaceScaleChoice
("ScaleChoice",
"Set the scale choice object.",
&MatchboxFactory::theScaleChoice, false, false, true, true, false);
static Parameter<MatchboxFactory,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The factorization scale factor.",
&MatchboxFactory::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxFactory,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The renormalization scale factor.",
&MatchboxFactory::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Switch<MatchboxFactory,bool> interfaceFixedCouplings
("FixedCouplings",
"Switch on or off fixed couplings.",
&MatchboxFactory::theFixedCouplings, true, false, false);
static SwitchOption interfaceFixedCouplingsOn
(interfaceFixedCouplings,
"On",
"On",
true);
static SwitchOption interfaceFixedCouplingsOff
(interfaceFixedCouplings,
"Off",
"Off",
false);
static Switch<MatchboxFactory,bool> interfaceFixedQEDCouplings
("FixedQEDCouplings",
"Switch on or off fixed QED couplings.",
&MatchboxFactory::theFixedQEDCouplings, true, false, false);
static SwitchOption interfaceFixedQEDCouplingsOn
(interfaceFixedQEDCouplings,
"On",
"On",
true);
static SwitchOption interfaceFixedQEDCouplingsOff
(interfaceFixedQEDCouplings,
"Off",
"Off",
false);
static Switch<MatchboxFactory,bool> interfaceVetoScales
("VetoScales",
"Switch on or setting veto scales.",
&MatchboxFactory::theVetoScales, false, false, false);
static SwitchOption interfaceVetoScalesOn
(interfaceVetoScales,
"On",
"On",
true);
static SwitchOption interfaceVetoScalesOff
(interfaceVetoScales,
"Off",
"Off",
false);
static RefVector<MatchboxFactory,MatchboxAmplitude> interfaceAmplitudes
("Amplitudes",
"The amplitude objects.",
&MatchboxFactory::theAmplitudes, -1, false, false, true, true, false);
static RefVector<MatchboxFactory,MatchboxMEBase> interfaceBornMEs
("BornMEs",
"The Born matrix elements to be used",
&MatchboxFactory::theBornMEs, -1, false, false, true, true, false);
static RefVector<MatchboxFactory,MatchboxInsertionOperator> interfaceVirtuals
("Virtuals",
"The virtual corrections to include",
&MatchboxFactory::theVirtuals, -1, false, false, true, true, false);
static RefVector<MatchboxFactory,MatchboxMEBase> interfaceRealEmissionMEs
("RealEmissionMEs",
"The RealEmission matrix elements to be used",
&MatchboxFactory::theRealEmissionMEs, -1, false, false, true, true, false);
static RefVector<MatchboxFactory,MatchboxMEBase> interfaceBornVirtuals
("BornVirtualMEs",
"The generated Born/virtual contributions",
&MatchboxFactory::theBornVirtualMEs, -1, false, true, true, true, false);
static RefVector<MatchboxFactory,SubtractedME> interfaceSubtractedMEs
("SubtractedMEs",
"The generated subtracted real emission contributions",
&MatchboxFactory::theSubtractedMEs, -1, false, true, true, true, false);
static RefVector<MatchboxFactory,MatchboxMEBase> interfaceFiniteRealMEs
("FiniteRealMEs",
"The generated finite real contributions",
&MatchboxFactory::theFiniteRealMEs, -1, false, true, true, true, false);
static Switch<MatchboxFactory,bool> interfaceVerbose
("Verbose",
"Print full infomation on each evaluated phase space point.",
&MatchboxFactory::theVerbose, false, false, false);
static SwitchOption interfaceVerboseOn
(interfaceVerbose,
"On",
"On",
true);
static SwitchOption interfaceVerboseOff
(interfaceVerbose,
"Off",
"Off",
false);
static Switch<MatchboxFactory,bool> interfaceVerboseDia
("DiagramWeightVerbose",
"Print full infomation on each evaluated phase space point.",
&MatchboxFactory::theDiagramWeightVerbose, false, false, false);
static SwitchOption interfaceVerboseDiaOn
(interfaceVerboseDia,
"On",
"On",
true);
static SwitchOption interfaceVerboseDiaOff
(interfaceVerboseDia,
"Off",
"Off",
false);
static Parameter<MatchboxFactory,int> interfaceVerboseDiaNbins
("DiagramWeightVerboseNBins",
"No. of Bins for DiagramWeightVerbose Diagrams.",
&MatchboxFactory::theDiagramWeightVerboseNBins, 200, 0, 0,
false, false, Interface::lowerlim);
static Switch<MatchboxFactory,bool> interfaceInitVerbose
("InitVerbose",
"Print setup information.",
&MatchboxFactory::theInitVerbose, false, false, false);
static SwitchOption interfaceInitVerboseOn
(interfaceInitVerbose,
"On",
"On",
true);
static SwitchOption interfaceInitVerboseOff
(interfaceInitVerbose,
"Off",
"Off",
false);
static Parameter<MatchboxFactory,string> interfaceSubtractionData
("SubtractionData",
"Prefix for subtraction check data.",
&MatchboxFactory::theSubtractionData, "",
false, false);
static Switch<MatchboxFactory,int> interfaceSubtractionPlotType
("SubtractionPlotType",
"Switch for controlling what kind of plot is generated for checking the subtraction",
&MatchboxFactory::theSubtractionPlotType, 1, false, false);
static SwitchOption interfaceSubtractionPlotTypeLinearRatio
(interfaceSubtractionPlotType,
"LinRatio",
"Switch on the linear plot of the ratio",
1);
static SwitchOption interfaceSubtractionPlotTypeLogRelDiff
(interfaceSubtractionPlotType,
"LogRelDiff",
"Switch on the logarithmic plot of the relative difference",
2);
static Switch<MatchboxFactory,bool> interfaceSubtractionScatterPlot
("SubtractionScatterPlot",
"Switch for controlling whether subtraction data should be plotted for each phase space point individually",
&MatchboxFactory::theSubtractionScatterPlot, false, false, false);
static SwitchOption interfaceSubtractionScatterPlotOff
(interfaceSubtractionScatterPlot,
"Off", "Switch off the scatter plot", false);
static SwitchOption interfaceSubtractionScatterPlotOn
(interfaceSubtractionScatterPlot,
"On", "Switch on the scatter plot", true);
static Parameter<MatchboxFactory,string> interfacePoleData
("PoleData",
"Prefix for subtraction check data.",
&MatchboxFactory::thePoleData, "",
false, false);
static RefVector<MatchboxFactory,ParticleData> interfaceParticleGroup
("ParticleGroup",
"The particle group just started.",
&MatchboxFactory::particleGroup, -1, false, false, true, false, false);
static Command<MatchboxFactory> interfaceStartParticleGroup
("StartParticleGroup",
"Start a particle group.",
&MatchboxFactory::startParticleGroup, false);
static Command<MatchboxFactory> interfaceEndParticleGroup
("EndParticleGroup",
"End a particle group.",
&MatchboxFactory::endParticleGroup, false);
static Command<MatchboxFactory> interfaceProcess
("Process",
"Set the process(es) to consider.",
&MatchboxFactory::doProcess, false);
static Command<MatchboxFactory> interfaceLoopInducedProcess
("LoopInducedProcess",
"Set the loop induced process(es) to consider.",
&MatchboxFactory::doLoopInducedProcess, false);
static Command<MatchboxFactory> interfaceSingleRealProcess
("SingleRealProcess",
"Set the real emission process(es) to consider.",
&MatchboxFactory::doSingleRealProcess, false);
static Reference<MatchboxFactory,ShowerApproximation> interfaceShowerApproximation
("ShowerApproximation",
"Set the shower approximation to be considered.",
&MatchboxFactory::theShowerApproximation, false, false, true, true, false);
static Switch<MatchboxFactory,bool> interfaceRealEmissionScales
("RealEmissionScales",
"Switch on or off calculation of subtraction scales from real emission kinematics.",
&MatchboxFactory::theRealEmissionScales, false, false, false);
static SwitchOption interfaceRealEmissionScalesOn
(interfaceRealEmissionScales,
"On",
"On",
true);
static SwitchOption interfaceRealEmissionScalesOff
(interfaceRealEmissionScales,
"Off",
"Off",
false);
static Switch<MatchboxFactory,bool> interfaceAllProcesses
("AllProcesses",
"Consider all processes up to a maximum coupling order specified by the coupling order interfaces.",
&MatchboxFactory::theAllProcesses, false, false, false);
static SwitchOption interfaceAllProcessesYes
(interfaceAllProcesses,
"Yes",
"Include all processes.",
true);
static SwitchOption interfaceAllProcessesNo
(interfaceAllProcesses,
"No",
"Only consider processes matching the exact order in the couplings.",
false);
static RefVector<MatchboxFactory,MatchboxAmplitude> interfaceSelectAmplitudes
("SelectAmplitudes",
"The amplitude objects to be favoured in clashing responsibilities.",
&MatchboxFactory::theSelectedAmplitudes, -1, false, false, true, true, false);
static RefVector<MatchboxFactory,MatchboxAmplitude> interfaceDeselectAmplitudes
("DeselectAmplitudes",
"The amplitude objects to be disfavoured in clashing responsibilities.",
&MatchboxFactory::theDeselectedAmplitudes, -1, false, false, true, true, false);
static Switch<MatchboxFactory,int> interfaceDipoleSet
("DipoleSet",
"The set of subtraction terms to be considered.",
&MatchboxFactory::theDipoleSet, 0, false, false);
static SwitchOption interfaceDipoleSetCataniSeymour
(interfaceDipoleSet,
"CataniSeymour",
"Use default Catani-Seymour dipoles.",
0);
static RefVector<MatchboxFactory,ReweightBase> interfaceReweighters
("Reweighters",
"Reweight objects for matrix elements.",
&MatchboxFactory::theReweighters, -1, false, false, true, false, false);
static RefVector<MatchboxFactory,ReweightBase> interfacePreweighters
("Preweighters",
"Preweight objects for matrix elements.",
&MatchboxFactory::thePreweighters, -1, false, false, true, false, false);
static Switch<MatchboxFactory,bool> interfaceMECorrectionsOnly
("MECorrectionsOnly",
"Prepare only ME corrections, but no NLO calculation.",
&MatchboxFactory::theMECorrectionsOnly, false, false, false);
static SwitchOption interfaceMECorrectionsOnlyYes
(interfaceMECorrectionsOnly,
"Yes",
"Produce only ME corrections.",
true);
static SwitchOption interfaceMECorrectionsOnlyNo
(interfaceMECorrectionsOnly,
"No",
"Produce full NLO.",
false);
static Switch<MatchboxFactory,bool> interfaceLoopSimCorrections
("LoopSimCorrections",
"Prepare LoopSim corrections.",
&MatchboxFactory::theLoopSimCorrections, false, false, false);
static SwitchOption interfaceLoopSimCorrectionsYes
(interfaceLoopSimCorrections,
"Yes",
"Produce loopsim corrections.",
true);
static SwitchOption interfaceLoopSimCorrectionsNo
(interfaceLoopSimCorrections,
"No",
"Produce full NLO.",
false);
static Switch<MatchboxFactory,bool> interfaceFirstPerturbativePDF
("FirstPerturbativePDF",
"",
&MatchboxFactory::theFirstPerturbativePDF, true, false, false);
static SwitchOption interfaceFirstPerturbativePDFYes
(interfaceFirstPerturbativePDF,
"Yes",
"",
true);
static SwitchOption interfaceFirstPerturbativePDFNo
(interfaceFirstPerturbativePDF,
"No",
"",
false);
static Switch<MatchboxFactory,bool> interfaceSecondPerturbativePDF
("SecondPerturbativePDF",
"",
&MatchboxFactory::theSecondPerturbativePDF, true, false, false);
static SwitchOption interfaceSecondPerturbativePDFYes
(interfaceSecondPerturbativePDF,
"Yes",
"",
true);
static SwitchOption interfaceSecondPerturbativePDFNo
(interfaceSecondPerturbativePDF,
"No",
"",
false);
static Command<MatchboxFactory> interfaceProductionMode
("ProductionMode",
"Switch this factory to production mode.",
&MatchboxFactory::doProductionMode, false);
static Switch<MatchboxFactory,bool> interfaceSpinCorrelations
("SpinCorrelations",
"Fill information for the spin correlations, if possible.",
&MatchboxFactory::theSpinCorrelations, false, false, false);
static SwitchOption interfaceSpinCorrelationsYes
(interfaceSpinCorrelations,
"Yes",
"",
true);
static SwitchOption interfaceSpinCorrelationsNo
(interfaceSpinCorrelations,
"No",
"",
false);
static Parameter<MatchboxFactory,double> interfaceAlphaParameter
("AlphaParameter",
"Nagy-AlphaParameter.",
&MatchboxFactory::theAlphaParameter, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
}
// *** 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<MatchboxFactory,SubProcessHandler>
describeHerwigMatchboxFactory("Herwig::MatchboxFactory", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Matching/DipoleMatching.cc b/MatrixElement/Matchbox/Matching/DipoleMatching.cc
--- a/MatrixElement/Matchbox/Matching/DipoleMatching.cc
+++ b/MatrixElement/Matchbox/Matching/DipoleMatching.cc
@@ -1,126 +1,126 @@
// -*- C++ -*-
//
// DipoleMatching.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 DipoleMatching class.
//
#include "DipoleMatching.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.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"
using namespace Herwig;
DipoleMatching::DipoleMatching() {}
DipoleMatching::~DipoleMatching() {}
IBPtr DipoleMatching::clone() const {
return new_ptr(*this);
}
IBPtr DipoleMatching::fullclone() const {
return new_ptr(*this);
}
CrossSection DipoleMatching::dSigHatDR() const {
double xme2 = 0.;
pair<int,int> ij(dipole()->bornEmitter(),
dipole()->bornSpectator());
double ccme2 =
dipole()->underlyingBornME()->largeNColourCorrelatedME2(ij,theLargeNBasis);
ccme2 *=
dipole()->underlyingBornME()->me2() /
dipole()->underlyingBornME()->largeNME2(theLargeNBasis);
xme2 = dipole()->me2Avg(ccme2);
xme2 /= dipole()->underlyingBornME()->lastXComb().lastAlphaS();
double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale());
if ( bornPDF == 0.0 )
return ZERO;
xme2 *= bornPDF;
if ( restrictPhasespace() )
xme2 *= hardScaleProfile(dipole()->showerHardScale(),dipole()->lastPt());
CrossSection res =
sqr(hbarc) *
realXComb()->jacobian() *
subtractionScaleWeight() *
xme2 /
(2. * realXComb()->lastSHat());
return res;
}
double DipoleMatching::me2() const {
- throw Exception() << "Not intented to use. Disable the ShowerApproximationGenerator."
+ throw Exception() << "DipoleMatching::me2(): Not intented to use. Disable the ShowerApproximationGenerator."
<< Exception::abortnow;
return 0.;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleMatching::persistentOutput(PersistentOStream & os) const {
os << theShowerHandler;
}
void DipoleMatching::persistentInput(PersistentIStream & is, int) {
is >> theShowerHandler;
}
void DipoleMatching::doinit() {
ShowerApproximation::doinit();
if ( theShowerHandler ) {
if ( theShowerHandler->scaleFactorOption() < 2 ) {
hardScaleFactor(theShowerHandler->hardScaleFactor());
factorizationScaleFactor(theShowerHandler->factorizationScaleFactor());
renormalizationScaleFactor(theShowerHandler->renormalizationScaleFactor());
}
}
}
// *** 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<DipoleMatching,Herwig::ShowerApproximation>
describeHerwigDipoleMatching("Herwig::DipoleMatching", "HwDipoleMatching.so HwShower.so");
void DipoleMatching::Init() {
static ClassDocumentation<DipoleMatching> documentation
("DipoleMatching implements NLO matching with the dipole shower.");
static Reference<DipoleMatching,ShowerHandler> interfaceShowerHandler
("ShowerHandler",
"",
&DipoleMatching::theShowerHandler, false, false, true, true, false);
}
diff --git a/MatrixElement/Matchbox/Matching/QTildeMatching.cc b/MatrixElement/Matchbox/Matching/QTildeMatching.cc
--- a/MatrixElement/Matchbox/Matching/QTildeMatching.cc
+++ b/MatrixElement/Matchbox/Matching/QTildeMatching.cc
@@ -1,445 +1,445 @@
// -*- C++ -*-
//
// QTildeMatching.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 QTildeMatching class.
//
#include "QTildeMatching.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.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"
using namespace Herwig;
QTildeMatching::QTildeMatching() {}
QTildeMatching::~QTildeMatching() {}
IBPtr QTildeMatching::clone() const {
return new_ptr(*this);
}
IBPtr QTildeMatching::fullclone() const {
return new_ptr(*this);
}
void QTildeMatching::checkCutoff() {
if ( showerTildeKinematics() ) {
showerTildeKinematics()->
prepare(realCXComb(),bornCXComb());
showerTildeKinematics()->dipole(dipole());
showerTildeKinematics()->getShowerVariables();
}
}
void QTildeMatching::getShowerVariables() {
// already filled from checkCutoff in this case
if ( showerTildeKinematics() )
return;
// get the shower variables
calculateShowerVariables();
// check for the cutoff
dipole()->isAboveCutoff(isAboveCutoff());
// get the hard scale
dipole()->showerHardScale(hardScale());
// check for phase space
dipole()->isInShowerPhasespace(isInShowerPhasespace());
}
bool QTildeMatching::isInShowerPhasespace() const {
assert((theQTildeSudakov->cutOffOption() == 0 || theQTildeSudakov->cutOffOption() == 2) &&
"implementation only provided for default and pt cutoff");
Energy qtildeHard = ZERO;
Energy qtilde = dipole()->showerScale();
assert(!dipole()->showerParameters().empty());
double z = dipole()->showerParameters()[0];
// FF
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) {
qtildeHard =
theQTildeFinder->
calculateFinalFinalScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()],
bornCXComb()->meMomenta()[dipole()->bornSpectator()],
bornCXComb()->mePartonData()[dipole()->bornEmitter()]->iColour() == PDT::Colour3).first;
}
// FI
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) {
qtildeHard =
theQTildeFinder->
calculateInitialFinalScales(bornCXComb()->meMomenta()[dipole()->bornSpectator()],
bornCXComb()->meMomenta()[dipole()->bornEmitter()],false).second;
}
// IF
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) {
qtildeHard =
theQTildeFinder->
calculateInitialFinalScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()],
bornCXComb()->meMomenta()[dipole()->bornSpectator()],false).first;
if ( z < (dipole()->bornEmitter() == 0 ? bornCXComb()->lastX1() : bornCXComb()->lastX2()) )
return false;
}
// II
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2 ) {
qtildeHard =
theQTildeFinder->
calculateInitialInitialScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()],
bornCXComb()->meMomenta()[dipole()->bornSpectator()]).first;
if ( z < (dipole()->bornEmitter() == 0 ? bornCXComb()->lastX1() : bornCXComb()->lastX2()) )
return false;
}
Energy Qg = theQTildeSudakov->kinScale();
Energy2 pt2 = ZERO;
if ( dipole()->bornEmitter() > 1 ) {
Energy mu = max(Qg,realCXComb()->meMomenta()[dipole()->realEmitter()].mass());
if ( bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == ParticleID::g )
pt2 = sqr(z*(1.-z)*qtilde) - sqr(mu);
else
pt2 = sqr(z*(1.-z)*qtilde) - sqr((1.-z)*mu) - z*sqr(Qg);
}
if ( dipole()->bornEmitter() < 2 ) {
pt2 = sqr((1.-z)*qtilde) - z*sqr(Qg);
}
if ( pt2 < theQTildeSudakov->pT2min() )
return false;
return qtilde <= qtildeHard && sqrt(pt2) < dipole()->showerHardScale();
}
bool QTildeMatching::isAboveCutoff() const {
assert((theQTildeSudakov->cutOffOption() == 0 || theQTildeSudakov->cutOffOption() == 2) &&
"implementation only provided for default and pt cutoff");
Energy qtilde = dipole()->showerScale();
assert(!dipole()->showerParameters().empty());
double z = dipole()->showerParameters()[0];
Energy Qg = theQTildeSudakov->kinScale();
if ( dipole()->bornEmitter() > 1 ) {
Energy mu = max(Qg,realCXComb()->meMomenta()[dipole()->realEmitter()].mass());
if ( bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == ParticleID::g )
return sqr(z*(1.-z)*qtilde) - sqr(mu) >= theQTildeSudakov->pT2min();
else
return sqr(z*(1.-z)*qtilde) - sqr((1.-z)*mu) - z*sqr(Qg) >= theQTildeSudakov->pT2min();
}
if ( dipole()->bornEmitter() < 2 ) {
return
sqr((1.-z)*qtilde) - z*sqr(Qg) >= theQTildeSudakov->pT2min();
}
return false;
}
CrossSection QTildeMatching::dSigHatDR() const {
assert(!dipole()->showerParameters().empty());
pair<Energy2,double> vars =
make_pair(sqr(dipole()->showerScale()),
dipole()->showerParameters()[0]);
pair<int,int> ij(dipole()->bornEmitter(),
dipole()->bornSpectator());
double ccme2 =
dipole()->underlyingBornME()->largeNColourCorrelatedME2(ij,theLargeNBasis);
ccme2 *=
dipole()->underlyingBornME()->me2() /
dipole()->underlyingBornME()->largeNME2(theLargeNBasis);
Energy2 prop = ZERO;
if ( dipole()->bornEmitter() > 1 ) {
prop =
(realCXComb()->meMomenta()[dipole()->realEmitter()] +
realCXComb()->meMomenta()[dipole()->realEmission()]).m2()
- bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2();
} else {
prop =
2.*vars.second*(realCXComb()->meMomenta()[dipole()->realEmitter()]*
realCXComb()->meMomenta()[dipole()->realEmission()]);
}
// note alphas included downstream from subtractionScaleWeight()
double xme2 = -8.*Constants::pi*ccme2*splitFn(vars)*realXComb()->lastSHat()/prop;
xme2 *=
pow(realCXComb()->lastSHat() / bornCXComb()->lastSHat(),
bornCXComb()->mePartonData().size()-4.);
double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale());
if ( bornPDF == 0.0 )
return ZERO;
xme2 *= bornPDF;
Energy qtilde = sqrt(vars.first);
double z = vars.second;
Energy2 pt2 = ZERO;
Energy Qg = theQTildeSudakov->kinScale();
if ( dipole()->bornEmitter() > 1 ) {
Energy mu = max(Qg,realCXComb()->meMomenta()[dipole()->realEmitter()].mass());
if ( bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == ParticleID::g )
pt2 = sqr(z*(1.-z)*qtilde) - sqr(mu);
else
pt2 = sqr(z*(1.-z)*qtilde) - sqr((1.-z)*mu) - z*sqr(Qg);
}
if ( dipole()->bornEmitter() < 2 ) {
pt2 = sqr((1.-z)*qtilde) - z*sqr(Qg);
}
assert(pt2 >= ZERO);
xme2 *= hardScaleProfile(dipole()->showerHardScale(),sqrt(pt2));
CrossSection res =
sqr(hbarc) *
realXComb()->jacobian() *
subtractionScaleWeight() *
xme2 /
(2. * realXComb()->lastSHat());
return res;
}
double QTildeMatching::me2() const {
- throw Exception() << "Not intented to use. Disable the ShowerApproximationGenerator."
+ throw Exception() << "QTildeMatching::me2(): Not intented to use. Disable the ShowerApproximationGenerator."
<< Exception::abortnow;
return 0.;
}
void QTildeMatching::calculateShowerVariables() const {
Lorentz5Momentum n;
Energy2 Q2 = ZERO;
const Lorentz5Momentum& pb = bornCXComb()->meMomenta()[dipole()->bornEmitter()];
const Lorentz5Momentum& pc = bornCXComb()->meMomenta()[dipole()->bornSpectator()];
if ( dipole()->bornEmitter() > 1 ) {
Q2 = (pb+pc).m2();
} else {
Q2 = -(pb-pc).m2();
}
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) {
double b = sqr(bornCXComb()->meMomenta()[dipole()->bornEmitter()].m())/Q2;
double c = sqr(bornCXComb()->meMomenta()[dipole()->bornSpectator()].m())/Q2;
double lambda = sqrt(1.+sqr(b)+sqr(c)-2.*b-2.*c-2.*b*c);
n = (1.-0.5*(1.-b+c-lambda))*pc - 0.5*(1.-b+c-lambda)*pb;
}
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) {
n = bornCXComb()->meMomenta()[dipole()->bornSpectator()];
}
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) {
double c = sqr(bornCXComb()->meMomenta()[dipole()->bornSpectator()].m())/Q2;
n = (1.+c)*pc - c*pb;
}
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2 ) {
n = bornCXComb()->meMomenta()[dipole()->bornSpectator()];
}
// the light-cone condition is numerically not very stable, so we
// explicitly push it on the light-cone here
n.setMass(ZERO);
n.rescaleEnergy();
double z = 0.0;
if ( dipole()->bornEmitter() > 1 ) {
z = 1. -
(n*realCXComb()->meMomenta()[dipole()->realEmission()])/
(n*bornCXComb()->meMomenta()[dipole()->bornEmitter()]);
} else {
z = 1. -
(n*realCXComb()->meMomenta()[dipole()->realEmission()])/
(n*realCXComb()->meMomenta()[dipole()->realEmitter()]);
}
Energy2 qtilde2 = ZERO;
Energy2 q2 = ZERO;
if ( dipole()->bornEmitter() > 1 ) {
q2 =
(realCXComb()->meMomenta()[dipole()->realEmitter()] + realCXComb()->meMomenta()[dipole()->realEmission()]).m2();
qtilde2 = (q2 - bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2())/(z*(1.-z));
} else {
q2 =
-(realCXComb()->meMomenta()[dipole()->realEmitter()] - realCXComb()->meMomenta()[dipole()->realEmission()]).m2();
qtilde2 = (q2 + bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2())/(1.-z);
}
assert(qtilde2 >= ZERO && z >= 0.0 && z <= 1.0);
dipole()->showerScale(sqrt(qtilde2));
dipole()->showerParameters().resize(1);
dipole()->showerParameters()[0] = z;
}
double QTildeMatching::splitFn(const pair<Energy2,double>& vars) const {
const Energy2& qtilde2 = vars.first;
const double& z = vars.second;
double Nc = SM().Nc();
// final state branching
if ( dipole()->bornEmitter() > 1 ) {
// final state quark quark branching
if ( abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 7 ) {
Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass();
return
((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(z)-2.*sqr(m)/(z*qtilde2))/(1.-z);
}
// final state gluon branching
if ( bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == ParticleID::g ) {
if ( realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) {
// ATTENTION the factor 2 here is intentional as it cancels to the 1/2
// stemming from the large-N colour correlator
return 2.*Nc*(z/(1.-z)+(1.-z)/z+z*(1.-z));
}
if ( abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) {
Energy m = realCXComb()->mePartonData()[dipole()->realEmission()]->hardProcessMass();
return (1./2.)*(1.-2.*z*(1.-z)+2.*sqr(m)/(z*(1.-z)*qtilde2));
}
}
// final state squark branching
if ((abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) > 1000000 &&
abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 1000007) ||
(abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) > 2000000 &&
abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 2000007)){
Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass();
return ((sqr(Nc)-1.)/Nc)*(z-sqr(m)/(z*qtilde2))/(1.-z);
}
// final state gluino branching
if (bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == 1000021){
Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass();
return Nc*(1.+sqr(z)-2.*sqr(m)/(z*qtilde2))/(1.-z);
}
}
// initial state branching
if ( dipole()->bornEmitter() < 2 ) {
// g/g
if ( realCXComb()->mePartonData()[dipole()->realEmitter()]->id() == ParticleID::g &&
realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) {
// see above for factor of 2
return 2.*Nc*(z/(1.-z)+(1.-z)/z+z*(1.-z));
}
// q/q
if ( abs(realCXComb()->mePartonData()[dipole()->realEmitter()]->id()) < 7 &&
realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) {
return
((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(z))/(1.-z);
}
// g/q
if ( realCXComb()->mePartonData()[dipole()->realEmitter()]->id() == ParticleID::g &&
abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) {
return (1./2.)*(1.-2.*z*(1.-z));
}
// q/g
if ( abs(realCXComb()->mePartonData()[dipole()->realEmitter()]->id()) < 7 &&
abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) {
return
((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(1.-z))/z;
}
}
return 0.0;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void QTildeMatching::doinit() {
assert(theShowerHandler && theQTildeFinder && theQTildeSudakov);
theShowerHandler->init();
theQTildeFinder->init();
theQTildeSudakov->init();
if ( theShowerHandler->scaleFactorOption() < 2 ) {
hardScaleFactor(theShowerHandler->hardScaleFactor());
factorizationScaleFactor(theShowerHandler->factorizationScaleFactor());
renormalizationScaleFactor(theShowerHandler->renormalizationScaleFactor());
}
ShowerApproximation::doinit();
}
void QTildeMatching::doinitrun() {
assert(theShowerHandler && theQTildeFinder && theQTildeSudakov);
theShowerHandler->initrun();
theQTildeFinder->initrun();
theQTildeSudakov->initrun();
ShowerApproximation::doinitrun();
}
void QTildeMatching::persistentOutput(PersistentOStream & os) const {
os << theQTildeFinder << theQTildeSudakov << theShowerHandler;
}
void QTildeMatching::persistentInput(PersistentIStream & is, int) {
is >> theQTildeFinder >> theQTildeSudakov >> theShowerHandler;
}
// *** 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<QTildeMatching,Herwig::ShowerApproximation>
describeHerwigQTildeMatching("Herwig::QTildeMatching", "HwShower.so HwQTildeMatching.so");
void QTildeMatching::Init() {
static ClassDocumentation<QTildeMatching> documentation
("QTildeMatching implements NLO matching with the default shower.");
static Reference<QTildeMatching,QTildeFinder> interfaceQTildeFinder
("QTildeFinder",
"Set the partner finder to calculate hard scales.",
&QTildeMatching::theQTildeFinder, false, false, true, false, false);
static Reference<QTildeMatching,QTildeSudakov> interfaceQTildeSudakov
("QTildeSudakov",
"Set the partner finder to calculate hard scales.",
&QTildeMatching::theQTildeSudakov, false, false, true, false, false);
static Reference<QTildeMatching,ShowerHandler> interfaceShowerHandler
("ShowerHandler",
"",
&QTildeMatching::theShowerHandler, false, false, true, true, false);
}
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,713 +1,713 @@
// -*- 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(),
theBelowCutoff(false),
theFFPtCut(1.0*GeV), theFFScreeningScale(ZERO),
theFIPtCut(1.0*GeV), theFIScreeningScale(ZERO),
theIIPtCut(1.0*GeV), theIIScreeningScale(ZERO),
theRestrictPhasespace(true), theHardScaleFactor(1.0),
theRenormalizationScaleFactor(1.0), theFactorizationScaleFactor(1.0),
theExtrapolationX(1.0),
theRealEmissionScaleInSubtraction(showerScale),
theBornScaleInSubtraction(showerScale),
theEmissionScaleInSubtraction(showerScale),
theRealEmissionScaleInSplitting(showerScale),
theBornScaleInSplitting(showerScale),
theEmissionScaleInSplitting(showerScale),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(1.*GeV),
theProfileScales(true),
theProfileRho(0.3), 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() << "expecting a colour basis object"
+ throw Exception() << "ShowerApproximation::setLargeNBasis(): Expecting a colour basis object."
<< Exception::abortnow;
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() >= ffPtCut();
} else if ( ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() < 2 ) ||
( dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() > 1 ) ) {
return dipole()->lastPt() >= fiPtCut();
} else {
assert(dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() < 2);
return dipole()->lastPt() >= iiPtCut();
}
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());
}
}
double ShowerApproximation::hardScaleProfile(Energy hard, Energy soft) const {
double x = soft/hard;
if ( theProfileScales ) {
if ( x > 1. ) {
return 0.;
} else if ( x <= 1. && x > 1. - theProfileRho ) {
return sqr(1.-x)/(2.*sqr(theProfileRho));
} else if ( x <= 1. - theProfileRho &&
x > 1. - 2.*theProfileRho ) {
return 1. - sqr(1.-2.*theProfileRho-x)/(2.*sqr(theProfileRho));
} else {
return 1.;
}
}
if ( x <= 1. )
return 1.;
return 0.;
}
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)
<< theRestrictPhasespace << theHardScaleFactor
<< theRenormalizationScaleFactor << theFactorizationScaleFactor
<< theExtrapolationX
<< theRealEmissionScaleInSubtraction << theBornScaleInSubtraction
<< theEmissionScaleInSubtraction << theRealEmissionScaleInSplitting
<< theBornScaleInSplitting << theEmissionScaleInSplitting
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV)
<< theProfileScales << theProfileRho << maxPtIsMuF;
}
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)
>> theRestrictPhasespace >> theHardScaleFactor
>> theRenormalizationScaleFactor >> theFactorizationScaleFactor
>> theExtrapolationX
>> theRealEmissionScaleInSubtraction >> theBornScaleInSubtraction
>> theEmissionScaleInSubtraction >> theRealEmissionScaleInSplitting
>> theBornScaleInSplitting >> theEmissionScaleInSplitting
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV)
>> theProfileScales >> theProfileRho >> maxPtIsMuF;
}
// *** 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> 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 Switch<ShowerApproximation,bool> interfaceProfileScales
("ProfileScales",
"Switch on or off use of profile scales.",
&ShowerApproximation::theProfileScales, true, false, false);
static SwitchOption interfaceProfileScalesYes
(interfaceProfileScales,
"Yes",
"Use profile scales.",
true);
static SwitchOption interfaceProfileScalesNo
(interfaceProfileScales,
"No",
"Use a hard cutoff.",
false);
static Parameter<ShowerApproximation,double> interfaceProfileRho
("ProfileRho",
"The rho parameter of the profile scales.",
&ShowerApproximation::theProfileRho, 0.3, 0.0, 1.0,
false, false, Interface::limited);
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,460 +1,460 @@
// -*- 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() {
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);
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());
theLastPresamplingMomenta[0] = theLastBornME->lastMEMomenta()[0];
theLastPresamplingMomenta[1] = theLastBornME->lastMEMomenta()[1];
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() {
tSubProPtr oldSub = lastIncomingXComb->subProcess();
theLastPartons.first->set5Momentum(oldSub->incoming().first->momentum());
theLastPartons.second->set5Momentum(oldSub->incoming().second->momentum());
theLastBornXComb->clean();
theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons,
theLastMomenta,theLastRandomNumbers);
theLastBornME->setXComb(theLastBornXComb);
theLastBornME->generateKinematics(&theLastRandomNumbers[2]);
theLastBornME->dSigHatDR();
}
void ShowerApproximationGenerator::
handle(EventHandler & eh, const tPVector &,
const Hint &) {
theFactory->setHardTreeEmitter(-1);
theFactory->setHardTreeSubprocess(SubProPtr());
lastIncomingXComb = dynamic_ptr_cast<tStdXCombPtr>(eh.lastXCombPtr());
if ( !lastIncomingXComb )
- throw Exception() << "expecting a standard event handler"
+ throw Exception() << "ShowerApproximationGenerator::handle(): Expecting a standard event handler."
<< Exception::abortnow;
if ( lastIncomingXComb->lastProjector() )
lastIncomingXComb = lastIncomingXComb->lastProjector();
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();
theLastBornME->phasespace(thePhasespace);
theLastBornXComb = (**kernels.begin()).bornXComb();
if ( !prepare() )
return;
Energy winnerPt = ZERO;
Ptr<ShowerApproximationKernel>::ptr winnerKernel;
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();
}
}
if ( !winnerKernel || winnerPt == ZERO )
return;
SubProPtr oldSub = lastIncomingXComb->subProcess();
SubProPtr newSub;
try {
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());
}
}
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/Scales/MatchboxHtScale.cc b/MatrixElement/Matchbox/Scales/MatchboxHtScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxHtScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxHtScale.cc
@@ -1,144 +1,152 @@
// -*- C++ -*-
//
// MatchboxHtScale.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 MatchboxHtScale class.
//
#include "MatchboxHtScale.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.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"
using namespace Herwig;
MatchboxHtScale::MatchboxHtScale()
: theIncludeMT(false), theHTFactor(1.0),
theMTFactor(1.0) {}
MatchboxHtScale::~MatchboxHtScale() {}
IBPtr MatchboxHtScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxHtScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxHtScale::renormalizationScale() const {
tcPDVector pd (mePartonData().begin() + 2, mePartonData().end());
vector<LorentzMomentum> p (meMomenta().begin() + 2, meMomenta().end());
tcPDPtr t1 = mePartonData()[0];
tcPDPtr t2 = mePartonData()[1];
tcCutsPtr cuts = lastCutsPtr();
theJetFinder->cluster(pd, p, cuts, t1, t2);
initWeightFactors(pd,p,theJetFinder);
// momentum of the non-jet system
LorentzMomentum nonJetMomentum(ZERO,ZERO,ZERO,ZERO);
// (weighted) pt of the jet systems
Energy ptJetSum = ZERO;
+ bool gotone = false;
+
tcPDVector::const_iterator pdata = pd.begin();
vector<LorentzMomentum>::const_iterator mom = p.begin();
for ( ; mom != p.end(); ++pdata, ++mom ) {
if ( theJetFinder->unresolvedMatcher()->check(**pdata) ) {
+ gotone = true;
ptJetSum += jetPtWeight(*mom)*mom->perp();
} else if ( theIncludeMT ) {
nonJetMomentum += *mom;
}
}
+ if ( !gotone )
+ throw Exception() << "MatchboxHtScale::renormalizationScale(): "
+ << "No jets could be found. Check your setup."
+ << Exception::abortnow;
+
Energy mtNonJetSum =
sqrt(nonJetMomentum.perp2() + nonJetMomentum.m2());
mtNonJetSum *= theMTFactor;
ptJetSum *= theHTFactor;
return sqr(ptJetSum + mtNonJetSum);
}
Energy2 MatchboxHtScale::factorizationScale() const {
return renormalizationScale();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxHtScale::persistentOutput(PersistentOStream & os) const {
os << theJetFinder << theIncludeMT << theHTFactor << theMTFactor;
}
void MatchboxHtScale::persistentInput(PersistentIStream & is, int) {
is >> theJetFinder >> theIncludeMT >> theHTFactor >> theMTFactor;
}
// *** 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<MatchboxHtScale,MatchboxScaleChoice>
describeHerwigMatchboxHtScale("Herwig::MatchboxHtScale", "HwMatchboxScales.so");
void MatchboxHtScale::Init() {
static ClassDocumentation<MatchboxHtScale> documentation
("MatchboxHtScale implements scale choices related to transverse momenta.");
static Reference<MatchboxHtScale,JetFinder> interfaceJetFinder
("JetFinder",
"A reference to the jet finder.",
&MatchboxHtScale::theJetFinder, false, false, true, false, false);
static Switch<MatchboxHtScale,bool> interfaceIncludeMT
("IncludeMT",
"Include the transverse masses of the non-jet objects.",
&MatchboxHtScale::theIncludeMT, false, false, false);
static SwitchOption interfaceIncludeMTYes
(interfaceIncludeMT,
"Yes",
"",
true);
static SwitchOption interfaceIncludeMTNo
(interfaceIncludeMT,
"No",
"",
false);
static Parameter<MatchboxHtScale,double> interfaceHTFactor
("HTFactor",
"A factor to scale the HT contribution.",
&MatchboxHtScale::theHTFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxHtScale,double> interfaceMTFactor
("MTFactor",
"A factor to scale the MT contribution.",
&MatchboxHtScale::theMTFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxLeptonMassScale.cc b/MatrixElement/Matchbox/Scales/MatchboxLeptonMassScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxLeptonMassScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxLeptonMassScale.cc
@@ -1,100 +1,105 @@
// -*- C++ -*-
//
// MatchboxLeptonMassScale.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 MatchboxLeptonMassScale class.
//
#include "MatchboxLeptonMassScale.h"
#include "ThePEG/Interface/ClassDocumentation.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"
using namespace Herwig;
MatchboxLeptonMassScale::MatchboxLeptonMassScale() {}
MatchboxLeptonMassScale::~MatchboxLeptonMassScale() {}
IBPtr MatchboxLeptonMassScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxLeptonMassScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxLeptonMassScale::renormalizationScale() const {
int firstLepton = -1;
int secondLepton = -1;
for ( size_t k = 0; k < mePartonData().size(); ++k ) {
if ( abs(mePartonData()[k]->id()) > 10 &&
abs(mePartonData()[k]->id()) < 17 ) {
if ( firstLepton < 0 ) {
firstLepton = k;
} else if ( secondLepton < 0 ) {
secondLepton = k;
} else break;
}
}
+ if ( firstLepton < 0 || secondLepton < 0 )
+ throw Exception() << "MatchboxLeptonMassScale::renormalizationScale(): "
+ << "No lepton pair could be found. Check your setup."
+ << Exception::abortnow;
+
if ( (firstLepton < 2 && secondLepton > 1) ||
(firstLepton > 1 && secondLepton < 2) )
return abs((meMomenta()[firstLepton] -
meMomenta()[secondLepton]).m2());
return
(meMomenta()[firstLepton] +
meMomenta()[secondLepton]).m2();
}
Energy2 MatchboxLeptonMassScale::factorizationScale() const {
return renormalizationScale();
}
Energy2 MatchboxLeptonMassScale::renormalizationScaleQED() const {
return renormalizationScale();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxLeptonMassScale::persistentOutput(PersistentOStream &) const {}
void MatchboxLeptonMassScale::persistentInput(PersistentIStream &, int) {}
// *** 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<MatchboxLeptonMassScale,MatchboxScaleChoice>
describeHerwigMatchboxLeptonMassScale("Herwig::MatchboxLeptonMassScale", "HwMatchboxScales.so");
void MatchboxLeptonMassScale::Init() {
static ClassDocumentation<MatchboxLeptonMassScale> documentation
("MatchboxLeptonMassScale implements scale choices related "
"to lepton pair invariant masses.");
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxLeptonPtScale.cc b/MatrixElement/Matchbox/Scales/MatchboxLeptonPtScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxLeptonPtScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxLeptonPtScale.cc
@@ -1,113 +1,123 @@
// -*- C++ -*-
//
// MatchboxLeptonPtScale.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 MatchboxLeptonPtScale class.
//
#include "MatchboxLeptonPtScale.h"
#include "ThePEG/Interface/ClassDocumentation.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"
using namespace Herwig;
MatchboxLeptonPtScale::MatchboxLeptonPtScale() {}
MatchboxLeptonPtScale::~MatchboxLeptonPtScale() {}
IBPtr MatchboxLeptonPtScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxLeptonPtScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxLeptonPtScale::renormalizationScale() const {
int firstLepton = -1;
int secondLepton = -1;
for ( size_t k = 2; k < mePartonData().size(); ++k ) {
if ( abs(mePartonData()[k]->id()) > 10 &&
abs(mePartonData()[k]->id()) < 17 ) {
if ( firstLepton < 0 ) {
firstLepton = k;
} else if ( secondLepton < 0 ) {
secondLepton = k;
} else break;
}
}
+ if ( firstLepton < 0 || secondLepton < 0 )
+ throw Exception() << "MatchboxLeptonPtScale::renormalizationScale(): "
+ << "No lepton pair could be found. Check your setup."
+ << Exception::abortnow;
+
return
(meMomenta()[firstLepton] +
meMomenta()[secondLepton]).perp2();
}
Energy2 MatchboxLeptonPtScale::factorizationScale() const {
return renormalizationScale();
}
Energy2 MatchboxLeptonPtScale::renormalizationScaleQED() const {
int firstLepton = -1;
int secondLepton = -1;
for ( size_t k = 2; k < mePartonData().size(); ++k ) {
if ( abs(mePartonData()[k]->id()) > 10 &&
abs(mePartonData()[k]->id()) < 17 ) {
if ( firstLepton < 0 ) {
firstLepton = k;
} else if ( secondLepton < 0 ) {
secondLepton = k;
} else break;
}
}
+ if ( firstLepton < 0 || secondLepton < 0 )
+ throw Exception() << "MatchboxLeptonPtScale::renormalizationScaleQED(): "
+ << "No lepton pair could be found. Check your setup."
+ << Exception::abortnow;
+
return
(meMomenta()[firstLepton] +
meMomenta()[secondLepton]).m2();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxLeptonPtScale::persistentOutput(PersistentOStream &) const {}
void MatchboxLeptonPtScale::persistentInput(PersistentIStream &, int) {}
// *** 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<MatchboxLeptonPtScale,MatchboxScaleChoice>
describeHerwigMatchboxLeptonPtScale("Herwig::MatchboxLeptonPtScale", "HwMatchboxScales.so");
void MatchboxLeptonPtScale::Init() {
static ClassDocumentation<MatchboxLeptonPtScale> documentation
("MatchboxLeptonPtScale implements scale choices related "
"to lepton pair transverse momenta.");
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxParticlePtScale.cc b/MatrixElement/Matchbox/Scales/MatchboxParticlePtScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxParticlePtScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxParticlePtScale.cc
@@ -1,102 +1,102 @@
// -*- C++ -*-
//
// MatchboxParticlePtScale.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 MatchboxParticlePtScale class.
//
#include "MatchboxParticlePtScale.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.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"
using namespace Herwig;
MatchboxParticlePtScale::MatchboxParticlePtScale() {}
MatchboxParticlePtScale::~MatchboxParticlePtScale() {}
IBPtr MatchboxParticlePtScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxParticlePtScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxParticlePtScale::renormalizationScale() const {
tcPDVector pd (mePartonData().begin() + 2, mePartonData().end());
vector<LorentzMomentum> p (meMomenta().begin() + 2, meMomenta().end());
Energy2 pt2 = ZERO;
int found = 0;
tcPDVector::const_iterator itpd = pd.begin();
for (vector<LorentzMomentum>::const_iterator itp = p.begin() ;
itp != p.end(); ++itp, ++itpd )
if ( theMatcher->check(**itpd) ) {
found++;
pt2 = (*itp).perp2();
}
if ( found == 1 )
return pt2;
else
- throw Exception() << "MatchboxParticlePtScale has found "
+ throw Exception() << "MatchboxParticlePtScale: Found "
<< found << " particles of the requested type "
<< "where exactly 1 was expected. Aborting this event."
<< Exception::eventerror;
return ZERO;
}
Energy2 MatchboxParticlePtScale::factorizationScale() const {
return renormalizationScale();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxParticlePtScale::persistentOutput(PersistentOStream & os) const {
os << theMatcher;
}
void MatchboxParticlePtScale::persistentInput(PersistentIStream & is, int) {
is >> theMatcher;
}
// *** 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<MatchboxParticlePtScale,MatchboxScaleChoice>
describeHerwigMatchboxParticlePtScale("Herwig::MatchboxParticlePtScale", "HwMatchboxScales.so");
void MatchboxParticlePtScale::Init() {
static ClassDocumentation<MatchboxParticlePtScale> documentation
("MatchboxParticlePtScale implements scale choices related to transverse momenta.");
static Reference<MatchboxParticlePtScale,MatcherBase> interfaceMatcher
("Matcher",
"A matcher to determine the particle that this scale is working on",
&MatchboxParticlePtScale::theMatcher, false, false, true, false, false);
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxPtScale.cc b/MatrixElement/Matchbox/Scales/MatchboxPtScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxPtScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxPtScale.cc
@@ -1,96 +1,104 @@
// -*- C++ -*-
//
// MatchboxPtScale.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 MatchboxPtScale class.
//
#include "MatchboxPtScale.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.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"
using namespace Herwig;
MatchboxPtScale::MatchboxPtScale() {}
MatchboxPtScale::~MatchboxPtScale() {}
IBPtr MatchboxPtScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxPtScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxPtScale::renormalizationScale() const {
tcPDVector pd (mePartonData().begin() + 2, mePartonData().end());
vector<LorentzMomentum> p (meMomenta().begin() + 2, meMomenta().end());
tcPDPtr t1 = mePartonData()[0];
tcPDPtr t2 = mePartonData()[1];
tcCutsPtr cuts = lastCutsPtr();
theJetFinder->cluster(pd, p, cuts, t1, t2);
+ bool gotone = false;
+
Energy2 maxpt2 = ZERO;
tcPDVector::const_iterator itpd = pd.begin();
for (vector<LorentzMomentum>::const_iterator itp = p.begin() ;
itp != p.end(); ++itp, ++itpd )
- if ( (**itpd).coloured() )
+ if ( theJetFinder->unresolvedMatcher()->matches(*itpd) ) {
+ gotone = true;
maxpt2 = max(maxpt2,(*itp).perp2());
+ }
+
+ if ( !gotone )
+ throw Exception() << "MatchboxPtScale::renormalizationScale(): No jet could be found. Check your setup."
+ << Exception::abortnow;
return maxpt2;
}
Energy2 MatchboxPtScale::factorizationScale() const {
return renormalizationScale();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxPtScale::persistentOutput(PersistentOStream & os) const {
os << theJetFinder;
}
void MatchboxPtScale::persistentInput(PersistentIStream & is, int) {
is >> theJetFinder;
}
// *** 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<MatchboxPtScale,MatchboxScaleChoice>
describeHerwigMatchboxPtScale("Herwig::MatchboxPtScale", "HwMatchboxScales.so");
void MatchboxPtScale::Init() {
static ClassDocumentation<MatchboxPtScale> documentation
("MatchboxPtScale implements scale choices related to transverse momenta.");
static Reference<MatchboxPtScale,JetFinder> interfaceJetFinder
("JetFinder",
"A reference to the jet finder.",
&MatchboxPtScale::theJetFinder, false, false, true, false, false);
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxTopMTScale.cc b/MatrixElement/Matchbox/Scales/MatchboxTopMTScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxTopMTScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxTopMTScale.cc
@@ -1,101 +1,101 @@
// -*- C++ -*-
//
// MatchboxTopMTScale.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 MatchboxTopMTScale class.
//
#include "MatchboxTopMTScale.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxTopMTScale::MatchboxTopMTScale() {}
MatchboxTopMTScale::~MatchboxTopMTScale() {}
IBPtr MatchboxTopMTScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxTopMTScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxTopMTScale::renormalizationScale() const {
size_t k = 2;
int top = -1;
int antitop = -1;
while ( (top == -1 || antitop == -1) && k < mePartonData().size() ){
if ( mePartonData()[k]->id() == 6 ) {
if ( top < 0 )
top = k;
else
assert(false);
} else if ( mePartonData()[k]->id() == -6 ) {
if ( antitop < 0 )
antitop = k;
else
assert(false);
}
k++;
}
if ( top < 2 || antitop < 2 ){
- cerr << "MatchboxTopMTScale: Could not find a top-antitop-pair in the final state!\n";
- assert(false);
+ throw Exception() << "MatchboxTopMTScale: Could not find a top-antitop-pair in the final state!\n"
+ << Exception::abortnow;
}
// cerr << " sqrt(TopMTScale) = "
// << sqrt(meMomenta()[top].mt2()+meMomenta()[antitop].mt2())/GeV
// << "\n" << flush;
return(meMomenta()[top].mt2()+meMomenta()[antitop].mt2());
}
Energy2 MatchboxTopMTScale::factorizationScale() const {
return(renormalizationScale());
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxTopMTScale::persistentOutput(PersistentOStream &) const {}
void MatchboxTopMTScale::persistentInput(PersistentIStream &, int) {}
// *** 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<MatchboxTopMTScale,MatchboxScaleChoice>
describeHerwigMatchboxTopMTScale("Herwig::MatchboxTopMTScale", "HwMatchboxScales.so");
void MatchboxTopMTScale::Init() {
static ClassDocumentation<MatchboxTopMTScale> documentation
("MatchboxTopMTScale implements the quadratic sum of the transverse masses of the top and antitop quark as a scale choice.");
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxTopMassScale.cc b/MatrixElement/Matchbox/Scales/MatchboxTopMassScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxTopMassScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxTopMassScale.cc
@@ -1,101 +1,101 @@
// -*- C++ -*-
//
// MatchboxTopMassScale.cc is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2014 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 MatchboxTopMassScale class.
//
#include "MatchboxTopMassScale.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxTopMassScale::MatchboxTopMassScale() {}
MatchboxTopMassScale::~MatchboxTopMassScale() {}
IBPtr MatchboxTopMassScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxTopMassScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxTopMassScale::renormalizationScale() const {
size_t k = 2;
int top = -1;
int antitop = -1;
while ( (top == -1 || antitop == -1) && k < mePartonData().size() ){
if ( mePartonData()[k]->id() == 6 ) {
if ( top < 0 )
top = k;
else
assert(false);
} else if ( mePartonData()[k]->id() == -6 ) {
if ( antitop < 0 )
antitop = k;
else
assert(false);
}
k++;
}
if ( top < 2 || antitop < 2 ){
- cerr << "MatchboxTopMassScale: Could not find a top-antitop-pair in the final state!\n";
- assert(false);
+ throw Exception() << "MatchboxTopMassScale: Could not find a top-antitop-pair in the final state!\n"
+ << Exception::abortnow;
}
// cerr << " sqrt(TopMassScale) = "
// << sqrt((meMomenta()[top]+meMomenta()[antitop]).m2())/GeV
// << "\n" << flush;
return((meMomenta()[top]+meMomenta()[antitop]).m2());
}
Energy2 MatchboxTopMassScale::factorizationScale() const {
return(renormalizationScale());
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxTopMassScale::persistentOutput(PersistentOStream &) const {}
void MatchboxTopMassScale::persistentInput(PersistentIStream &, int) {}
// *** 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<MatchboxTopMassScale,MatchboxScaleChoice>
describeHerwigMatchboxTopMassScale("Herwig::MatchboxTopMassScale", "HwMatchboxScales.so");
void MatchboxTopMassScale::Init() {
static ClassDocumentation<MatchboxTopMassScale> documentation
("MatchboxTopMassScale implements invariant mass of top-antitop pair as scale choice.");
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxTopMinMTScale.cc b/MatrixElement/Matchbox/Scales/MatchboxTopMinMTScale.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxTopMinMTScale.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxTopMinMTScale.cc
@@ -1,101 +1,101 @@
// -*- C++ -*-
//
// MatchboxTopMinMTScale.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 MatchboxTopMinMTScale class.
//
#include "MatchboxTopMinMTScale.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig++/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxTopMinMTScale::MatchboxTopMinMTScale() {}
MatchboxTopMinMTScale::~MatchboxTopMinMTScale() {}
IBPtr MatchboxTopMinMTScale::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxTopMinMTScale::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxTopMinMTScale::renormalizationScale() const {
size_t k = 2;
int top = -1;
int antitop = -1;
while ( (top == -1 || antitop == -1) && k < mePartonData().size() ){
if ( mePartonData()[k]->id() == 6 ) {
if ( top < 0 )
top = k;
else
assert(false);
} else if ( mePartonData()[k]->id() == -6 ) {
if ( antitop < 0 )
antitop = k;
else
assert(false);
}
k++;
}
if ( top < 2 || antitop < 2 ){
- cerr << "MatchboxTopMinMTScale: Could not find a top-antitop-pair in the final state!\n";
- assert(false);
+ throw Exception() << "MatchboxTopMinMTScale: Could not find a top-antitop-pair in the final state!\n"
+ << Exception::abortnow;
}
// cerr << " sqrt(TopMTScale) = "
// << sqrt(min(meMomenta()[top].mt2(),meMomenta()[antitop].mt2()))/GeV
// << "\n" << flush;
return(min(meMomenta()[top].mt2(),meMomenta()[antitop].mt2()));
}
Energy2 MatchboxTopMinMTScale::factorizationScale() const {
return(renormalizationScale());
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxTopMinMTScale::persistentOutput(PersistentOStream &) const {}
void MatchboxTopMinMTScale::persistentInput(PersistentIStream &, int) {}
// *** 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<MatchboxTopMinMTScale,MatchboxScaleChoice>
describeHerwigMatchboxTopMinMTScale("Herwig::MatchboxTopMinMTScale", "HwMatchboxScales.so");
void MatchboxTopMinMTScale::Init() {
static ClassDocumentation<MatchboxTopMinMTScale> documentation
("MatchboxTopMinMTScale implements the quadratic sum of the transverse masses of the top and antitop quark as a scale choice.");
}
diff --git a/MatrixElement/Matchbox/Scales/MatchboxTriVecScales.cc b/MatrixElement/Matchbox/Scales/MatchboxTriVecScales.cc
--- a/MatrixElement/Matchbox/Scales/MatchboxTriVecScales.cc
+++ b/MatrixElement/Matchbox/Scales/MatchboxTriVecScales.cc
@@ -1,190 +1,192 @@
// -*- C++ -*-
//
// MatchboxTriVecScales.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 MatchboxTriVecScales class.
//
#include "MatchboxTriVecScales.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxTriVecScales::MatchboxTriVecScales()
: theTriVecScaleChoice(1) {}
MatchboxTriVecScales::~MatchboxTriVecScales() {}
IBPtr MatchboxTriVecScales::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxTriVecScales::fullclone() const {
return new_ptr(*this);
}
Energy2 MatchboxTriVecScales::HtPrimeScale() const {
tcPDVector pd (mePartonData().begin() + 2, mePartonData().end());
vector<LorentzMomentum> p (meMomenta().begin() + 2, meMomenta().end());
tcPDPtr t1 = mePartonData()[0];
tcPDPtr t2 = mePartonData()[1];
tcCutsPtr cuts = lastCutsPtr();
theJetFinder->cluster(pd, p, cuts, t1, t2);
Energy sumpartpt = ZERO;
int foundpart = 0;
Energy vec1et = ZERO;
Energy vec2et = ZERO;
Energy vec3et = ZERO;
Energy sumvecet = ZERO;
int foundlept[3] = {0,0,0}; // First entry for e-like, second entry for mu-like, third entry for tau-like
int ivec1 = 0;
int ivec2 = 0;
int ivec3 = 0;
tcPDVector::const_iterator itpd = pd.begin();
int ip = 2;
for (vector<LorentzMomentum>::const_iterator itp = p.begin() ;
itp != p.end(); ++itp, ++itpd, ++ip ) {
if ( (**itpd).coloured() ) {
sumpartpt += (*itp).perp();
foundpart++;
}
if ( !(**itpd).coloured() ) {
if ( abs((**itpd).id())==ParticleID::nu_e || abs((**itpd).id())==ParticleID::eminus ) {
if ( foundlept[0]==0 ) {
foundlept[0] +=1;
ivec1 = ip;
}
if ( foundlept[0]==1 ) {
vec1et = sqrt( (p[ivec1]+p[ip]).m2() + (p[ivec1]+p[ip]).perp2() );
}
}
if ( abs((**itpd).id())==ParticleID::nu_mu || abs((**itpd).id())==ParticleID::muminus ) {
if ( foundlept[1]==0 ) {
foundlept[1] +=1;
ivec2 = ip;
}
if ( foundlept[1]==1 ) {
vec2et = sqrt( (p[ivec2]+p[ip]).m2() + (p[ivec2]+p[ip]).perp2() );
}
}
if ( abs((**itpd).id())==ParticleID::nu_tau || abs((**itpd).id())==ParticleID::tauminus ) {
if ( foundlept[2]==0 ) {
foundlept[2] +=1;
ivec3 = ip;
}
if ( foundlept[2]==1 ) {
vec3et = sqrt( (p[ivec3]+p[ip]).m2() + (p[ivec3]+p[ip]).perp2() );
}
}
}
}
sumvecet = vec1et+vec2et+vec3et;
// Check for consistency in number of lepton pairs and members therein
for (int i = 0; i<3; ++i ) {
- if (foundlept[i]>2 || foundlept[i]%2!=0) throw InitException() << "MatchboxTriVecScales::HtPrimeScale(): Inconsistency in number of lepton pairs and members therein!";
+ if (foundlept[i]>2 || foundlept[i]%2!=0)
+ throw Exception() << "MatchboxTriVecScales::HtPrimeScale(): Inconsistency in number of lepton pairs and members therein!"
+ << Exception::abortnow;
}
return sqr(sumpartpt+sumvecet);
}
Energy2 MatchboxTriVecScales::HtPrimeModScale() const {
throw InitException() << "MatchboxTriVecScales::HtPrimeModScale(): Not yet implemented!";
}
Energy2 MatchboxTriVecScales::EtScale() const {
throw InitException() << "MatchboxTriVecScales::EtScale(): Not yet implemented!";
}
Energy2 MatchboxTriVecScales::renormalizationScale() const {
// if ( theTriVecScaleChoice==1 ) return 0.5*HtPrimeScale();
// else if ( theTriVecScaleChoice==2 ) return 0.5*HtPrimeModScale();
// else if ( theTriVecScaleChoice==3 ) return 0.5*EtScale();
if ( theTriVecScaleChoice==2 ) return 0.5*HtPrimeModScale();
if ( theTriVecScaleChoice==3 ) return 0.5*EtScale();
return 0.5*HtPrimeScale(); // The default is theTriVecScaleChoice==1
}
Energy2 MatchboxTriVecScales::factorizationScale() const {
return renormalizationScale();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxTriVecScales::persistentOutput(PersistentOStream & os) const {
os << theJetFinder << theTriVecScaleChoice;
}
void MatchboxTriVecScales::persistentInput(PersistentIStream & is, int) {
is >> theJetFinder >> theTriVecScaleChoice;
}
// *** 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<MatchboxTriVecScales,MatchboxScaleChoice>
describeHerwigMatchboxTriVecScales("Herwig::MatchboxTriVecScales", "HwMatchboxScales.so");
void MatchboxTriVecScales::Init() {
static ClassDocumentation<MatchboxTriVecScales> documentation
("MatchboxTriVecScales implements scale choices related to transverse momenta and transverse energies for"
"events with up to three vector bosons in the final state, plus additional jets, where the vector bosons"
"are associated to lepton pairs of distinct families.");
static Reference<MatchboxTriVecScales,JetFinder> interfaceJetFinder
("JetFinder",
"A reference to the jet finder.",
&MatchboxTriVecScales::theJetFinder, false, false, true, false, false);
static Switch<MatchboxTriVecScales,unsigned int> interfaceTriVecScaleChoice
("TriVecScaleChoice",
"The scale choice to use.",
&MatchboxTriVecScales::theTriVecScaleChoice, 1, false, false);
static SwitchOption interfaceTriVecScaleChoice1
(interfaceTriVecScaleChoice,
"HtPrimeScale",
"Sum of the transverse energies of the lepton pairs and the transverse momenta of the jets.",
1);
static SwitchOption interfaceTriVecScaleChoice2
(interfaceTriVecScaleChoice,
"HtPrimeModScale",
"Sum of the transverse energies of the lepton pairs and the transverse momenta of the jets."
"Each transverse jet momenta is thereby suppressed by an exponential of the rapidity difference to the average rapidity of the two hardest jets."
"This scale choice is of benefit only for two or more jets in the event.",
2);
static SwitchOption interfaceTriVecScaleChoice3
(interfaceTriVecScaleChoice,
"EtScale",
"Sum of the transverse energies of the lepton pairs and the transverse energies of the jets."
"This scale choice is of benefit only for two or more jets in the event.",
3);
}
diff --git a/MatrixElement/Matchbox/Utility/ColourBasis.cc b/MatrixElement/Matchbox/Utility/ColourBasis.cc
--- a/MatrixElement/Matchbox/Utility/ColourBasis.cc
+++ b/MatrixElement/Matchbox/Utility/ColourBasis.cc
@@ -1,1278 +1,1278 @@
// -*- C++ -*-
//
// ColourBasis.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 ColourBasis class.
//
#include "ColourBasis.h"
#include "ThePEG/Interface/ClassDocumentation.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 "Herwig++/MatrixElement/Matchbox/MatchboxFactory.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <iterator>
using std::ostream_iterator;
#include "DiagramDrawer.h"
using namespace Herwig;
using boost::numeric::ublas::trans;
// default gcc on SLC6 confuses this with std::conj,
// use explicit namespacing in the code instead
//
// using boost::numeric::ublas::conj;
using boost::numeric::ublas::row;
using boost::numeric::ublas::column;
using boost::numeric::ublas::prod;
Ptr<MatchboxFactory>::tptr ColourBasis::factory() const {
return theFactory;
}
void ColourBasis::factory(Ptr<MatchboxFactory>::tptr f) {
theFactory = f;
}
ColourBasis::ColourBasis()
: theLargeN(false), didRead(false), didWrite(false), theSearchPath("") {}
ColourBasis::~ColourBasis() {
for ( map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >::iterator cl =
theColourLineMap.begin(); cl != theColourLineMap.end(); ++cl ) {
for ( vector<ColourLines*>::iterator c = cl->second.begin();
c != cl->second.end(); ++c ) {
if ( *c )
delete *c;
}
}
theColourLineMap.clear();
}
void ColourBasis::clear() {
theLargeN = false;
theNormalOrderedLegs.clear();
theIndexMap.clear();
theScalarProducts.clear();
theCharges.clear();
theChargeNonZeros.clear();
theCorrelators.clear();
theFlowMap.clear();
theColourLineMap.clear();
theOrderingStringIdentifiers.clear();
theOrderingIdentifiers.clear();
didRead = false;
didWrite = false;
tmp.clear();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
bool ColourBasis::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
return colourConnected(basis,idColoured,idAntiColoured,a);
}
const string& ColourBasis::orderingString(const cPDVector& sub,
const map<size_t,size_t>& colourToAmplitude,
size_t tensorId) {
map<size_t,string>& tensors = theOrderingStringIdentifiers[sub];
if ( !tensors.empty() ) {
assert(tensors.find(tensorId) != tensors.end());
return tensors[tensorId];
}
const set<vector<size_t> >& xordering = ordering(sub,colourToAmplitude,tensorId);
ostringstream os;
os << "[";
for ( set<vector<size_t> >::const_iterator t = xordering.begin();
t != xordering.end(); ++t ) {
os << "[";
for ( vector<size_t>::const_iterator s = t->begin();
s != t->end(); ++s ) {
os << *s << (s != --t->end() ? "," : "");
}
os << "]" << (t != --xordering.end() ? "," : "");
}
os << "]";
tensors[tensorId] = os.str();
return tensors[tensorId];
}
const set<vector<size_t> >& ColourBasis::ordering(const cPDVector& sub,
const map<size_t,size_t>& colourToAmplitude,
size_t tensorId) {
map<size_t,set<vector<size_t> > >& tensors = theOrderingIdentifiers[sub];
if ( !tensors.empty() ) {
assert(tensors.find(tensorId) != tensors.end());
return tensors[tensorId];
}
const vector<PDT::Colour>& basisId = normalOrderedLegs(sub);
map<size_t,vector<vector<size_t> > > labels = basisList(basisId);
for ( map<size_t,vector<vector<size_t> > >::const_iterator t =
labels.begin(); t != labels.end(); ++t ) {
set<vector<size_t> > xordering;
for ( vector<vector<size_t> >::const_iterator s = t->second.begin();
s != t->second.end(); ++s ) {
vector<size_t> crossed;
for ( vector<size_t>::const_iterator l = s->begin();
l != s->end(); ++l ) {
map<size_t,size_t>::const_iterator trans =
colourToAmplitude.find(*l);
assert(trans != colourToAmplitude.end());
crossed.push_back(trans->second);
}
xordering.insert(crossed);
}
tensors[t->first] = xordering;
}
assert(tensors.find(tensorId) != tensors.end());
return tensors[tensorId];
}
vector<PDT::Colour> ColourBasis::normalOrderMap(const cPDVector& sub) {
vector<PDT::Colour> allLegs = projectColour(sub);
vector<PDT::Colour> legs = normalOrder(allLegs);
if ( allLegs[0] == PDT::Colour3 )
allLegs[0] = PDT::Colour3bar;
else if ( allLegs[0] == PDT::Colour3bar )
allLegs[0] = PDT::Colour3;
if ( allLegs[1] == PDT::Colour3 )
allLegs[1] = PDT::Colour3bar;
else if ( allLegs[1] == PDT::Colour3bar )
allLegs[1] = PDT::Colour3;
if ( theIndexMap.find(sub) == theIndexMap.end() ) {
map<size_t,size_t> trans;
vector<PDT::Colour> checkLegs = legs;
size_t n = checkLegs.size();
for ( size_t i = 0; i < allLegs.size(); ++i ) {
size_t j = 0;
while ( checkLegs[j] != allLegs[i] ) {
++j; if ( j == n ) break;
}
if ( j == n ) continue;
trans[i] = j;
checkLegs[j] = PDT::ColourUndefined;
}
theIndexMap[sub] = trans;
}
return legs;
}
const vector<PDT::Colour>& ColourBasis::normalOrderedLegs(const cPDVector& sub) const {
static vector<PDT::Colour> empty;
map<cPDVector,vector<PDT::Colour> >::const_iterator n =
theNormalOrderedLegs.find(sub);
if ( n != theNormalOrderedLegs.end() )
return n->second;
return empty;
}
size_t ColourBasis::prepare(const cPDVector& sub,
bool noCorrelations) {
vector<PDT::Colour> legs = normalOrderMap(sub);
bool doPrepare = false;
if ( theNormalOrderedLegs.find(sub) == theNormalOrderedLegs.end() )
theNormalOrderedLegs[sub] = legs;
if ( theScalarProducts.find(legs) == theScalarProducts.end() )
doPrepare = true;
if ( doPrepare )
doPrepare = !readBasis(legs);
size_t dim = doPrepare ? prepareBasis(legs) : theScalarProducts[legs].size1();
if ( theCharges.find(legs) != theCharges.end() )
return dim;
if ( !doPrepare && noCorrelations )
return dim;
symmetric_matrix<double,upper>& sp =
theScalarProducts.insert(make_pair(legs,symmetric_matrix<double,upper>(dim,dim))).first->second;
for ( size_t a = 0; a < dim; ++a )
for ( size_t b = a; b < dim; ++b )
sp(a,b) = scalarProduct(a,b,legs);
if ( noCorrelations )
return dim;
vector<PDT::Colour> legsPlus = legs;
legsPlus.push_back(PDT::Colour8);
legsPlus = normalOrder(legsPlus);
bool doPreparePlus = theScalarProducts.find(legsPlus) == theScalarProducts.end();
size_t dimPlus = doPreparePlus ? prepareBasis(legsPlus) : theScalarProducts[legsPlus].size1();
symmetric_matrix<double,upper>& spPlus =
doPreparePlus ?
theScalarProducts.insert(make_pair(legsPlus,symmetric_matrix<double,upper>(dimPlus,dimPlus))).first->second :
theScalarProducts[legsPlus];
if ( doPreparePlus ) {
for ( size_t a = 0; a < dimPlus; ++a )
for ( size_t b = a; b < dimPlus; ++b )
spPlus(a,b) = scalarProduct(a,b,legsPlus);
}
typedef map<size_t,compressed_matrix<double> > cMap;
cMap& cm = theCharges.insert(make_pair(legs,cMap())).first->second;
typedef map<size_t,vector<pair<size_t,size_t> > > ccMap;
ccMap& ccm = theChargeNonZeros.insert(make_pair(legs,ccMap())).first->second;
tmp.resize(dimPlus,dim);
for ( size_t i = 0; i < legs.size(); ++i ) {
size_t nonZero = 0;
vector<pair<size_t,size_t> > nonZeros;
for ( size_t a = 0; a < dimPlus; ++a )
for ( size_t b = 0; b < dim; ++b ) {
tmp(a,b) = tMatrixElement(i,a,b,legsPlus,legs);
if ( tmp(a,b) != 0. ) {
++nonZero;
nonZeros.push_back(make_pair(a,b));
}
}
ccm.insert(make_pair(i,nonZeros));
compressed_matrix<double>& tm =
cm.insert(make_pair(i,compressed_matrix<double>(dimPlus,dim,nonZero))).first->second;
for ( size_t a = 0; a < dimPlus; ++a )
for ( size_t b = 0; b < dim; ++b ) {
if ( tmp(a,b) != 0. )
tm(a,b) = tmp(a,b);
}
}
map<pair<size_t,size_t>,symmetric_matrix<double,upper> >& xm = theCorrelators[legs];
for ( size_t i = 0; i < legs.size(); ++i )
for ( size_t j = i+1; j < legs.size(); ++j ) {
symmetric_matrix<double,upper>& mm =
xm.insert(make_pair(make_pair(i,j),symmetric_matrix<double,upper>(dim,dim))).first->second;
chargeProduct(cm[i],ccm[i],spPlus,cm[j],ccm[j],mm);
}
return dim;
}
void ColourBasis::chargeProduct(const compressed_matrix<double>& ti,
const vector<pair<size_t,size_t> >& tiNonZero,
const symmetric_matrix<double,upper>& X,
const compressed_matrix<double>& tj,
const vector<pair<size_t,size_t> >& tjNonZero,
symmetric_matrix<double,upper>& result) const {
for ( size_t i = 0; i < result.size1(); ++i )
for ( size_t j = i; j < result.size1(); ++j )
result(i,j) = 0.;
for ( vector<pair<size_t,size_t> >::const_iterator i = tiNonZero.begin();
i != tiNonZero.end(); ++i )
for ( vector<pair<size_t,size_t> >::const_iterator j = tjNonZero.begin();
j != tjNonZero.end(); ++j ) {
if ( j->second < i->second )
continue;
result(i->second,j->second) +=
ti(i->first,i->second)*tj(j->first,j->second)*X(i->first,j->first);
}
}
void ColourBasis::chargeProductAdd(const compressed_matrix<double>& ti,
const vector<pair<size_t,size_t> >& tiNonZero,
const matrix<Complex>& X,
const compressed_matrix<double>& tj,
const vector<pair<size_t,size_t> >& tjNonZero,
matrix<Complex>& result,
double factor) const {
for ( vector<pair<size_t,size_t> >::const_iterator i = tiNonZero.begin();
i != tiNonZero.end(); ++i )
for ( vector<pair<size_t,size_t> >::const_iterator j = tjNonZero.begin();
j != tjNonZero.end(); ++j ) {
result(i->first,j->first) += factor*
ti(i->first,i->second)*tj(j->first,j->second)*X(i->second,j->second);
}
}
string ColourBasis::cfstring(const list<list<pair<int,bool> > >& flow) {
ostringstream out("");
for ( list<list<pair<int,bool> > >::const_iterator line =
flow.begin(); line != flow.end(); ++line ) {
for ( list<pair<int,bool> >::const_iterator node =
line->begin(); node != line->end(); ++node ) {
out << (node->second ? "-" : "") << (node->first+1) << " ";
}
if ( line != --(flow.end()) )
out << ", ";
}
return out.str();
}
vector<string> ColourBasis::makeFlows(Ptr<Tree2toNDiagram>::tcptr diag,
size_t dim) const {
vector<string> res(dim);
list<list<list<pair<int,bool> > > > fdata =
colourFlows(diag);
cPDVector ext;
tcPDVector dext = diag->external();
copy(dext.begin(),dext.end(),back_inserter(ext));
vector<PDT::Colour> colouredLegs =
normalOrder(projectColour(ext));
for ( list<list<list<pair<int,bool> > > >::const_iterator flow =
fdata.begin(); flow != fdata.end(); ++flow ) {
for ( size_t i = 0; i < dim; ++i ) {
bool matches = true;
for ( list<list<pair<int,bool> > >::const_iterator line =
flow->begin(); line != flow->end(); ++line ) {
pair<int,bool> front(diag->externalId(line->front().first),line->front().second);
if ( front.first < 2 )
front.second = !front.second;
pair<int,bool> back(diag->externalId(line->back().first),line->back().second);
if ( back.first < 2 )
back.second = !back.second;
if ( !colourConnected(ext,colouredLegs,front,back,i) ) {
matches = false;
break;
}
}
if ( matches ) {
assert(res[i] == "" &&
"only support colour bases with unique mapping to large-N colour flows");
res[i] = cfstring(*flow);
}
}
}
bool gotone = false;
for ( vector<string>::const_iterator f = res.begin();
f != res.end(); ++f ) {
if ( *f != "" ) {
gotone = true;
break;
}
}
if ( !gotone ) {
generator()->log() << "warning no color flow found for diagram\n";
DiagramDrawer::drawDiag(generator()->log(),*diag);
}
return res;
}
size_t ColourBasis::prepare(const MEBase::DiagramVector& diags,
bool noCorrelations) {
size_t dim = 0;
for ( MEBase::DiagramVector::const_iterator d = diags.begin();
d != diags.end(); ++d ) {
Ptr<Tree2toNDiagram>::tcptr dd = dynamic_ptr_cast<Ptr<Tree2toNDiagram>::ptr>(*d);
assert(dd);
dim = prepare(dd->partons(),noCorrelations);
if ( !haveColourFlows() || theFlowMap.find(dd) != theFlowMap.end() )
continue;
theFlowMap[dd] = makeFlows(dd,dim);
}
return dim;
}
bool matchEnd(int a, pair<int,bool> b,
Ptr<Tree2toNDiagram>::tcptr diag) {
if ( a != b.first )
return false;
if ( b.first != diag->nSpace()-1 ) {
return
!b.second ?
diag->allPartons()[b.first]->hasColour() :
diag->allPartons()[b.first]->hasAntiColour();
} else {
return
!b.second ?
diag->allPartons()[b.first]->hasAntiColour() :
diag->allPartons()[b.first]->hasColour();
}
return false;
}
bool findPath(pair<int,bool> a, pair<int,bool> b,
Ptr<Tree2toNDiagram>::tcptr diag,
list<pair<int,bool> >& path,
bool backward) {
assert(a.first==0 ? !backward : true);
if ( path.empty() )
path.push_back(a);
if ( !backward ) {
if ( diag->children(a.first).first == -1 )
return matchEnd(a.first,b,diag);
pair<int,int> children = diag->children(a.first);
bool cc = (children.first == diag->nSpace()-1);
if ( diag->allPartons()[children.first]->coloured() )
if ( !cc ?
(!a.second ?
diag->allPartons()[children.first]->hasColour() :
diag->allPartons()[children.first]->hasAntiColour()) :
(!a.second ?
diag->allPartons()[children.first]->hasAntiColour() :
diag->allPartons()[children.first]->hasColour()) ) {
pair<int,bool> next(children.first,a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,false) ) {
path.pop_back();
} else return true;
}
cc = (children.second == diag->nSpace()-1);
if ( diag->allPartons()[children.second]->coloured() )
if ( !cc ?
(!a.second ?
diag->allPartons()[children.second]->hasColour() :
diag->allPartons()[children.second]->hasAntiColour()) :
(!a.second ?
diag->allPartons()[children.second]->hasAntiColour() :
diag->allPartons()[children.second]->hasColour()) ) {
pair<int,bool> next(children.second,a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,false) ) {
path.pop_back();
} else return true;
}
if ( path.size() == 1 )
path.pop_back();
return false;
} else {
int parent = diag->parent(a.first);
pair<int,int> neighbours = diag->children(parent);
int neighbour = a.first == neighbours.first ? neighbours.second : neighbours.first;
if ( matchEnd(parent,b,diag) ) {
path.push_back(b);
return true;
}
if ( matchEnd(neighbour,b,diag) ) {
path.push_back(b);
return true;
}
if ( diag->allPartons()[neighbour]->coloured() )
if ( a.second ?
diag->allPartons()[neighbour]->hasColour() :
diag->allPartons()[neighbour]->hasAntiColour() ) {
pair<int,bool> next(neighbour,!a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,false) ) {
path.pop_back();
} else return true;
}
if ( parent == 0 ) {
if ( path.size() == 1 )
path.pop_back();
return false;
}
if ( diag->allPartons()[parent]->coloured() )
if ( !a.second ?
diag->allPartons()[parent]->hasColour() :
diag->allPartons()[parent]->hasAntiColour() ) {
pair<int,bool> next(parent,a.second);
path.push_back(next);
if ( !findPath(next,b,diag,path,true) ) {
path.pop_back();
} else return true;
}
if ( path.size() == 1 )
path.pop_back();
return false;
}
return false;
}
list<pair<int,bool> > ColourBasis::colouredPath(pair<int,bool> a, pair<int,bool> b,
Ptr<Tree2toNDiagram>::tcptr diag) {
list<pair<int,bool> > res;
if ( a.first == b.first )
return res;
bool aIn = (a.first < 2);
bool bIn = (b.first < 2);
if ( (aIn && bIn) || (!aIn && !bIn) )
if ( (a.second && b.second) ||
(!a.second && !b.second) )
return res;
if ( (aIn && !bIn) || (!aIn && bIn) )
if ( (!a.second && b.second) ||
(a.second && !b.second) )
return res;
if ( a.first > b.first )
swap(a,b);
a.first = diag->diagramId(a.first);
b.first = diag->diagramId(b.first);
if ( a.first == diag->nSpace()-1 )
a.second = !a.second;
if ( b.first == diag->nSpace()-1 )
b.second = !b.second;
if ( !findPath(a,b,diag,res,a.first != 0) )
return res;
if ( b.first == diag->nSpace()-1 ) {
res.back().second = !res.back().second;
}
if ( a.first == diag->nSpace()-1 ) {
res.front().second = !res.front().second;
}
return res;
}
list<list<list<pair<int,bool> > > >
ColourBasis::colourFlows(Ptr<Tree2toNDiagram>::tcptr diag) {
vector<pair<int,bool> > connectSource;
vector<pair<int,bool> > connectSink;
for ( size_t i = 0; i != diag->partons().size(); ++i ) {
if ( i < 2 && diag->partons()[i]->hasAntiColour() )
connectSource.push_back(make_pair(i,true));
if ( i < 2 && diag->partons()[i]->hasColour() )
connectSink.push_back(make_pair(i,false));
if ( i > 1 && diag->partons()[i]->hasColour() )
connectSource.push_back(make_pair(i,false));
if ( i > 1 && diag->partons()[i]->hasAntiColour() )
connectSink.push_back(make_pair(i,true));
}
assert(connectSource.size() == connectSink.size());
list<list<list<pair<int,bool> > > > ret;
do {
vector<pair<int,bool> >::iterator source =
connectSource.begin();
vector<pair<int,bool> >::iterator sink =
connectSink.begin();
list<list<pair<int,bool> > > res;
for ( ; source != connectSource.end(); ++source, ++sink ) {
if ( source->first == sink->first ) {
res.clear();
break;
}
list<pair<int,bool> > line =
colouredPath(*source,*sink,diag);
if ( line.empty() ) {
res.clear();
break;
}
res.push_back(line);
}
if ( !res.empty() ) {
// check, if all dressed properly
vector<pair<int,int> > dressed((*diag).allPartons().size(),make_pair(0,0));
for ( size_t p = 0; p < diag->allPartons().size(); ++p ) {
if ( diag->allPartons()[p]->hasColour() &&
!diag->allPartons()[p]->hasAntiColour() )
dressed[p].first = 1;
if ( diag->allPartons()[p]->hasAntiColour() &&
!diag->allPartons()[p]->hasColour() )
dressed[p].second = 1;
if ( diag->allPartons()[p]->hasAntiColour() &&
diag->allPartons()[p]->hasColour() ) {
dressed[p].first = 1; dressed[p].second = 1;
}
}
for ( list<list<pair<int,bool> > >::const_iterator l = res.begin();
l != res.end(); ++l ) {
for ( list<pair<int,bool> >::const_iterator n = l->begin();
n != l->end(); ++n ) {
if ( !(n->second) )
dressed[n->first].first -= 1;
else
dressed[n->first].second -= 1;
}
}
for ( vector<pair<int,int> >::const_iterator d = dressed.begin();
d != dressed.end(); ++d ) {
if ( d->first != 0 || d->second != 0 ) {
res.clear();
break;
}
}
if ( !res.empty() )
ret.push_back(res);
}
} while ( std::next_permutation(connectSink.begin(),connectSink.end()) );
return ret;
}
void ColourBasis::updateColourLines(Ptr<Tree2toNDiagram>::tcptr dd) {
map<Ptr<Tree2toNDiagram>::tcptr,vector<string> >::const_iterator cl =
theFlowMap.find(dd);
assert(cl != theFlowMap.end());
vector<ColourLines*> clines(cl->second.size());
for ( size_t k = 0; k < cl->second.size(); ++k ) {
if ( cl->second[k] == "" ) {
clines[k] = 0;
continue;
}
clines[k] = new ColourLines(cl->second[k]);
}
theColourLineMap[cl->first] = clines;
}
map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >&
ColourBasis::colourLineMap() {
if ( !theColourLineMap.empty() )
return theColourLineMap;
for ( map<Ptr<Tree2toNDiagram>::tcptr,vector<string> >::const_iterator cl =
theFlowMap.begin(); cl != theFlowMap.end(); ++cl ) {
vector<ColourLines*> clines(cl->second.size());
for ( size_t k = 0; k < cl->second.size(); ++k ) {
if ( cl->second[k] == "" ) {
clines[k] = 0;
continue;
}
clines[k] = new ColourLines(cl->second[k]);
}
theColourLineMap[cl->first] = clines;
}
return theColourLineMap;
}
Selector<const ColourLines *> ColourBasis::colourGeometries(tcDiagPtr diag,
const map<vector<int>,CVector>& amps) {
Ptr<Tree2toNDiagram>::tcptr dd =
dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
assert(dd && theFlowMap.find(dd) != theFlowMap.end());
map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >::const_iterator colit =
colourLineMap().find(dd);
if ( colit == colourLineMap().end() ) {
updateColourLines(dd);
colit = colourLineMap().find(dd);
}
const vector<ColourLines*>& cl = colit->second;
Selector<const ColourLines *> sel;
size_t dim = amps.begin()->second.size();
assert(dim == cl.size());
double w = 0.;
for ( size_t i = 0; i < dim; ++i ) {
if ( !cl[i] )
continue;
w = 0.;
for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
a != amps.end(); ++a )
w += real(conj((a->second)(i))*((a->second)(i)));
if ( w > 0. )
sel.insert(w,cl[i]);
}
assert(!sel.empty());
return sel;
}
size_t ColourBasis::tensorIdFromFlow(tcDiagPtr diag, const ColourLines * flow) {
Ptr<Tree2toNDiagram>::tcptr dd =
dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
assert(dd && theFlowMap.find(dd) != theFlowMap.end());
map<Ptr<Tree2toNDiagram>::tcptr,vector<ColourLines*> >::const_iterator colit =
colourLineMap().find(dd);
if ( colit == colourLineMap().end() ) {
updateColourLines(dd);
colit = colourLineMap().find(dd);
}
const vector<ColourLines*>& cl = colit->second;
size_t res = 0;
for ( ; res < cl.size(); ++res ) {
if ( flow == cl[res] )
break;
}
assert(res < cl.size());
return res;
}
const symmetric_matrix<double,upper>& ColourBasis::scalarProducts(const cPDVector& sub) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
ScalarProductMap::const_iterator spit =
theScalarProducts.find(lit->second);
assert(spit != theScalarProducts.end());
return spit->second;
}
const compressed_matrix<double>& ColourBasis::charge(const cPDVector& sub, size_t iIn) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
ChargeMap::const_iterator ct =
theCharges.find(lit->second);
assert(ct != theCharges.end());
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= theIndexMap.find(sub);
assert(trans != theIndexMap.end());
size_t i = trans->second.find(iIn)->second;
map<size_t,compressed_matrix<double> >::const_iterator cit
= ct->second.find(i);
assert(cit != ct->second.end());
return cit->second;
}
const vector<pair<size_t,size_t> >& ColourBasis::chargeNonZero(const cPDVector& sub, size_t iIn) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
ChargeNonZeroMap::const_iterator ct =
theChargeNonZeros.find(lit->second);
assert(ct != theChargeNonZeros.end());
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= theIndexMap.find(sub);
assert(trans != theIndexMap.end());
size_t i = trans->second.find(iIn)->second;
map<size_t,vector<pair<size_t,size_t> > >::const_iterator cit
= ct->second.find(i);
assert(cit != ct->second.end());
return cit->second;
}
const symmetric_matrix<double,upper>& ColourBasis::correlator(const cPDVector& sub,
const pair<size_t,size_t>& ijIn) const {
map<cPDVector,vector<PDT::Colour> >::const_iterator lit =
theNormalOrderedLegs.find(sub);
assert(lit != theNormalOrderedLegs.end());
CorrelatorMap::const_iterator cit =
theCorrelators.find(lit->second);
assert(cit != theCorrelators.end());
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= theIndexMap.find(sub);
assert(trans != theIndexMap.end());
pair<size_t,size_t> ij(trans->second.find(ijIn.first)->second,
trans->second.find(ijIn.second)->second);
if ( ij.first > ij.second )
swap(ij.first,ij.second);
map<pair<size_t,size_t>,symmetric_matrix<double,upper> >::const_iterator cijit
= cit->second.find(ij);
assert(cijit != cit->second.end());
return cijit->second;
}
double ColourBasis::me2(const cPDVector& sub,
const map<vector<int>,CVector>& amps) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
double res = 0.;
for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
a != amps.end(); ++a ) {
res += real(inner_prod(boost::numeric::ublas::conj(a->second),prod(sp,a->second)));
}
return res;
}
double ColourBasis::interference(const cPDVector& sub,
const map<vector<int>,CVector>& amps1,
const map<vector<int>,CVector>& amps2) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
double res = 0.;
map<vector<int>,CVector>::const_iterator a = amps1.begin();
map<vector<int>,CVector>::const_iterator b = amps2.begin();
for ( ; a != amps1.end(); ++a, ++b ) {
assert(a->first == b->first);
res += 2.*real(inner_prod(boost::numeric::ublas::conj(a->second),prod(sp,b->second)));
}
assert(!isnan(res));
return res;
}
double ColourBasis::colourCorrelatedME2(const pair<size_t,size_t>& ij,
const cPDVector& sub,
const map<vector<int>,CVector>& amps) const {
const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
double res = 0.;
for ( map<vector<int>,CVector>::const_iterator a = amps.begin();
a != amps.end(); ++a ) {
res += real(inner_prod(boost::numeric::ublas::conj(a->second),prod(cij,a->second)));
}
return res;
}
Complex ColourBasis::interference(const cPDVector& sub,
const CVector& left,
const CVector& right) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
return inner_prod(boost::numeric::ublas::conj(left),prod(sp,right));
}
Complex ColourBasis::colourCorrelatedInterference(const pair<size_t,size_t>& ij,
const cPDVector& sub,
const CVector& left,
const CVector& right) const {
const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
return inner_prod(boost::numeric::ublas::conj(left),prod(cij,right));
}
double ColourBasis::me2(const cPDVector& sub,
const matrix<Complex>& amp) const {
const symmetric_matrix<double,upper>& sp = scalarProducts(sub);
double tr = 0;
size_t n = amp.size1();
for ( size_t i = 0; i < n; ++i ) {
tr += real(inner_prod(row(sp,i),column(amp,i)));
}
return tr;
}
double ColourBasis::colourCorrelatedME2(const pair<size_t,size_t>& ij,
const cPDVector& sub,
const matrix<Complex>& amp) const {
const symmetric_matrix<double,upper>& cij = correlator(sub,ij);
double tr = 0;
size_t n = amp.size1();
for ( size_t i = 0; i < n; ++i ) {
tr += real(inner_prod(row(cij,i),column(amp,i)));
}
return tr;
}
struct pickColour {
PDT::Colour operator()(tcPDPtr p) const {
return p->iColour();
}
};
vector<PDT::Colour> ColourBasis::projectColour(const cPDVector& sub) const {
vector<PDT::Colour> res(sub.size());
transform(sub.begin(),sub.end(),res.begin(),pickColour());
return res;
}
vector<PDT::Colour> ColourBasis::normalOrder(const vector<PDT::Colour>& legs) const {
vector<PDT::Colour> crosslegs = legs;
if ( crosslegs[0] == PDT::Colour3 )
crosslegs[0] = PDT::Colour3bar;
else if ( crosslegs[0] == PDT::Colour3bar )
crosslegs[0] = PDT::Colour3;
if ( crosslegs[1] == PDT::Colour3 )
crosslegs[1] = PDT::Colour3bar;
else if ( crosslegs[1] == PDT::Colour3bar )
crosslegs[1] = PDT::Colour3;
int n3 = count_if(crosslegs.begin(),crosslegs.end(),matchRep(PDT::Colour3));
int n8 = count_if(crosslegs.begin(),crosslegs.end(),matchRep(PDT::Colour8));
vector<PDT::Colour> ordered(2*n3+n8,PDT::Colour8);
int i = 0;
while ( i < 2*n3 ) {
ordered[i] = PDT::Colour3;
ordered[i+1] = PDT::Colour3bar;
i+=2;
}
return ordered;
}
string ColourBasis::file(const vector<PDT::Colour>& sub) const {
string res = name() + "-";
for ( vector<PDT::Colour>::const_iterator lit = sub.begin();
lit != sub.end(); ++lit ) {
if ( *lit == PDT::Colour3 )
res += "3";
if ( *lit == PDT::Colour3bar )
res += "3bar";
if ( *lit == PDT::Colour8 )
res += "8";
}
if ( largeN() )
res += "largeN";
return res;
}
void ColourBasis::writeBasis(const string& prefix) const {
if ( didWrite )
return;
set<vector<PDT::Colour> > legs;
for ( map<cPDVector,vector<PDT::Colour> >::const_iterator lit
= theNormalOrderedLegs.begin(); lit != theNormalOrderedLegs.end(); ++lit ) {
legs.insert(lit->second);
}
string searchPath = theSearchPath;
if ( searchPath != "" )
if ( *(--searchPath.end()) != '/' )
searchPath += "/";
for ( set<vector<PDT::Colour> >::const_iterator known = legs.begin();
known != legs.end(); ++known ) {
string fname = searchPath + prefix + file(*known) + ".cdat";
ifstream check(fname.c_str());
if ( check ) continue;
ofstream out(fname.c_str());
if ( !out )
- throw Exception() << "ColourBasis failed to open "
+ throw Exception() << "ColourBasis: Failed to open "
<< fname << " for storing colour basis information."
<< Exception::abortnow;
out << setprecision(18);
const symmetric_matrix<double,upper>& sp =
theScalarProducts.find(*known)->second;
write(sp,out);
if ( theCharges.find(*known) != theCharges.end() ) {
out << "#charges\n";
const map<size_t,compressed_matrix<double> >& tm =
theCharges.find(*known)->second;
const map<size_t,vector<pair<size_t,size_t> > >& tc =
theChargeNonZeros.find(*known)->second;
map<size_t,vector<pair<size_t,size_t> > >::const_iterator kc =
tc.begin();
for ( map<size_t,compressed_matrix<double> >::const_iterator k = tm.begin();
k != tm.end(); ++k, ++kc ) {
out << k->first << "\n";
write(k->second,out,kc->second);
}
const map<pair<size_t,size_t>,symmetric_matrix<double,upper> >& cm =
theCorrelators.find(*known)->second;
for ( map<pair<size_t,size_t>,symmetric_matrix<double,upper> >::const_iterator k =
cm.begin(); k != cm.end(); ++k ) {
out << k->first.first << "\n" << k->first.second << "\n";
write(k->second,out);
}
} else {
out << "#nocharges\n";
}
out << flush;
}
didWrite = true;
}
bool ColourBasis::readBasis(const vector<PDT::Colour>& legs) {
string searchPath = theSearchPath;
if ( searchPath != "" )
if ( *(--searchPath.end()) != '/' )
searchPath += "/";
string fname = searchPath + file(legs) + ".cdat";
ifstream in(fname.c_str());
if ( !in )
return false;
read(theScalarProducts[legs],in);
string tag; in >> tag;
if ( tag != "#nocharges" ) {
for ( size_t k = 0; k < legs.size(); ++k ) {
size_t i; in >> i;
read(theCharges[legs][i],in,theChargeNonZeros[legs][i]);
}
for ( size_t k = 0; k < legs.size()*(legs.size()-1)/2; ++k ) {
size_t i,j; in >> i >> j;
read(theCorrelators[legs][make_pair(i,j)],in);
}
}
readBasisDetails(legs);
return true;
}
void ColourBasis::readBasis() {
if ( didRead )
return;
string searchPath = theSearchPath;
if ( searchPath != "" )
if ( *(--searchPath.end()) != '/' )
searchPath += "/";
set<vector<PDT::Colour> > legs;
for ( map<cPDVector,vector<PDT::Colour> >::const_iterator lit
= theNormalOrderedLegs.begin(); lit != theNormalOrderedLegs.end(); ++lit )
legs.insert(lit->second);
for ( set<vector<PDT::Colour> >::const_iterator known = legs.begin();
known != legs.end(); ++known ) {
if ( theScalarProducts.find(*known) != theScalarProducts.end() )
continue;
string fname = searchPath + file(*known) + ".cdat";
if ( !readBasis(*known) )
- throw Exception() << "ColourBasis failed to open "
+ throw Exception() << "ColourBasis: Failed to open "
<< fname << " for reading colour basis information."
<< Exception::abortnow;
}
didRead = true;
}
void ColourBasis::write(const symmetric_matrix<double,upper>& m, ostream& os) const {
os << m.size1() << "\n";
for ( size_t i = 0; i < m.size1(); ++i )
for ( size_t j = i; j < m.size1(); ++j )
os << m(i,j) << "\n";
os << flush;
}
void ColourBasis::read(symmetric_matrix<double,upper>& m, istream& is) {
size_t s; is >> s;
m.resize(s);
for ( size_t i = 0; i < m.size1(); ++i )
for ( size_t j = i; j < m.size1(); ++j )
is >> m(i,j);
}
void ColourBasis::write(const compressed_matrix<double>& m, ostream& os,
const vector<pair<size_t,size_t> >& nonZeros) const {
os << nonZeros.size() << "\n"
<< m.size1() << "\n"
<< m.size2() << "\n";
for ( vector<pair<size_t,size_t> >::const_iterator nz = nonZeros.begin();
nz != nonZeros.end(); ++nz )
os << nz->first << "\n" << nz->second << "\n"
<< m(nz->first,nz->second) << "\n";
os << flush;
}
void ColourBasis::read(compressed_matrix<double>& m, istream& is,
vector<pair<size_t,size_t> >& nonZeros) {
size_t nonZero, size1, size2;
is >> nonZero >> size1 >> size2;
nonZeros.resize(nonZero);
m = compressed_matrix<double>(size1,size2,nonZero);
for ( size_t k = 0; k < nonZero; ++k ) {
size_t i,j; double val;
is >> i >> j >> val;
nonZeros[k] = make_pair(i,j);
m(i,j) = val;
}
}
void ColourBasis::doinit() {
HandlerBase::doinit();
if ( theSearchPath.empty() && factory() )
theSearchPath = factory()->buildStorage();
readBasis();
}
void ColourBasis::dofinish() {
HandlerBase::dofinish();
writeBasis();
}
void ColourBasis::doinitrun() {
HandlerBase::doinitrun();
if ( theSearchPath.empty() && factory() )
theSearchPath = factory()->buildStorage();
readBasis();
}
void ColourBasis::persistentOutput(PersistentOStream & os) const {
os << theLargeN << theNormalOrderedLegs
<< theIndexMap << theFlowMap << theOrderingStringIdentifiers
<< theOrderingIdentifiers << theFactory << theSearchPath;
writeBasis();
}
void ColourBasis::persistentInput(PersistentIStream & is, int) {
is >> theLargeN >> theNormalOrderedLegs
>> theIndexMap >> theFlowMap >> theOrderingStringIdentifiers
>> theOrderingIdentifiers >> theFactory >> theSearchPath;
}
// *** 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<ColourBasis,HandlerBase>
describeColourBasis("Herwig::ColourBasis", "Herwig.so");
void ColourBasis::Init() {
static ClassDocumentation<ColourBasis> documentation
("ColourBasis is an interface to a colour basis "
"implementation.");
static Switch<ColourBasis,bool> interfaceLargeN
("LargeN",
"Switch on or off large-N evaluation.",
&ColourBasis::theLargeN, false, false, false);
static SwitchOption interfaceLargeNOn
(interfaceLargeN,
"On",
"Work in N=infinity",
true);
static SwitchOption interfaceLargeNOff
(interfaceLargeN,
"Off",
"Work in N=3",
false);
}
diff --git a/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc b/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc
--- a/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc
+++ b/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc
@@ -1,107 +1,107 @@
// -*- C++ -*-
//
// MatchboxFactoryMatcher.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 MatchboxFactoryMatcher class.
//
#include "MatchboxFactoryMatcher.h"
#include "ThePEG/Interface/ClassDocumentation.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"
using namespace Herwig;
MatchboxFactoryMatcher::MatchboxFactoryMatcher()
: theGroup("") {}
MatchboxFactoryMatcher::~MatchboxFactoryMatcher() {}
IBPtr MatchboxFactoryMatcher::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxFactoryMatcher::fullclone() const {
return new_ptr(*this);
}
PMPtr MatchboxFactoryMatcher::pmclone() const {
return new_ptr(*this);
}
bool MatchboxFactoryMatcher::check(const ParticleData & data) const {
return theIds.find(data.id()) != theIds.end();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxFactoryMatcher::persistentOutput(PersistentOStream & os) const {
os << theFactory << theGroup << theIds;
}
void MatchboxFactoryMatcher::persistentInput(PersistentIStream & is, int) {
is >> theFactory >> theGroup >> theIds;
}
void MatchboxFactoryMatcher::doinit() {
if ( !MatchboxFactory::isMatchboxRun() )
return;
if ( !theFactory )
throw InitException()
- << "No factory object has been set for the matcher '"
+ << "MatchboxFactoryMatcher::doinit(): No factory object has been set for the matcher '"
<< name() << "'" << Exception::abortnow;
map<string,PDVector>::const_iterator grp
= theFactory->particleGroups().find(theGroup);
if ( grp == theFactory->particleGroups().end() )
throw InitException()
- << "Particle group '" << theGroup << "' not defined in factory object '"
+ << "MatchboxFactoryMatcher::doinit(): Particle group '" << theGroup << "' not defined in factory object '"
<< theFactory->name() << "'" << Exception::abortnow;
theIds.clear();
for ( PDVector::const_iterator p = grp->second.begin();
p != grp->second.end(); ++p )
theIds.insert((**p).id());
MatcherBase::doinit();
}
// *** 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<MatchboxFactoryMatcher,ThePEG::MatcherBase>
describeHerwigMatchboxFactoryMatcher("Herwig::MatchboxFactoryMatcher", "Herwig.so");
void MatchboxFactoryMatcher::Init() {
static ClassDocumentation<MatchboxFactoryMatcher> documentation
("MatchboxFactoryMatcher matches particles according to MatchboxFatory particle groups");
static Reference<MatchboxFactoryMatcher,MatchboxFactory> interfaceFactory
("Factory",
"Set the factory to query for particle groups.",
&MatchboxFactoryMatcher::theFactory, false, false, true, true, false);
static Parameter<MatchboxFactoryMatcher,string> interfaceGroup
("Group",
"Set the group name to match.",
&MatchboxFactoryMatcher::theGroup, "",
false, false);
}
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
@@ -1,396 +1,396 @@
// -*- C++ -*-
//
// SimpleColourBasis.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.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SimpleColourBasis class.
//
#include "SimpleColourBasis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
SimpleColourBasis::SimpleColourBasis() {}
SimpleColourBasis::~SimpleColourBasis() {}
IBPtr SimpleColourBasis::clone() const {
return new_ptr(*this);
}
IBPtr SimpleColourBasis::fullclone() const {
return new_ptr(*this);
}
size_t SimpleColourBasis::prepareBasis(const vector<PDT::Colour>& basis) {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 || basis == id33bar || basis == id33bar8 )
return 1;
if ( basis == id888 || basis == id33bar88 || basis == id33bar33bar )
return 2;
if ( basis == id8888 )
return 6;
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis::prepareBasis(): Cannot handle colour configuration" << Exception::abortnow;
return 0;
}
double SimpleColourBasis::scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& abBasis) const {
if ( id33bar.empty() )
makeIds();
double Nc = SM().Nc();
double Nc2 = sqr(Nc);
double Nc3 = Nc*Nc2;
double Nc4 = sqr(Nc2);
double Nc6 = Nc2*Nc4;
if ( a > b )
swap(a,b);
if ( !largeN() ) {
if ( abBasis == id88 ) {
return ( Nc2 - 1. )/4.;
}
if ( abBasis == id33bar ) {
return Nc;
}
if ( abBasis == id888 ) {
if ( a == b )
return ( Nc4 - 3.*Nc2 + 2. )/(8.*Nc);
return -( Nc2 - 1. )/(4.*Nc);
}
if ( abBasis == id33bar8 ) {
return ( Nc2 - 1. )/2.;
}
if ( abBasis == id8888 ) {
if ( a == b )
return ( Nc6 - 4.*Nc4 + 6.*Nc2 - 3. )/(16.*Nc2);
if ( ( a == 0 && b == 1 ) ||
( a == 2 && b == 3 ) ||
( a == 4 && b == 5 ) )
return ( Nc4 + 2.*Nc2 - 3. )/(16.*Nc2);
return -( Nc2 - 4. + 3./Nc2 )/16.;
}
if ( abBasis == id33bar88 ) {
if ( a == b )
return ( Nc4 - 2.*Nc2 + 1 )/(4.*Nc);
return -( Nc2 - 1. )/(4.*Nc);
}
if ( abBasis == id33bar33bar ) {
if ( a == b )
return Nc2;
return Nc;
}
} else {
if ( a != b )
return 0.;
if ( abBasis == id88 ) {
return Nc2/4.;
}
if ( abBasis == id33bar ) {
return Nc;
}
if ( abBasis == id888 ) {
return Nc3/8.;
}
if ( abBasis == id33bar8 ) {
return Nc2/2.;
}
if ( abBasis == id8888 ) {
return Nc4/16.;
}
if ( abBasis == id33bar88 ) {
return Nc3/4.;
}
if ( abBasis == id33bar33bar ) {
return Nc2;
}
}
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis::scalarProduct(): Cannot handle colour configuration" << Exception::abortnow;
}
double SimpleColourBasis::tMatrixElement(size_t i, size_t a,
size_t b,
const vector<PDT::Colour>&,
const vector<PDT::Colour>& bBasis) const {
if ( id33bar.empty() )
makeIds();
if ( bBasis == id88 ) {
if ( i == 0 )
return a == 0 ? -1. : 1.;
else
return a == 0 ? 1. : -1.;
}
if ( bBasis == id33bar ) {
return i == 0 ? 1. : -1.;
}
if ( bBasis == id888 ) {
if ( i == 0 ) {
if ( a == 3 && b == 0 )
return 1.;
if ( a == 0 && b == 0 )
return -1.;
if ( a == 1 && b == 1 )
return 1.;
if ( a == 2 && b == 1 )
return -1.;
}
if ( i == 1 ) {
if ( a == 4 && b == 0 )
return 1.;
if ( a == 3 && b == 0 )
return -1.;
if ( a == 2 && b == 1 )
return 1.;
if ( a == 5 && b == 1 )
return -1.;
}
if ( i == 2 ) {
if ( a == 0 && b == 0 )
return 1.;
if ( a == 4 && b == 0 )
return -1.;
if ( a == 5 && b == 1 )
return 1.;
if ( a == 1 && b == 1 )
return -1.;
}
return 0.;
}
if ( bBasis == id33bar8 ) {
if ( i == 0 )
return a == 1 ? 1. : 0.;
if ( i == 1 )
return a == 0 ? -1. : 0.;
if ( i == 2 )
return a == 0 ? 1. : -1.;
}
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis::tMatrixElement(): Cannot handle colour configuration" << Exception::abortnow;
return 0.;
}
bool SimpleColourBasis::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
if ( id33bar.empty() )
makeIds();
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
if ( basis == id88 ) {
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar ) {
return
idColoured == 0 && idAntiColoured == 1;
}
if ( basis == id888 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar8 ) {
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
if ( basis == id8888 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 0 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
if ( a == 2 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 0 );
if ( a == 3 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 4 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 5 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar88 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
if ( basis == id33bar33bar ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 2 && idAntiColoured == 3 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
return false;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void SimpleColourBasis::makeIds() const {
id88.push_back(PDT::Colour8);
id88.push_back(PDT::Colour8);
id33bar.push_back(PDT::Colour3);
id33bar.push_back(PDT::Colour3bar);
id888.push_back(PDT::Colour8);
id888.push_back(PDT::Colour8);
id888.push_back(PDT::Colour8);
id33bar8.push_back(PDT::Colour3);
id33bar8.push_back(PDT::Colour3bar);
id33bar8.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id33bar88.push_back(PDT::Colour3);
id33bar88.push_back(PDT::Colour3bar);
id33bar88.push_back(PDT::Colour8);
id33bar88.push_back(PDT::Colour8);
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
}
void SimpleColourBasis::persistentOutput(PersistentOStream &) const {}
void SimpleColourBasis::persistentInput(PersistentIStream &, int) {}
// *** 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<SimpleColourBasis,ColourBasis>
describeHerwigSimpleColourBasis("Herwig::SimpleColourBasis", "Herwig.so");
void SimpleColourBasis::Init() {
static ClassDocumentation<SimpleColourBasis> documentation
("SimpleColourBasis implements the colour algebra needed for "
"electroweak boson and electroweak boson + jet production at NLO. It mainly "
"serves as an example for the general ColourBasis interface.");
}
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
@@ -1,2864 +1,2864 @@
// -*- C++ -*-
//
// SimpleColourBasis2.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.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SimpleColourBasis2 class.
//
#include "SimpleColourBasis2.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
SimpleColourBasis2::SimpleColourBasis2() {}
SimpleColourBasis2::~SimpleColourBasis2() {}
IBPtr SimpleColourBasis2::clone() const {
return new_ptr(*this);
}
IBPtr SimpleColourBasis2::fullclone() const {
return new_ptr(*this);
}
size_t SimpleColourBasis2::prepareBasis(const vector<PDT::Colour>& basis) {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 ) {
return 1;
}
if ( basis == id33bar ) {
return 1;
}
if ( basis == id888 ) {
return 2;
}
if ( basis == id33bar8 ) {
return 1;
}
if ( basis == id8888 ) {
return 9;
}
if ( basis == id33bar88 ) {
return 3;
}
if ( basis == id33bar33bar ) {
return 2;
}
if ( basis == id88888 ) {
return 44;
}
if ( basis == id33bar888 ) {
return 11;
}
if ( basis == id33bar33bar8 ) {
return 4;
}
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis2::prepareBasis(): Cannot handle colour configuration" << Exception::abortnow;
return 0;
}
double SimpleColourBasis2::scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
double Nc = SM().Nc();
double Nc2 = sqr(Nc);
double Nc3 = Nc*Nc2;
double Nc4 = sqr(Nc2);
double Nc5 = Nc*Nc4;
double Nc6 = Nc2*Nc4;
double Nc8 = Nc2*Nc6;
if ( a > b )
swap(a,b);
if ( !largeN() ) {
if ( basis == id88 ) {
if( a == 0 && b == 0 )
return (-1 + Nc2)/4.;
}
if ( basis == id33bar ) {
if( a == 0 && b == 0 )
return Nc;
}
if ( basis == id888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) )
return (2 - 3*Nc2 + Nc4)/(8.*Nc);
if( ( a == 0 ) && ( b == 1 ) )
return -(-1 + Nc2)/(4.*Nc);
}
if ( basis == id33bar8 ) {
if( a == 0 && b == 0 )
return (-1 + Nc2)/2.;
}
if ( basis == id8888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) )
return sqr(-1 + Nc2)/16.;
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 2 ) ||
( a == 1 && b == 2 ) )
return (-1 + Nc2)/16.;
if( ( a == 0 && b == 3 ) ||
( a == 0 && b == 5 ) ||
( a == 0 && b == 7 ) ||
( a == 0 && b == 8 ) ||
( a == 1 && b == 4 ) ||
( a == 1 && b == 5 ) ||
( a == 1 && b == 6 ) ||
( a == 1 && b == 7 ) ||
( a == 2 && b == 3 ) ||
( a == 2 && b == 4 ) ||
( a == 2 && b == 6 ) ||
( a == 2 && b == 8 ) )
return sqr(-1 + Nc2)/(16.*Nc);
if( ( a == 0 && b == 4 ) ||
( a == 0 && b == 6 ) ||
( a == 1 && b == 3 ) ||
( a == 1 && b == 8 ) ||
( a == 2 && b == 5 ) ||
( a == 2 && b == 7 ) )
return -(-1 + Nc2)/(16.*Nc);
if( ( a == 3 && b == 3 ) ||
( a == 4 && b == 4 ) ||
( a == 5 && b == 5 ) ||
( a == 6 && b == 6 ) ||
( a == 7 && b == 7 ) ||
( a == 8 && b == 8 ) )
return (-3 + 6*Nc2 - 4*Nc4 + Nc6)/(16.*Nc2);
if( ( a == 3 && b == 4 ) ||
( a == 3 && b == 5 ) ||
( a == 3 && b == 6 ) ||
( a == 3 && b == 7 ) ||
( a == 4 && b == 5 ) ||
( a == 4 && b == 7 ) ||
( a == 4 && b == 8 ) ||
( a == 5 && b == 6 ) ||
( a == 5 && b == 8 ) ||
( a == 6 && b == 7 ) ||
( a == 6 && b == 8 ) ||
( a == 7 && b == 8 ) )
return (4 - 3/Nc2 - Nc2)/16.;
if( ( a == 3 && b == 8 ) ||
( a == 4 && b == 6 ) ||
( a == 5 && b == 7 ) )
return (-3 + 2*Nc2 + Nc4)/(16.*Nc2);
}
if ( basis == id33bar88 ) {
if( a == 0 && b == 0 )
return (Nc*(-1 + Nc2))/4.;
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 2 ) )
return (-1 + Nc2)/4.;
if( ( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) )
return sqr(-1 + Nc2)/(4.*Nc);
if( a == 1 && b == 2 )
return -(-1 + Nc2)/(4.*Nc);
}
if ( basis == id33bar33bar ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) )
return Nc2;
if( a == 0 && b == 1 )
return Nc;
}
if ( basis == id88888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) ||
( a == 3 && b == 3 ) ||
( a == 4 && b == 4 ) ||
( a == 5 && b == 5 ) ||
( a == 6 && b == 6 ) ||
( a == 7 && b == 7 ) ||
( a == 8 && b == 8 ) ||
( a == 9 && b == 9 ) ||
( a == 10 && b == 10 ) ||
( a == 11 && b == 11 ) ||
( a == 12 && b == 12 ) ||
( a == 13 && b == 13 ) ||
( a == 14 && b == 14 ) ||
( a == 15 && b == 15 ) ||
( a == 16 && b == 16 ) ||
( a == 17 && b == 17 ) ||
( a == 18 && b == 18 ) ||
( a == 19 && b == 19 ) )
return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc);
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 2 ) ||
( a == 0 && b == 7 ) ||
( a == 0 && b == 10 ) ||
( a == 0 && b == 12 ) ||
( a == 0 && b == 13 ) ||
( a == 1 && b == 2 ) ||
( a == 1 && b == 4 ) ||
( a == 1 && b == 11 ) ||
( a == 1 && b == 14 ) ||
( a == 1 && b == 15 ) ||
( a == 2 && b == 5 ) ||
( a == 2 && b == 8 ) ||
( a == 2 && b == 16 ) ||
( a == 2 && b == 17 ) ||
( a == 3 && b == 4 ) ||
( a == 3 && b == 5 ) ||
( a == 3 && b == 6 ) ||
( a == 3 && b == 9 ) ||
( a == 3 && b == 14 ) ||
( a == 3 && b == 16 ) ||
( a == 4 && b == 5 ) ||
( a == 4 && b == 11 ) ||
( a == 4 && b == 12 ) ||
( a == 4 && b == 18 ) ||
( a == 5 && b == 8 ) ||
( a == 5 && b == 13 ) ||
( a == 5 && b == 19 ) ||
( a == 6 && b == 7 ) ||
( a == 6 && b == 8 ) ||
( a == 6 && b == 9 ) ||
( a == 6 && b == 12 ) ||
( a == 6 && b == 17 ) ||
( a == 7 && b == 8 ) ||
( a == 7 && b == 10 ) ||
( a == 7 && b == 14 ) ||
( a == 7 && b == 19 ) ||
( a == 8 && b == 15 ) ||
( a == 8 && b == 18 ) ||
( a == 9 && b == 10 ) ||
( a == 9 && b == 11 ) ||
( a == 9 && b == 13 ) ||
( a == 9 && b == 15 ) ||
( a == 10 && b == 11 ) ||
( a == 10 && b == 16 ) ||
( a == 10 && b == 18 ) ||
( a == 11 && b == 17 ) ||
( a == 11 && b == 19 ) ||
( a == 12 && b == 13 ) ||
( a == 12 && b == 17 ) ||
( a == 12 && b == 18 ) ||
( a == 13 && b == 15 ) ||
( a == 13 && b == 19 ) ||
( a == 14 && b == 15 ) ||
( a == 14 && b == 16 ) ||
( a == 14 && b == 19 ) ||
( a == 15 && b == 18 ) ||
( a == 16 && b == 17 ) ||
( a == 16 && b == 18 ) ||
( a == 17 && b == 19 ) )
return (2 - 3*Nc2 + Nc4)/(32.*Nc);
if( ( a == 0 && b == 3 ) ||
( a == 1 && b == 6 ) ||
( a == 2 && b == 9 ) ||
( a == 4 && b == 7 ) ||
( a == 5 && b == 10 ) ||
( a == 8 && b == 11 ) ||
( a == 12 && b == 14 ) ||
( a == 13 && b == 16 ) ||
( a == 15 && b == 17 ) ||
( a == 18 && b == 19 ) )
return -sqr(-1 + Nc2)/(16.*Nc);
if( ( a == 0 && b == 4 ) ||
( a == 0 && b == 5 ) ||
( a == 0 && b == 6 ) ||
( a == 0 && b == 9 ) ||
( a == 0 && b == 14 ) ||
( a == 0 && b == 16 ) ||
( a == 1 && b == 3 ) ||
( a == 1 && b == 7 ) ||
( a == 1 && b == 8 ) ||
( a == 1 && b == 9 ) ||
( a == 1 && b == 12 ) ||
( a == 1 && b == 17 ) ||
( a == 2 && b == 3 ) ||
( a == 2 && b == 6 ) ||
( a == 2 && b == 10 ) ||
( a == 2 && b == 11 ) ||
( a == 2 && b == 13 ) ||
( a == 2 && b == 15 ) ||
( a == 3 && b == 7 ) ||
( a == 3 && b == 10 ) ||
( a == 3 && b == 12 ) ||
( a == 3 && b == 13 ) ||
( a == 4 && b == 6 ) ||
( a == 4 && b == 8 ) ||
( a == 4 && b == 10 ) ||
( a == 4 && b == 14 ) ||
( a == 4 && b == 19 ) ||
( a == 5 && b == 7 ) ||
( a == 5 && b == 9 ) ||
( a == 5 && b == 11 ) ||
( a == 5 && b == 16 ) ||
( a == 5 && b == 18 ) ||
( a == 6 && b == 11 ) ||
( a == 6 && b == 14 ) ||
( a == 6 && b == 15 ) ||
( a == 7 && b == 11 ) ||
( a == 7 && b == 12 ) ||
( a == 7 && b == 18 ) ||
( a == 8 && b == 9 ) ||
( a == 8 && b == 10 ) ||
( a == 8 && b == 17 ) ||
( a == 8 && b == 19 ) ||
( a == 9 && b == 16 ) ||
( a == 9 && b == 17 ) ||
( a == 10 && b == 13 ) ||
( a == 10 && b == 19 ) ||
( a == 11 && b == 15 ) ||
( a == 11 && b == 18 ) ||
( a == 12 && b == 15 ) ||
( a == 12 && b == 16 ) ||
( a == 12 && b == 19 ) ||
( a == 13 && b == 14 ) ||
( a == 13 && b == 17 ) ||
( a == 13 && b == 18 ) ||
( a == 14 && b == 17 ) ||
( a == 14 && b == 18 ) ||
( a == 15 && b == 16 ) ||
( a == 15 && b == 19 ) ||
( a == 16 && b == 19 ) ||
( a == 17 && b == 18 ) )
return -(-1 + Nc2)/(16.*Nc);
if( ( a == 0 && b == 8 ) ||
( a == 0 && b == 11 ) ||
( a == 0 && b == 15 ) ||
( a == 0 && b == 17 ) ||
( a == 0 && b == 18 ) ||
( a == 0 && b == 19 ) ||
( a == 1 && b == 5 ) ||
( a == 1 && b == 10 ) ||
( a == 1 && b == 13 ) ||
( a == 1 && b == 16 ) ||
( a == 1 && b == 18 ) ||
( a == 1 && b == 19 ) ||
( a == 2 && b == 4 ) ||
( a == 2 && b == 7 ) ||
( a == 2 && b == 12 ) ||
( a == 2 && b == 14 ) ||
( a == 2 && b == 18 ) ||
( a == 2 && b == 19 ) ||
( a == 3 && b == 8 ) ||
( a == 3 && b == 11 ) ||
( a == 3 && b == 15 ) ||
( a == 3 && b == 17 ) ||
( a == 3 && b == 18 ) ||
( a == 3 && b == 19 ) ||
( a == 4 && b == 9 ) ||
( a == 4 && b == 13 ) ||
( a == 4 && b == 15 ) ||
( a == 4 && b == 16 ) ||
( a == 4 && b == 17 ) ||
( a == 5 && b == 6 ) ||
( a == 5 && b == 12 ) ||
( a == 5 && b == 14 ) ||
( a == 5 && b == 15 ) ||
( a == 5 && b == 17 ) ||
( a == 6 && b == 10 ) ||
( a == 6 && b == 13 ) ||
( a == 6 && b == 16 ) ||
( a == 6 && b == 18 ) ||
( a == 6 && b == 19 ) ||
( a == 7 && b == 9 ) ||
( a == 7 && b == 13 ) ||
( a == 7 && b == 15 ) ||
( a == 7 && b == 16 ) ||
( a == 7 && b == 17 ) ||
( a == 8 && b == 12 ) ||
( a == 8 && b == 13 ) ||
( a == 8 && b == 14 ) ||
( a == 8 && b == 16 ) ||
( a == 9 && b == 12 ) ||
( a == 9 && b == 14 ) ||
( a == 9 && b == 18 ) ||
( a == 9 && b == 19 ) ||
( a == 10 && b == 12 ) ||
( a == 10 && b == 14 ) ||
( a == 10 && b == 15 ) ||
( a == 10 && b == 17 ) ||
( a == 11 && b == 12 ) ||
( a == 11 && b == 13 ) ||
( a == 11 && b == 14 ) ||
( a == 11 && b == 16 ) )
return 0;
if( ( a == 0 && b == 20 ) ||
( a == 0 && b == 21 ) ||
( a == 0 && b == 23 ) ||
( a == 0 && b == 25 ) ||
( a == 0 && b == 36 ) ||
( a == 0 && b == 42 ) ||
( a == 1 && b == 21 ) ||
( a == 1 && b == 22 ) ||
( a == 1 && b == 23 ) ||
( a == 1 && b == 24 ) ||
( a == 1 && b == 30 ) ||
( a == 1 && b == 40 ) ||
( a == 2 && b == 20 ) ||
( a == 2 && b == 22 ) ||
( a == 2 && b == 24 ) ||
( a == 2 && b == 25 ) ||
( a == 2 && b == 28 ) ||
( a == 2 && b == 34 ) ||
( a == 3 && b == 26 ) ||
( a == 3 && b == 27 ) ||
( a == 3 && b == 29 ) ||
( a == 3 && b == 31 ) ||
( a == 3 && b == 37 ) ||
( a == 3 && b == 43 ) ||
( a == 4 && b == 24 ) ||
( a == 4 && b == 27 ) ||
( a == 4 && b == 28 ) ||
( a == 4 && b == 29 ) ||
( a == 4 && b == 30 ) ||
( a == 4 && b == 38 ) ||
( a == 5 && b == 22 ) ||
( a == 5 && b == 26 ) ||
( a == 5 && b == 28 ) ||
( a == 5 && b == 30 ) ||
( a == 5 && b == 31 ) ||
( a == 5 && b == 32 ) ||
( a == 6 && b == 31 ) ||
( a == 6 && b == 32 ) ||
( a == 6 && b == 33 ) ||
( a == 6 && b == 35 ) ||
( a == 6 && b == 37 ) ||
( a == 6 && b == 41 ) ||
( a == 7 && b == 25 ) ||
( a == 7 && b == 33 ) ||
( a == 7 && b == 34 ) ||
( a == 7 && b == 35 ) ||
( a == 7 && b == 36 ) ||
( a == 7 && b == 39 ) ||
( a == 8 && b == 20 ) ||
( a == 8 && b == 26 ) ||
( a == 8 && b == 32 ) ||
( a == 8 && b == 34 ) ||
( a == 8 && b == 36 ) ||
( a == 8 && b == 37 ) ||
( a == 9 && b == 29 ) ||
( a == 9 && b == 35 ) ||
( a == 9 && b == 38 ) ||
( a == 9 && b == 39 ) ||
( a == 9 && b == 41 ) ||
( a == 9 && b == 43 ) ||
( a == 10 && b == 23 ) ||
( a == 10 && b == 33 ) ||
( a == 10 && b == 39 ) ||
( a == 10 && b == 40 ) ||
( a == 10 && b == 41 ) ||
( a == 10 && b == 42 ) ||
( a == 11 && b == 21 ) ||
( a == 11 && b == 27 ) ||
( a == 11 && b == 38 ) ||
( a == 11 && b == 40 ) ||
( a == 11 && b == 42 ) ||
( a == 11 && b == 43 ) ||
( a == 12 && b == 20 ) ||
( a == 12 && b == 28 ) ||
( a == 12 && b == 32 ) ||
( a == 12 && b == 38 ) ||
( a == 12 && b == 41 ) ||
( a == 12 && b == 42 ) ||
( a == 13 && b == 21 ) ||
( a == 13 && b == 30 ) ||
( a == 13 && b == 32 ) ||
( a == 13 && b == 35 ) ||
( a == 13 && b == 36 ) ||
( a == 13 && b == 38 ) ||
( a == 14 && b == 22 ) ||
( a == 14 && b == 26 ) ||
( a == 14 && b == 34 ) ||
( a == 14 && b == 39 ) ||
( a == 14 && b == 40 ) ||
( a == 14 && b == 43 ) ||
( a == 15 && b == 23 ) ||
( a == 15 && b == 26 ) ||
( a == 15 && b == 29 ) ||
( a == 15 && b == 30 ) ||
( a == 15 && b == 36 ) ||
( a == 15 && b == 39 ) ||
( a == 16 && b == 24 ) ||
( a == 16 && b == 27 ) ||
( a == 16 && b == 33 ) ||
( a == 16 && b == 34 ) ||
( a == 16 && b == 37 ) ||
( a == 16 && b == 40 ) ||
( a == 17 && b == 25 ) ||
( a == 17 && b == 27 ) ||
( a == 17 && b == 28 ) ||
( a == 17 && b == 31 ) ||
( a == 17 && b == 33 ) ||
( a == 17 && b == 42 ) ||
( a == 18 && b == 20 ) ||
( a == 18 && b == 23 ) ||
( a == 18 && b == 24 ) ||
( a == 18 && b == 29 ) ||
( a == 18 && b == 37 ) ||
( a == 18 && b == 41 ) ||
( a == 19 && b == 21 ) ||
( a == 19 && b == 22 ) ||
( a == 19 && b == 25 ) ||
( a == 19 && b == 31 ) ||
( a == 19 && b == 35 ) ||
( a == 19 && b == 43 ) )
return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc2);
if( ( a == 0 && b == 22 ) ||
( a == 0 && b == 24 ) ||
( a == 0 && b == 32 ) ||
( a == 0 && b == 33 ) ||
( a == 0 && b == 38 ) ||
( a == 0 && b == 39 ) ||
( a == 1 && b == 20 ) ||
( a == 1 && b == 25 ) ||
( a == 1 && b == 26 ) ||
( a == 1 && b == 27 ) ||
( a == 1 && b == 38 ) ||
( a == 1 && b == 39 ) ||
( a == 2 && b == 21 ) ||
( a == 2 && b == 23 ) ||
( a == 2 && b == 26 ) ||
( a == 2 && b == 27 ) ||
( a == 2 && b == 32 ) ||
( a == 2 && b == 33 ) ||
( a == 3 && b == 28 ) ||
( a == 3 && b == 30 ) ||
( a == 3 && b == 34 ) ||
( a == 3 && b == 35 ) ||
( a == 3 && b == 40 ) ||
( a == 3 && b == 41 ) ||
( a == 4 && b == 20 ) ||
( a == 4 && b == 21 ) ||
( a == 4 && b == 26 ) ||
( a == 4 && b == 31 ) ||
( a == 4 && b == 40 ) ||
( a == 4 && b == 41 ) ||
( a == 5 && b == 20 ) ||
( a == 5 && b == 21 ) ||
( a == 5 && b == 27 ) ||
( a == 5 && b == 29 ) ||
( a == 5 && b == 34 ) ||
( a == 5 && b == 35 ) ||
( a == 6 && b == 28 ) ||
( a == 6 && b == 29 ) ||
( a == 6 && b == 34 ) ||
( a == 6 && b == 36 ) ||
( a == 6 && b == 42 ) ||
( a == 6 && b == 43 ) ||
( a == 7 && b == 22 ) ||
( a == 7 && b == 23 ) ||
( a == 7 && b == 32 ) ||
( a == 7 && b == 37 ) ||
( a == 7 && b == 42 ) ||
( a == 7 && b == 43 ) ||
( a == 8 && b == 22 ) ||
( a == 8 && b == 23 ) ||
( a == 8 && b == 28 ) ||
( a == 8 && b == 29 ) ||
( a == 8 && b == 33 ) ||
( a == 8 && b == 35 ) ||
( a == 9 && b == 30 ) ||
( a == 9 && b == 31 ) ||
( a == 9 && b == 36 ) ||
( a == 9 && b == 37 ) ||
( a == 9 && b == 40 ) ||
( a == 9 && b == 42 ) ||
( a == 10 && b == 24 ) ||
( a == 10 && b == 25 ) ||
( a == 10 && b == 36 ) ||
( a == 10 && b == 37 ) ||
( a == 10 && b == 38 ) ||
( a == 10 && b == 43 ) ||
( a == 11 && b == 24 ) ||
( a == 11 && b == 25 ) ||
( a == 11 && b == 30 ) ||
( a == 11 && b == 31 ) ||
( a == 11 && b == 39 ) ||
( a == 11 && b == 41 ) ||
( a == 12 && b == 21 ) ||
( a == 12 && b == 24 ) ||
( a == 12 && b == 29 ) ||
( a == 12 && b == 31 ) ||
( a == 12 && b == 33 ) ||
( a == 12 && b == 36 ) ||
( a == 13 && b == 20 ) ||
( a == 13 && b == 22 ) ||
( a == 13 && b == 29 ) ||
( a == 13 && b == 31 ) ||
( a == 13 && b == 39 ) ||
( a == 13 && b == 42 ) ||
( a == 14 && b == 23 ) ||
( a == 14 && b == 25 ) ||
( a == 14 && b == 27 ) ||
( a == 14 && b == 30 ) ||
( a == 14 && b == 35 ) ||
( a == 14 && b == 37 ) ||
( a == 15 && b == 20 ) ||
( a == 15 && b == 22 ) ||
( a == 15 && b == 35 ) ||
( a == 15 && b == 37 ) ||
( a == 15 && b == 38 ) ||
( a == 15 && b == 40 ) ||
( a == 16 && b == 23 ) ||
( a == 16 && b == 25 ) ||
( a == 16 && b == 26 ) ||
( a == 16 && b == 28 ) ||
( a == 16 && b == 41 ) ||
( a == 16 && b == 43 ) ||
( a == 17 && b == 21 ) ||
( a == 17 && b == 24 ) ||
( a == 17 && b == 32 ) ||
( a == 17 && b == 34 ) ||
( a == 17 && b == 41 ) ||
( a == 17 && b == 43 ) ||
( a == 18 && b == 26 ) ||
( a == 18 && b == 28 ) ||
( a == 18 && b == 33 ) ||
( a == 18 && b == 36 ) ||
( a == 18 && b == 38 ) ||
( a == 18 && b == 40 ) ||
( a == 19 && b == 27 ) ||
( a == 19 && b == 30 ) ||
( a == 19 && b == 32 ) ||
( a == 19 && b == 34 ) ||
( a == 19 && b == 39 ) ||
( a == 19 && b == 42 ) )
return -(2 - 3*Nc2 + Nc4)/(32.*Nc2);
if( ( a == 0 && b == 26 ) ||
( a == 0 && b == 27 ) ||
( a == 0 && b == 29 ) ||
( a == 0 && b == 31 ) ||
( a == 0 && b == 37 ) ||
( a == 0 && b == 43 ) ||
( a == 1 && b == 31 ) ||
( a == 1 && b == 32 ) ||
( a == 1 && b == 33 ) ||
( a == 1 && b == 35 ) ||
( a == 1 && b == 37 ) ||
( a == 1 && b == 41 ) ||
( a == 2 && b == 29 ) ||
( a == 2 && b == 35 ) ||
( a == 2 && b == 38 ) ||
( a == 2 && b == 39 ) ||
( a == 2 && b == 41 ) ||
( a == 2 && b == 43 ) ||
( a == 3 && b == 20 ) ||
( a == 3 && b == 21 ) ||
( a == 3 && b == 23 ) ||
( a == 3 && b == 25 ) ||
( a == 3 && b == 36 ) ||
( a == 3 && b == 42 ) ||
( a == 4 && b == 25 ) ||
( a == 4 && b == 33 ) ||
( a == 4 && b == 34 ) ||
( a == 4 && b == 35 ) ||
( a == 4 && b == 36 ) ||
( a == 4 && b == 39 ) ||
( a == 5 && b == 23 ) ||
( a == 5 && b == 33 ) ||
( a == 5 && b == 39 ) ||
( a == 5 && b == 40 ) ||
( a == 5 && b == 41 ) ||
( a == 5 && b == 42 ) ||
( a == 6 && b == 21 ) ||
( a == 6 && b == 22 ) ||
( a == 6 && b == 23 ) ||
( a == 6 && b == 24 ) ||
( a == 6 && b == 30 ) ||
( a == 6 && b == 40 ) ||
( a == 7 && b == 24 ) ||
( a == 7 && b == 27 ) ||
( a == 7 && b == 28 ) ||
( a == 7 && b == 29 ) ||
( a == 7 && b == 30 ) ||
( a == 7 && b == 38 ) ||
( a == 8 && b == 21 ) ||
( a == 8 && b == 27 ) ||
( a == 8 && b == 38 ) ||
( a == 8 && b == 40 ) ||
( a == 8 && b == 42 ) ||
( a == 8 && b == 43 ) ||
( a == 9 && b == 20 ) ||
( a == 9 && b == 22 ) ||
( a == 9 && b == 24 ) ||
( a == 9 && b == 25 ) ||
( a == 9 && b == 28 ) ||
( a == 9 && b == 34 ) ||
( a == 10 && b == 22 ) ||
( a == 10 && b == 26 ) ||
( a == 10 && b == 28 ) ||
( a == 10 && b == 30 ) ||
( a == 10 && b == 31 ) ||
( a == 10 && b == 32 ) ||
( a == 11 && b == 20 ) ||
( a == 11 && b == 26 ) ||
( a == 11 && b == 32 ) ||
( a == 11 && b == 34 ) ||
( a == 11 && b == 36 ) ||
( a == 11 && b == 37 ) ||
( a == 12 && b == 22 ) ||
( a == 12 && b == 26 ) ||
( a == 12 && b == 34 ) ||
( a == 12 && b == 39 ) ||
( a == 12 && b == 40 ) ||
( a == 12 && b == 43 ) ||
( a == 13 && b == 24 ) ||
( a == 13 && b == 27 ) ||
( a == 13 && b == 33 ) ||
( a == 13 && b == 34 ) ||
( a == 13 && b == 37 ) ||
( a == 13 && b == 40 ) ||
( a == 14 && b == 20 ) ||
( a == 14 && b == 28 ) ||
( a == 14 && b == 32 ) ||
( a == 14 && b == 38 ) ||
( a == 14 && b == 41 ) ||
( a == 14 && b == 42 ) ||
( a == 15 && b == 25 ) ||
( a == 15 && b == 27 ) ||
( a == 15 && b == 28 ) ||
( a == 15 && b == 31 ) ||
( a == 15 && b == 33 ) ||
( a == 15 && b == 42 ) ||
( a == 16 && b == 21 ) ||
( a == 16 && b == 30 ) ||
( a == 16 && b == 32 ) ||
( a == 16 && b == 35 ) ||
( a == 16 && b == 36 ) ||
( a == 16 && b == 38 ) ||
( a == 17 && b == 23 ) ||
( a == 17 && b == 26 ) ||
( a == 17 && b == 29 ) ||
( a == 17 && b == 30 ) ||
( a == 17 && b == 36 ) ||
( a == 17 && b == 39 ) ||
( a == 18 && b == 21 ) ||
( a == 18 && b == 22 ) ||
( a == 18 && b == 25 ) ||
( a == 18 && b == 31 ) ||
( a == 18 && b == 35 ) ||
( a == 18 && b == 43 ) ||
( a == 19 && b == 20 ) ||
( a == 19 && b == 23 ) ||
( a == 19 && b == 24 ) ||
( a == 19 && b == 29 ) ||
( a == 19 && b == 37 ) ||
( a == 19 && b == 41 ) )
return -sqr(-1 + Nc2)/(16.*Nc2);
if( ( a == 0 && b == 28 ) ||
( a == 0 && b == 30 ) ||
( a == 0 && b == 34 ) ||
( a == 0 && b == 35 ) ||
( a == 0 && b == 40 ) ||
( a == 0 && b == 41 ) ||
( a == 1 && b == 28 ) ||
( a == 1 && b == 29 ) ||
( a == 1 && b == 34 ) ||
( a == 1 && b == 36 ) ||
( a == 1 && b == 42 ) ||
( a == 1 && b == 43 ) ||
( a == 2 && b == 30 ) ||
( a == 2 && b == 31 ) ||
( a == 2 && b == 36 ) ||
( a == 2 && b == 37 ) ||
( a == 2 && b == 40 ) ||
( a == 2 && b == 42 ) ||
( a == 3 && b == 22 ) ||
( a == 3 && b == 24 ) ||
( a == 3 && b == 32 ) ||
( a == 3 && b == 33 ) ||
( a == 3 && b == 38 ) ||
( a == 3 && b == 39 ) ||
( a == 4 && b == 22 ) ||
( a == 4 && b == 23 ) ||
( a == 4 && b == 32 ) ||
( a == 4 && b == 37 ) ||
( a == 4 && b == 42 ) ||
( a == 4 && b == 43 ) ||
( a == 5 && b == 24 ) ||
( a == 5 && b == 25 ) ||
( a == 5 && b == 36 ) ||
( a == 5 && b == 37 ) ||
( a == 5 && b == 38 ) ||
( a == 5 && b == 43 ) ||
( a == 6 && b == 20 ) ||
( a == 6 && b == 25 ) ||
( a == 6 && b == 26 ) ||
( a == 6 && b == 27 ) ||
( a == 6 && b == 38 ) ||
( a == 6 && b == 39 ) ||
( a == 7 && b == 20 ) ||
( a == 7 && b == 21 ) ||
( a == 7 && b == 26 ) ||
( a == 7 && b == 31 ) ||
( a == 7 && b == 40 ) ||
( a == 7 && b == 41 ) ||
( a == 8 && b == 24 ) ||
( a == 8 && b == 25 ) ||
( a == 8 && b == 30 ) ||
( a == 8 && b == 31 ) ||
( a == 8 && b == 39 ) ||
( a == 8 && b == 41 ) ||
( a == 9 && b == 21 ) ||
( a == 9 && b == 23 ) ||
( a == 9 && b == 26 ) ||
( a == 9 && b == 27 ) ||
( a == 9 && b == 32 ) ||
( a == 9 && b == 33 ) ||
( a == 10 && b == 20 ) ||
( a == 10 && b == 21 ) ||
( a == 10 && b == 27 ) ||
( a == 10 && b == 29 ) ||
( a == 10 && b == 34 ) ||
( a == 10 && b == 35 ) ||
( a == 11 && b == 22 ) ||
( a == 11 && b == 23 ) ||
( a == 11 && b == 28 ) ||
( a == 11 && b == 29 ) ||
( a == 11 && b == 33 ) ||
( a == 11 && b == 35 ) ||
( a == 12 && b == 23 ) ||
( a == 12 && b == 25 ) ||
( a == 12 && b == 27 ) ||
( a == 12 && b == 30 ) ||
( a == 12 && b == 35 ) ||
( a == 12 && b == 37 ) ||
( a == 13 && b == 23 ) ||
( a == 13 && b == 25 ) ||
( a == 13 && b == 26 ) ||
( a == 13 && b == 28 ) ||
( a == 13 && b == 41 ) ||
( a == 13 && b == 43 ) ||
( a == 14 && b == 21 ) ||
( a == 14 && b == 24 ) ||
( a == 14 && b == 29 ) ||
( a == 14 && b == 31 ) ||
( a == 14 && b == 33 ) ||
( a == 14 && b == 36 ) ||
( a == 15 && b == 21 ) ||
( a == 15 && b == 24 ) ||
( a == 15 && b == 32 ) ||
( a == 15 && b == 34 ) ||
( a == 15 && b == 41 ) ||
( a == 15 && b == 43 ) ||
( a == 16 && b == 20 ) ||
( a == 16 && b == 22 ) ||
( a == 16 && b == 29 ) ||
( a == 16 && b == 31 ) ||
( a == 16 && b == 39 ) ||
( a == 16 && b == 42 ) ||
( a == 17 && b == 20 ) ||
( a == 17 && b == 22 ) ||
( a == 17 && b == 35 ) ||
( a == 17 && b == 37 ) ||
( a == 17 && b == 38 ) ||
( a == 17 && b == 40 ) ||
( a == 18 && b == 27 ) ||
( a == 18 && b == 30 ) ||
( a == 18 && b == 32 ) ||
( a == 18 && b == 34 ) ||
( a == 18 && b == 39 ) ||
( a == 18 && b == 42 ) ||
( a == 19 && b == 26 ) ||
( a == 19 && b == 28 ) ||
( a == 19 && b == 33 ) ||
( a == 19 && b == 36 ) ||
( a == 19 && b == 38 ) ||
( a == 19 && b == 40 ) )
return (1 - 1/Nc2)/16.;
if( ( a == 20 && b == 20 ) ||
( a == 21 && b == 21 ) ||
( a == 22 && b == 22 ) ||
( a == 23 && b == 23 ) ||
( a == 24 && b == 24 ) ||
( a == 25 && b == 25 ) ||
( a == 26 && b == 26 ) ||
( a == 27 && b == 27 ) ||
( a == 28 && b == 28 ) ||
( a == 29 && b == 29 ) ||
( a == 30 && b == 30 ) ||
( a == 31 && b == 31 ) ||
( a == 32 && b == 32 ) ||
( a == 33 && b == 33 ) ||
( a == 34 && b == 34 ) ||
( a == 35 && b == 35 ) ||
( a == 36 && b == 36 ) ||
( a == 37 && b == 37 ) ||
( a == 38 && b == 38 ) ||
( a == 39 && b == 39 ) ||
( a == 40 && b == 40 ) ||
( a == 41 && b == 41 ) ||
( a == 42 && b == 42 ) ||
( a == 43 && b == 43 ) )
return (4 - 10*Nc2 + 10*Nc4 - 5*Nc6 + Nc8)/(32.*Nc3);
if( ( a == 20 && b == 21 ) ||
( a == 20 && b == 22 ) ||
( a == 20 && b == 26 ) ||
( a == 20 && b == 29 ) ||
( a == 20 && b == 38 ) ||
( a == 21 && b == 24 ) ||
( a == 21 && b == 27 ) ||
( a == 21 && b == 31 ) ||
( a == 21 && b == 32 ) ||
( a == 22 && b == 23 ) ||
( a == 22 && b == 32 ) ||
( a == 22 && b == 35 ) ||
( a == 22 && b == 39 ) ||
( a == 23 && b == 25 ) ||
( a == 23 && b == 26 ) ||
( a == 23 && b == 33 ) ||
( a == 23 && b == 37 ) ||
( a == 24 && b == 25 ) ||
( a == 24 && b == 33 ) ||
( a == 24 && b == 38 ) ||
( a == 24 && b == 41 ) ||
( a == 25 && b == 27 ) ||
( a == 25 && b == 39 ) ||
( a == 25 && b == 43 ) ||
( a == 26 && b == 27 ) ||
( a == 26 && b == 28 ) ||
( a == 26 && b == 40 ) ||
( a == 27 && b == 30 ) ||
( a == 27 && b == 34 ) ||
( a == 28 && b == 29 ) ||
( a == 28 && b == 33 ) ||
( a == 28 && b == 34 ) ||
( a == 28 && b == 41 ) ||
( a == 29 && b == 31 ) ||
( a == 29 && b == 35 ) ||
( a == 29 && b == 36 ) ||
( a == 30 && b == 31 ) ||
( a == 30 && b == 35 ) ||
( a == 30 && b == 39 ) ||
( a == 30 && b == 40 ) ||
( a == 31 && b == 41 ) ||
( a == 31 && b == 42 ) ||
( a == 32 && b == 33 ) ||
( a == 32 && b == 34 ) ||
( a == 32 && b == 42 ) ||
( a == 33 && b == 36 ) ||
( a == 34 && b == 35 ) ||
( a == 34 && b == 43 ) ||
( a == 35 && b == 37 ) ||
( a == 36 && b == 37 ) ||
( a == 36 && b == 38 ) ||
( a == 36 && b == 42 ) ||
( a == 37 && b == 40 ) ||
( a == 37 && b == 43 ) ||
( a == 38 && b == 39 ) ||
( a == 38 && b == 40 ) ||
( a == 39 && b == 42 ) ||
( a == 40 && b == 41 ) ||
( a == 41 && b == 43 ) ||
( a == 42 && b == 43 ) )
return -(-4 + 7*Nc2 - 4*Nc4 + Nc6)/(32.*Nc3);
if( ( a == 20 && b == 23 ) ||
( a == 20 && b == 24 ) ||
( a == 20 && b == 28 ) ||
( a == 20 && b == 32 ) ||
( a == 20 && b == 36 ) ||
( a == 21 && b == 22 ) ||
( a == 21 && b == 25 ) ||
( a == 21 && b == 30 ) ||
( a == 21 && b == 38 ) ||
( a == 21 && b == 42 ) ||
( a == 22 && b == 25 ) ||
( a == 22 && b == 26 ) ||
( a == 22 && b == 30 ) ||
( a == 22 && b == 34 ) ||
( a == 23 && b == 24 ) ||
( a == 23 && b == 36 ) ||
( a == 23 && b == 39 ) ||
( a == 23 && b == 40 ) ||
( a == 24 && b == 27 ) ||
( a == 24 && b == 28 ) ||
( a == 24 && b == 40 ) ||
( a == 25 && b == 33 ) ||
( a == 25 && b == 34 ) ||
( a == 25 && b == 42 ) ||
( a == 26 && b == 29 ) ||
( a == 26 && b == 30 ) ||
( a == 26 && b == 34 ) ||
( a == 26 && b == 37 ) ||
( a == 27 && b == 28 ) ||
( a == 27 && b == 31 ) ||
( a == 27 && b == 40 ) ||
( a == 27 && b == 43 ) ||
( a == 28 && b == 31 ) ||
( a == 28 && b == 32 ) ||
( a == 29 && b == 30 ) ||
( a == 29 && b == 37 ) ||
( a == 29 && b == 38 ) ||
( a == 29 && b == 41 ) ||
( a == 30 && b == 38 ) ||
( a == 31 && b == 32 ) ||
( a == 31 && b == 35 ) ||
( a == 31 && b == 43 ) ||
( a == 32 && b == 35 ) ||
( a == 32 && b == 36 ) ||
( a == 33 && b == 34 ) ||
( a == 33 && b == 37 ) ||
( a == 33 && b == 41 ) ||
( a == 33 && b == 42 ) ||
( a == 34 && b == 37 ) ||
( a == 35 && b == 36 ) ||
( a == 35 && b == 39 ) ||
( a == 35 && b == 43 ) ||
( a == 36 && b == 39 ) ||
( a == 37 && b == 41 ) ||
( a == 38 && b == 41 ) ||
( a == 38 && b == 42 ) ||
( a == 39 && b == 40 ) ||
( a == 39 && b == 43 ) ||
( a == 40 && b == 43 ) ||
( a == 41 && b == 42 ) )
return (2 - 3*Nc2 + Nc4)/(16.*Nc3);
if( ( a == 20 && b == 25 ) ||
( a == 20 && b == 34 ) ||
( a == 20 && b == 37 ) ||
( a == 20 && b == 41 ) ||
( a == 20 && b == 42 ) ||
( a == 21 && b == 23 ) ||
( a == 21 && b == 35 ) ||
( a == 21 && b == 36 ) ||
( a == 21 && b == 40 ) ||
( a == 21 && b == 43 ) ||
( a == 22 && b == 24 ) ||
( a == 22 && b == 28 ) ||
( a == 22 && b == 31 ) ||
( a == 22 && b == 40 ) ||
( a == 22 && b == 43 ) ||
( a == 23 && b == 29 ) ||
( a == 23 && b == 30 ) ||
( a == 23 && b == 41 ) ||
( a == 23 && b == 42 ) ||
( a == 24 && b == 29 ) ||
( a == 24 && b == 30 ) ||
( a == 24 && b == 34 ) ||
( a == 24 && b == 37 ) ||
( a == 25 && b == 28 ) ||
( a == 25 && b == 31 ) ||
( a == 25 && b == 35 ) ||
( a == 25 && b == 36 ) ||
( a == 26 && b == 31 ) ||
( a == 26 && b == 32 ) ||
( a == 26 && b == 36 ) ||
( a == 26 && b == 39 ) ||
( a == 26 && b == 43 ) ||
( a == 27 && b == 29 ) ||
( a == 27 && b == 33 ) ||
( a == 27 && b == 37 ) ||
( a == 27 && b == 38 ) ||
( a == 27 && b == 42 ) ||
( a == 28 && b == 30 ) ||
( a == 28 && b == 38 ) ||
( a == 28 && b == 42 ) ||
( a == 29 && b == 39 ) ||
( a == 29 && b == 43 ) ||
( a == 30 && b == 32 ) ||
( a == 30 && b == 36 ) ||
( a == 31 && b == 33 ) ||
( a == 31 && b == 37 ) ||
( a == 32 && b == 37 ) ||
( a == 32 && b == 38 ) ||
( a == 32 && b == 41 ) ||
( a == 33 && b == 35 ) ||
( a == 33 && b == 39 ) ||
( a == 33 && b == 40 ) ||
( a == 34 && b == 36 ) ||
( a == 34 && b == 39 ) ||
( a == 34 && b == 40 ) ||
( a == 35 && b == 38 ) ||
( a == 35 && b == 41 ) ||
( a == 38 && b == 43 ) ||
( a == 39 && b == 41 ) ||
( a == 40 && b == 42 ) )
return (4 - 3*Nc2 - 2*Nc4 + Nc6)/(32.*Nc3);
if( ( a == 20 && b == 27 ) ||
( a == 20 && b == 31 ) ||
( a == 20 && b == 35 ) ||
( a == 20 && b == 39 ) ||
( a == 20 && b == 40 ) ||
( a == 21 && b == 26 ) ||
( a == 21 && b == 29 ) ||
( a == 21 && b == 33 ) ||
( a == 21 && b == 34 ) ||
( a == 21 && b == 41 ) ||
( a == 22 && b == 29 ) ||
( a == 22 && b == 33 ) ||
( a == 22 && b == 37 ) ||
( a == 22 && b == 38 ) ||
( a == 22 && b == 42 ) ||
( a == 23 && b == 27 ) ||
( a == 23 && b == 28 ) ||
( a == 23 && b == 32 ) ||
( a == 23 && b == 35 ) ||
( a == 23 && b == 43 ) ||
( a == 24 && b == 31 ) ||
( a == 24 && b == 32 ) ||
( a == 24 && b == 36 ) ||
( a == 24 && b == 39 ) ||
( a == 24 && b == 43 ) ||
( a == 25 && b == 26 ) ||
( a == 25 && b == 30 ) ||
( a == 25 && b == 37 ) ||
( a == 25 && b == 38 ) ||
( a == 25 && b == 41 ) ||
( a == 26 && b == 33 ) ||
( a == 26 && b == 38 ) ||
( a == 26 && b == 41 ) ||
( a == 27 && b == 32 ) ||
( a == 27 && b == 35 ) ||
( a == 27 && b == 39 ) ||
( a == 28 && b == 35 ) ||
( a == 28 && b == 36 ) ||
( a == 28 && b == 40 ) ||
( a == 28 && b == 43 ) ||
( a == 29 && b == 33 ) ||
( a == 29 && b == 34 ) ||
( a == 29 && b == 42 ) ||
( a == 30 && b == 34 ) ||
( a == 30 && b == 37 ) ||
( a == 30 && b == 41 ) ||
( a == 30 && b == 42 ) ||
( a == 31 && b == 36 ) ||
( a == 31 && b == 39 ) ||
( a == 31 && b == 40 ) ||
( a == 32 && b == 39 ) ||
( a == 32 && b == 43 ) ||
( a == 33 && b == 38 ) ||
( a == 34 && b == 41 ) ||
( a == 34 && b == 42 ) ||
( a == 35 && b == 40 ) ||
( a == 36 && b == 40 ) ||
( a == 36 && b == 43 ) ||
( a == 37 && b == 38 ) ||
( a == 37 && b == 42 ) )
return -(-1 + Nc2)/(8.*Nc3);
if( ( a == 20 && b == 30 ) ||
( a == 20 && b == 33 ) ||
( a == 21 && b == 28 ) ||
( a == 21 && b == 39 ) ||
( a == 22 && b == 27 ) ||
( a == 22 && b == 36 ) ||
( a == 23 && b == 34 ) ||
( a == 23 && b == 38 ) ||
( a == 24 && b == 26 ) ||
( a == 24 && b == 42 ) ||
( a == 25 && b == 32 ) ||
( a == 25 && b == 40 ) ||
( a == 26 && b == 35 ) ||
( a == 27 && b == 41 ) ||
( a == 28 && b == 37 ) ||
( a == 29 && b == 32 ) ||
( a == 29 && b == 40 ) ||
( a == 30 && b == 43 ) ||
( a == 31 && b == 34 ) ||
( a == 31 && b == 38 ) ||
( a == 33 && b == 43 ) ||
( a == 35 && b == 42 ) ||
( a == 36 && b == 41 ) ||
( a == 37 && b == 39 ) )
return (4 - 5*Nc2 + Nc4)/(32.*Nc3);
if( ( a == 20 && b == 43 ) ||
( a == 21 && b == 37 ) ||
( a == 22 && b == 41 ) ||
( a == 23 && b == 31 ) ||
( a == 24 && b == 35 ) ||
( a == 25 && b == 29 ) ||
( a == 26 && b == 42 ) ||
( a == 27 && b == 36 ) ||
( a == 28 && b == 39 ) ||
( a == 30 && b == 33 ) ||
( a == 32 && b == 40 ) ||
( a == 34 && b == 38 ) )
return -(-1 + Nc4)/(8.*Nc3);
}
if ( basis == id33bar888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) )
return (2 - 3*Nc2 + Nc4)/8.;
if( a == 0 && b == 1 )
return (1 - Nc2)/4.;
if( ( a == 0 && b == 2 ) ||
( a == 0 && b == 3 ) ||
( a == 0 && b == 4 ) ||
( a == 1 && b == 2 ) ||
( a == 1 && b == 3 ) ||
( a == 1 && b == 4 ) )
return 0;
if( ( a == 0 && b == 5 ) ||
( a == 0 && b == 8 ) ||
( a == 0 && b == 9 ) ||
( a == 1 && b == 6 ) ||
( a == 1 && b == 7 ) ||
( a == 1 && b == 10 ) )
return (2 - 3*Nc2 + Nc4)/(8.*Nc);
if( ( a == 0 && b == 6 ) ||
( a == 0 && b == 7 ) ||
( a == 0 && b == 10 ) ||
( a == 1 && b == 5 ) ||
( a == 1 && b == 8 ) ||
( a == 1 && b == 9 ) )
return -(-1 + Nc2)/(4.*Nc);
if( ( a == 2 && b == 2 ) ||
( a == 3 && b == 3 ) ||
( a == 4 && b == 4 ) )
return sqr(-1 + Nc2)/8.;
if( ( a == 2 && b == 3 ) ||
( a == 2 && b == 4 ) ||
( a == 3 && b == 4 ) )
return (-1 + Nc2)/8.;
if( ( a == 2 && b == 5 ) ||
( a == 2 && b == 6 ) ||
( a == 2 && b == 8 ) ||
( a == 2 && b == 10 ) ||
( a == 3 && b == 6 ) ||
( a == 3 && b == 7 ) ||
( a == 3 && b == 8 ) ||
( a == 3 && b == 9 ) ||
( a == 4 && b == 5 ) ||
( a == 4 && b == 7 ) ||
( a == 4 && b == 9 ) ||
( a == 4 && b == 10 ) )
return sqr(-1 + Nc2)/(8.*Nc);
if( ( a == 2 && b == 7 ) ||
( a == 2 && b == 9 ) ||
( a == 3 && b == 5 ) ||
( a == 3 && b == 10 ) ||
( a == 4 && b == 6 ) ||
( a == 4 && b == 8 ) )
return -(-1 + Nc2)/(8.*Nc);
if( ( a == 5 && b == 5 ) ||
( a == 6 && b == 6 ) ||
( a == 7 && b == 7 ) ||
( a == 8 && b == 8 ) ||
( a == 9 && b == 9 ) ||
( a == 10 && b == 10 ) )
return pow(-1 + Nc2,3.)/(8.*Nc2);
if( ( a == 5 && b == 6 ) ||
( a == 5 && b == 7 ) ||
( a == 6 && b == 9 ) ||
( a == 7 && b == 8 ) ||
( a == 8 && b == 10 ) ||
( a == 9 && b == 10 ) )
return -sqr(-1 + Nc2)/(8.*Nc2);
if( ( a == 5 && b == 8 ) ||
( a == 5 && b == 9 ) ||
( a == 6 && b == 7 ) ||
( a == 6 && b == 10 ) ||
( a == 7 && b == 10 ) ||
( a == 8 && b == 9 ) )
return 0.125 - 1/(8.*Nc2);
if( ( a == 5 && b == 10 ) ||
( a == 6 && b == 8 ) ||
( a == 7 && b == 9 ) )
return (-1 + Nc4)/(8.*Nc2);
}
if ( basis == id33bar33bar8 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) ||
( a == 3 && b == 3 ) )
return (Nc*(-1 + Nc2))/2.;
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 3 ) ||
( a == 1 && b == 2 ) ||
( a == 2 && b == 3 ) )
return (-1 + Nc2)/2.;
if( ( a == 0 && b == 2 ) ||
( a == 1 && b == 3 ) )
return 0;
}
} else {
if ( a != b )
return 0.;
if ( basis == id88 ) {
return Nc2/4.;
}
if ( basis == id33bar ) {
return Nc;
}
if ( basis == id888 ) {
return Nc3/8.;
}
if ( basis == id33bar8 ) {
return Nc2/2.;
}
if ( basis == id8888 ) {
return Nc4/16.;
}
if ( basis == id33bar88 ) {
return Nc3/4.;
}
if ( basis == id33bar33bar ) {
return Nc2;
}
if ( basis == id88888 ) {
return Nc5/32.;
}
if ( basis == id33bar888 ) {
return Nc4/8.;
}
if ( basis == id33bar33bar8 ) {
return Nc3/2.;
}
}
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis2::scalarProduct(): Cannot handle colour configuration" << Exception::abortnow;
}
double SimpleColourBasis2::tMatrixElement(size_t i, size_t a,
size_t b,
const vector<PDT::Colour>&,
const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 ) {
if(i == 0 && a == 0 && b == 0) return -1;
if(i == 0 && a == 1 && b == 0) return 1;
if(i == 1 && a == 0 && b == 0) return 1;
if(i == 1 && a == 1 && b == 0) return -1;
return 0.;
}
if ( basis == id33bar ) {
if(i == 0 && a == 0 && b == 0) return 1;
if(i == 1 && a == 0 && b == 0) return -1;
return 0.;
}
if ( basis == id888 ) {
if(i == 0 && a == 3 && b == 0) return -1;
if(i == 0 && a == 5 && b == 1) return -1;
if(i == 0 && a == 7 && b == 0) return 1;
if(i == 0 && a == 8 && b == 1) return 1;
if(i == 1 && a == 4 && b == 0) return 1;
if(i == 1 && a == 5 && b == 1) return 1;
if(i == 1 && a == 6 && b == 1) return -1;
if(i == 1 && a == 7 && b == 0) return -1;
if(i == 2 && a == 3 && b == 0) return 1;
if(i == 2 && a == 4 && b == 0) return -1;
if(i == 2 && a == 6 && b == 1) return 1;
if(i == 2 && a == 8 && b == 1) return -1;
return 0.;
}
if ( basis == id33bar8 ) {
if(i == 0 && a == 2 && b == 0) return 1;
if(i == 1 && a == 1 && b == 0) return -1;
if(i == 2 && a == 1 && b == 0) return 1;
if(i == 2 && a == 2 && b == 0) return -1;
return 0.;
}
if ( basis == id8888 ) {
if(i == 0 && a == 2 && b == 2) return -1;
if(i == 0 && a == 5 && b == 1) return -1;
if(i == 0 && a == 8 && b == 0) return -1;
if(i == 0 && a == 9 && b == 2) return 1;
if(i == 0 && a == 10 && b == 1) return 1;
if(i == 0 && a == 11 && b == 0) return 1;
if(i == 0 && a == 20 && b == 3) return -1;
if(i == 0 && a == 22 && b == 4) return -1;
if(i == 0 && a == 26 && b == 5) return -1;
if(i == 0 && a == 28 && b == 6) return -1;
if(i == 0 && a == 32 && b == 7) return -1;
if(i == 0 && a == 34 && b == 8) return -1;
if(i == 0 && a == 38 && b == 3) return 1;
if(i == 0 && a == 39 && b == 4) return 1;
if(i == 0 && a == 40 && b == 5) return 1;
if(i == 0 && a == 41 && b == 6) return 1;
if(i == 0 && a == 42 && b == 7) return 1;
if(i == 0 && a == 43 && b == 8) return 1;
if(i == 1 && a == 2 && b == 2) return 1;
if(i == 1 && a == 9 && b == 2) return -1;
if(i == 1 && a == 13 && b == 0) return -1;
if(i == 1 && a == 15 && b == 1) return -1;
if(i == 1 && a == 16 && b == 0) return 1;
if(i == 1 && a == 17 && b == 1) return 1;
if(i == 1 && a == 24 && b == 3) return 1;
if(i == 1 && a == 25 && b == 4) return 1;
if(i == 1 && a == 27 && b == 5) return 1;
if(i == 1 && a == 28 && b == 6) return 1;
if(i == 1 && a == 29 && b == 6) return -1;
if(i == 1 && a == 30 && b == 5) return -1;
if(i == 1 && a == 33 && b == 7) return 1;
if(i == 1 && a == 34 && b == 8) return 1;
if(i == 1 && a == 35 && b == 8) return -1;
if(i == 1 && a == 36 && b == 7) return -1;
if(i == 1 && a == 38 && b == 3) return -1;
if(i == 1 && a == 39 && b == 4) return -1;
if(i == 2 && a == 5 && b == 1) return 1;
if(i == 2 && a == 10 && b == 1) return -1;
if(i == 2 && a == 13 && b == 0) return 1;
if(i == 2 && a == 16 && b == 0) return -1;
if(i == 2 && a == 18 && b == 2) return -1;
if(i == 2 && a == 19 && b == 2) return 1;
if(i == 2 && a == 21 && b == 3) return 1;
if(i == 2 && a == 22 && b == 4) return 1;
if(i == 2 && a == 23 && b == 4) return -1;
if(i == 2 && a == 24 && b == 3) return -1;
if(i == 2 && a == 30 && b == 5) return 1;
if(i == 2 && a == 31 && b == 6) return 1;
if(i == 2 && a == 32 && b == 7) return 1;
if(i == 2 && a == 33 && b == 7) return -1;
if(i == 2 && a == 35 && b == 8) return 1;
if(i == 2 && a == 37 && b == 8) return -1;
if(i == 2 && a == 40 && b == 5) return -1;
if(i == 2 && a == 41 && b == 6) return -1;
if(i == 3 && a == 8 && b == 0) return 1;
if(i == 3 && a == 11 && b == 0) return -1;
if(i == 3 && a == 15 && b == 1) return 1;
if(i == 3 && a == 17 && b == 1) return -1;
if(i == 3 && a == 18 && b == 2) return 1;
if(i == 3 && a == 19 && b == 2) return -1;
if(i == 3 && a == 20 && b == 3) return 1;
if(i == 3 && a == 21 && b == 3) return -1;
if(i == 3 && a == 23 && b == 4) return 1;
if(i == 3 && a == 25 && b == 4) return -1;
if(i == 3 && a == 26 && b == 5) return 1;
if(i == 3 && a == 27 && b == 5) return -1;
if(i == 3 && a == 29 && b == 6) return 1;
if(i == 3 && a == 31 && b == 6) return -1;
if(i == 3 && a == 36 && b == 7) return 1;
if(i == 3 && a == 37 && b == 8) return 1;
if(i == 3 && a == 42 && b == 7) return -1;
if(i == 3 && a == 43 && b == 8) return -1;
return 0.;
}
if ( basis == id33bar88 ) {
if(i == 0 && a == 4 && b == 0) return 1;
if(i == 0 && a == 9 && b == 1) return 1;
if(i == 0 && a == 10 && b == 2) return 1;
if(i == 1 && a == 4 && b == 0) return -1;
if(i == 1 && a == 5 && b == 1) return -1;
if(i == 1 && a == 7 && b == 2) return -1;
if(i == 2 && a == 0 && b == 0) return -1;
if(i == 2 && a == 1 && b == 0) return 1;
if(i == 2 && a == 6 && b == 1) return 1;
if(i == 2 && a == 7 && b == 2) return 1;
if(i == 2 && a == 8 && b == 2) return -1;
if(i == 2 && a == 9 && b == 1) return -1;
if(i == 3 && a == 0 && b == 0) return 1;
if(i == 3 && a == 1 && b == 0) return -1;
if(i == 3 && a == 5 && b == 1) return 1;
if(i == 3 && a == 6 && b == 1) return -1;
if(i == 3 && a == 8 && b == 2) return 1;
if(i == 3 && a == 10 && b == 2) return -1;
return 0.;
}
if ( basis == id33bar33bar ) {
if(i == 0 && a == 0 && b == 0) return 1;
if(i == 0 && a == 1 && b == 1) return 1;
if(i == 1 && a == 1 && b == 1) return -1;
if(i == 1 && a == 2 && b == 0) return -1;
if(i == 2 && a == 2 && b == 0) return 1;
if(i == 2 && a == 3 && b == 1) return 1;
if(i == 3 && a == 0 && b == 0) return -1;
if(i == 3 && a == 3 && b == 1) return -1;
return 0.;
}
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis2::tMatrixElement(): Cannot handle colour configuration" << Exception::abortnow;
return 0.;
}
bool SimpleColourBasis2::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
if ( id33bar.empty() )
makeIds();
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
if ( basis == id88 ) {
return
a == 0 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0));
}
if ( basis == id33bar ) {
return
a == 0 &&
(idColoured == 0 && idAntiColoured == 1);
}
if ( basis == id888 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar8 ) {
return
a == 0 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1));
}
if ( basis == id8888 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2))) ||
(a == 3 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 4 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 5 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 6 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 7 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 8 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar88 ) {
return
(a == 0 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 2)));
}
if ( basis == id33bar33bar ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3)));
}
if ( basis == id88888 ) {
return
(a == 0 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 1 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 2 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 3 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 4 &&
((idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 5 &&
((idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 6 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 7 &&
((idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 8 &&
((idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 9 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 10 &&
((idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 11 &&
((idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 12 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 13 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 14 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 15 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 16 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 17 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 18 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2))) ||
(a == 19 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2))) ||
(a == 20 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 21 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 22 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 23 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 24 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 25 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 26 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 27 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 28 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 29 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 30 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 31 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 32 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 33 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 34 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 35 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 36 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 37 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 38 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 39 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 40 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 41 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 42 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 43 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar888 ) {
return
(a == 0 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 2 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 3 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 4 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 5 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4))) ||
(a == 6 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3))) ||
(a == 7 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4))) ||
(a == 8 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2))) ||
(a == 9 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 10 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2)));
}
if ( basis == id33bar33bar8 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 3 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3)));
}
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis2::colourConnected(): Cannot handle colour configuration" << Exception::abortnow;
return false;
}
map<size_t,vector<vector<size_t> > > SimpleColourBasis2::basisList(const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
map<size_t,vector<vector<size_t> > > blist;
vector<vector<size_t> > structures;
vector<size_t> structure;
if ( basis == id88 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id33bar ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id888 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
return blist;
}
if ( basis == id33bar8 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id8888 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[8] = structures;
return blist;
}
if ( basis == id33bar88 ) {
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
return blist;
}
if ( basis == id33bar33bar ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
return blist;
}
if ( basis == id88888 ) {
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[8] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[9] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[10] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[11] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[12] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[13] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[14] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[15] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[16] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[17] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[18] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[19] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[20] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[21] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[22] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[23] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[24] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[25] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[26] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[27] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[28] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[29] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[30] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[31] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[32] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[33] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[34] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[35] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[36] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[37] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[38] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[39] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[40] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[41] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[42] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[43] = structures;
return blist;
}
if ( basis == id33bar888 ) {
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[8] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[9] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[10] = structures;
return blist;
}
if ( basis == id33bar33bar8 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[3] = structures;
return blist;
}
- throw Exception() << "Cannot handle colour configuration" << Exception::abortnow;
+ throw Exception() << "SimpleColourBasis2::basisList(): Cannot handle colour configuration" << Exception::abortnow;
return blist;
}
void SimpleColourBasis2::makeIds() const {
id88 = vector<PDT::Colour>(2,PDT::Colour8);
id33bar.push_back(PDT::Colour3);
id33bar.push_back(PDT::Colour3bar);
id888 = vector<PDT::Colour>(3,PDT::Colour8);
id33bar8 = id33bar;
id33bar8.push_back(PDT::Colour8);
id8888 = vector<PDT::Colour>(4,PDT::Colour8);
id33bar88 = id33bar8;
id33bar88.push_back(PDT::Colour8);
id33bar33bar = id33bar;
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
id88888 = vector<PDT::Colour>(5,PDT::Colour8);
id33bar888 = id33bar88;
id33bar888.push_back(PDT::Colour8);
id33bar33bar8 = id33bar33bar;
id33bar33bar8.push_back(PDT::Colour8);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void SimpleColourBasis2::persistentOutput(PersistentOStream &) const {}
void SimpleColourBasis2::persistentInput(PersistentIStream &, int) {}
// *** 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<SimpleColourBasis2,ColourBasis>
describeHerwigSimpleColourBasis2("Herwig::SimpleColourBasis2", "Herwig.so");
void SimpleColourBasis2::Init() {
static ClassDocumentation<SimpleColourBasis2> documentation
("SimpleColourBasis2 implements the colour algebra needed for "
"processes with four coloured legs at NLO. It mainly "
"serves as an example for the general ColourBasis interface.");
}
diff --git a/src/defaults/Cuts.in b/src/defaults/Cuts.in
--- a/src/defaults/Cuts.in
+++ b/src/defaults/Cuts.in
@@ -1,122 +1,123 @@
###########################################################
# Default cuts (applied to the hard subprocess)
#
# Don't change values here, re-set them in your own input
# files using these as examples.
###########################################################
mkdir /Herwig/Matchers
cd /Herwig/Matchers
create ThePEG::Matcher<Lepton> Lepton
+create ThePEG::Matcher<Neutrino> Neutrino
create ThePEG::Matcher<ChargedLepton> ChargedLepton
create ThePEG::Matcher<LightQuark> LightQuark
create ThePEG::Matcher<LightAntiQuark> LightAntiQuark
create ThePEG::Matcher<StandardQCDParton> StandardQCDParton
create ThePEG::Matcher<Photon> Photon
create ThePEG::Matcher<Top> Top
create ThePEG::Matcher<WBoson> WBoson
create ThePEG::Matcher<ZBoson> ZBoson
create ThePEG::Matcher<HiggsBoson> HiggsBoson
mkdir /Herwig/Cuts
cd /Herwig/Cuts
# create the cuts object for e+e-
create ThePEG::Cuts EECuts
newdef EECuts:MHatMin 22.36*GeV
# create the cuts object for hadron collisions
create ThePEG::Cuts QCDCuts
newdef QCDCuts:ScaleMin 2.0*GeV
newdef QCDCuts:X1Min 1.0e-5
newdef QCDCuts:X2Min 1.0e-5
newdef QCDCuts:MHatMin 20.*GeV
# cut on jet pt
create ThePEG::SimpleKTCut JetKtCut SimpleKTCut.so
newdef JetKtCut:Matcher /Herwig/Matchers/StandardQCDParton
newdef JetKtCut:MinKT 20.0*GeV
# cut on photon
create ThePEG::SimpleKTCut PhotonKtCut SimpleKTCut.so
newdef PhotonKtCut:Matcher /Herwig/Matchers/Photon
newdef PhotonKtCut:MinKT 20.0*GeV
newdef PhotonKtCut:MinEta -3.
newdef PhotonKtCut:MaxEta 3.
# cut on leptons
create ThePEG::SimpleKTCut LeptonKtCut SimpleKTCut.so
newdef LeptonKtCut:Matcher /Herwig/Matchers/Lepton
newdef LeptonKtCut:MinKT 0.0*GeV
# cut on charged leptons
create ThePEG::SimpleKTCut ChargedLeptonKtCut SimpleKTCut.so
newdef ChargedLeptonKtCut:Matcher /Herwig/Matchers/ChargedLepton
newdef ChargedLeptonKtCut:MinKT 0.0*GeV
# cut on top quarks
create ThePEG::KTRapidityCut TopKtCut KTRapidityCut.so
newdef TopKtCut:Matcher /Herwig/Matchers/Top
newdef TopKtCut:MinKT 0.0*GeV
# cut on W bosons
create ThePEG::KTRapidityCut WBosonKtCut KTRapidityCut.so
newdef WBosonKtCut:Matcher /Herwig/Matchers/WBoson
newdef WBosonKtCut:MinKT 0.0*GeV
# cut on Z bosons
create ThePEG::KTRapidityCut ZBosonKtCut KTRapidityCut.so
newdef ZBosonKtCut:Matcher /Herwig/Matchers/ZBoson
newdef ZBosonKtCut:MinKT 0.0*GeV
# cut on Higgs bosons
create ThePEG::KTRapidityCut HiggsBosonKtCut KTRapidityCut.so
newdef HiggsBosonKtCut:Matcher /Herwig/Matchers/HiggsBoson
newdef HiggsBosonKtCut:MinKT 0.0*GeV
# create a cut on the invariant mass of lepton pairs
create ThePEG::V2LeptonsCut MassCut V2LeptonsCut.so
newdef MassCut:Families All
newdef MassCut:CComb All
newdef MassCut:MinM 20.*GeV
newdef MassCut:MaxM 14000.*GeV
# create a cut on Q^2 for neutral current DIS
create ThePEG::SimpleDISCut NeutralCurrentCut SimpleDISCut.so
newdef NeutralCurrentCut:MinQ2 20.
newdef NeutralCurrentCut:Current Neutral
# create a cut on Q^2 for charged current DIS
create ThePEG::SimpleDISCut ChargedCurrentCut SimpleDISCut.so
newdef ChargedCurrentCut:MinQ2 20.
newdef ChargedCurrentCut:Current Charged
# create a cut of Q^2 for charged current DIS
# insert into hadron cuts
insert QCDCuts:OneCuts[0] JetKtCut
insert QCDCuts:OneCuts[1] PhotonKtCut
insert QCDCuts:OneCuts[2] LeptonKtCut
insert QCDCuts:OneCuts[3] TopKtCut
insert QCDCuts:OneCuts[4] WBosonKtCut
insert QCDCuts:OneCuts[5] ZBosonKtCut
insert QCDCuts:OneCuts[6] HiggsBosonKtCut
insert QCDCuts:OneCuts[7] ChargedLeptonKtCut
insert QCDCuts:MultiCuts[0] MassCut
# cuts for DIS
create ThePEG::Cuts DISCuts
newdef DISCuts:ScaleMin 1.0*GeV
newdef DISCuts:X1Min 1.0e-5
newdef DISCuts:X2Min 1.0e-5
insert DISCuts:TwoCuts[0] NeutralCurrentCut
insert DISCuts:TwoCuts[1] ChargedCurrentCut
# create diffrent cuts object for MinBias to avoid numerical problems
create ThePEG::Cuts MinBiasCuts
newdef MinBiasCuts:ScaleMin 2.0*GeV
newdef MinBiasCuts:X1Min 0.055
newdef MinBiasCuts:X2Min 0.055
newdef MinBiasCuts:MHatMin 0.0*GeV
diff --git a/src/defaults/MatchboxDefaults.in.in b/src/defaults/MatchboxDefaults.in.in
--- a/src/defaults/MatchboxDefaults.in.in
+++ b/src/defaults/MatchboxDefaults.in.in
@@ -1,740 +1,782 @@
################################################################################
#
# Default setup for Matchbox matrix element generation.
# You do not need to make any change in here; processes of
# interest can be chosen in the standard input files.
#
################################################################################
################################################################################
# Load libraries
################################################################################
library JetCuts.so
library FastJetFinder.so
library HwMatchboxScales.so
library HwMatchboxCuts.so
library HwSampling.so
library HwColorFull.so
library HwMatchboxBuiltin.so
################################################################################
# Integration/sampling
################################################################################
mkdir /Herwig/Samplers
cd /Herwig/Samplers
create Herwig::BinSampler FlatBinSampler
set FlatBinSampler:InitialPoints 1000
set FlatBinSampler:UseAllIterations No
create Herwig::CellGridSampler CellGridSampler
set CellGridSampler:InitialPoints 10000
set CellGridSampler:ExplorationPoints 500
set CellGridSampler:ExplorationSteps 4
set CellGridSampler:Gain 0.3
set CellGridSampler:Epsilon 1.0
set CellGridSampler:MinimumSelection 0.000001
set CellGridSampler:NIterations 1
set CellGridSampler:EnhancementFactor 1
set CellGridSampler:UseAllIterations No
set CellGridSampler:RemapperPoints 50000
set CellGridSampler:RemapperMinSelection 0.00001
set CellGridSampler:RemapChannelDimension Yes
set CellGridSampler:LuminosityMapperBins 20
set CellGridSampler:GeneralMapperBins 0
create Herwig::GeneralSampler Sampler
set Sampler:UpdateAfter 1000
set Sampler:BinSampler CellGridSampler
set Sampler:AddUpSamplers Off
set Sampler:GlobalMaximumWeight Off
set Sampler:FlatSubprocesses Off
set Sampler:MinSelection 0.000001
set Sampler:AlmostUnweighted Off
set Sampler:RunCombinationData Off
set Sampler:WriteGridsOnFinish No
################################################################################
# Setup the factory object
################################################################################
mkdir /Herwig/MatrixElements/Matchbox
cd /Herwig/MatrixElements/Matchbox
create Herwig::MatchboxFactory Factory
do Factory:StartParticleGroup p
insert Factory:ParticleGroup 0 /Herwig/Particles/b
insert Factory:ParticleGroup 0 /Herwig/Particles/bbar
insert Factory:ParticleGroup 0 /Herwig/Particles/c
insert Factory:ParticleGroup 0 /Herwig/Particles/cbar
insert Factory:ParticleGroup 0 /Herwig/Particles/s
insert Factory:ParticleGroup 0 /Herwig/Particles/sbar
insert Factory:ParticleGroup 0 /Herwig/Particles/d
insert Factory:ParticleGroup 0 /Herwig/Particles/dbar
insert Factory:ParticleGroup 0 /Herwig/Particles/u
insert Factory:ParticleGroup 0 /Herwig/Particles/ubar
insert Factory:ParticleGroup 0 /Herwig/Particles/g
do Factory:EndParticleGroup
do Factory:StartParticleGroup pbar
insert Factory:ParticleGroup 0 /Herwig/Particles/b
insert Factory:ParticleGroup 0 /Herwig/Particles/bbar
insert Factory:ParticleGroup 0 /Herwig/Particles/c
insert Factory:ParticleGroup 0 /Herwig/Particles/cbar
insert Factory:ParticleGroup 0 /Herwig/Particles/s
insert Factory:ParticleGroup 0 /Herwig/Particles/sbar
insert Factory:ParticleGroup 0 /Herwig/Particles/d
insert Factory:ParticleGroup 0 /Herwig/Particles/dbar
insert Factory:ParticleGroup 0 /Herwig/Particles/u
insert Factory:ParticleGroup 0 /Herwig/Particles/ubar
insert Factory:ParticleGroup 0 /Herwig/Particles/g
do Factory:EndParticleGroup
do Factory:StartParticleGroup j
insert Factory:ParticleGroup 0 /Herwig/Particles/b
insert Factory:ParticleGroup 0 /Herwig/Particles/bbar
insert Factory:ParticleGroup 0 /Herwig/Particles/c
insert Factory:ParticleGroup 0 /Herwig/Particles/cbar
insert Factory:ParticleGroup 0 /Herwig/Particles/s
insert Factory:ParticleGroup 0 /Herwig/Particles/sbar
insert Factory:ParticleGroup 0 /Herwig/Particles/d
insert Factory:ParticleGroup 0 /Herwig/Particles/dbar
insert Factory:ParticleGroup 0 /Herwig/Particles/u
insert Factory:ParticleGroup 0 /Herwig/Particles/ubar
insert Factory:ParticleGroup 0 /Herwig/Particles/g
do Factory:EndParticleGroup
do Factory:StartParticleGroup u
insert Factory:ParticleGroup 0 /Herwig/Particles/u
do Factory:EndParticleGroup
do Factory:StartParticleGroup ubar
insert Factory:ParticleGroup 0 /Herwig/Particles/ubar
do Factory:EndParticleGroup
do Factory:StartParticleGroup d
insert Factory:ParticleGroup 0 /Herwig/Particles/d
do Factory:EndParticleGroup
do Factory:StartParticleGroup dbar
insert Factory:ParticleGroup 0 /Herwig/Particles/dbar
do Factory:EndParticleGroup
do Factory:StartParticleGroup s
insert Factory:ParticleGroup 0 /Herwig/Particles/s
do Factory:EndParticleGroup
do Factory:StartParticleGroup sbar
insert Factory:ParticleGroup 0 /Herwig/Particles/sbar
do Factory:EndParticleGroup
do Factory:StartParticleGroup c
insert Factory:ParticleGroup 0 /Herwig/Particles/c
do Factory:EndParticleGroup
do Factory:StartParticleGroup cbar
insert Factory:ParticleGroup 0 /Herwig/Particles/cbar
do Factory:EndParticleGroup
do Factory:StartParticleGroup b
insert Factory:ParticleGroup 0 /Herwig/Particles/b
do Factory:EndParticleGroup
do Factory:StartParticleGroup bbar
insert Factory:ParticleGroup 0 /Herwig/Particles/bbar
do Factory:EndParticleGroup
do Factory:StartParticleGroup t
insert Factory:ParticleGroup 0 /Herwig/Particles/t
do Factory:EndParticleGroup
do Factory:StartParticleGroup tbar
insert Factory:ParticleGroup 0 /Herwig/Particles/tbar
do Factory:EndParticleGroup
do Factory:StartParticleGroup g
insert Factory:ParticleGroup 0 /Herwig/Particles/g
do Factory:EndParticleGroup
do Factory:StartParticleGroup gamma
insert Factory:ParticleGroup 0 /Herwig/Particles/gamma
do Factory:EndParticleGroup
do Factory:StartParticleGroup h0
insert Factory:ParticleGroup 0 /Herwig/Particles/h0
do Factory:EndParticleGroup
do Factory:StartParticleGroup W+
insert Factory:ParticleGroup 0 /Herwig/Particles/W+
do Factory:EndParticleGroup
do Factory:StartParticleGroup W-
insert Factory:ParticleGroup 0 /Herwig/Particles/W-
do Factory:EndParticleGroup
do Factory:StartParticleGroup Z0
insert Factory:ParticleGroup 0 /Herwig/Particles/Z0
do Factory:EndParticleGroup
do Factory:StartParticleGroup e+
insert Factory:ParticleGroup 0 /Herwig/Particles/e+
do Factory:EndParticleGroup
do Factory:StartParticleGroup e-
insert Factory:ParticleGroup 0 /Herwig/Particles/e-
do Factory:EndParticleGroup
do Factory:StartParticleGroup mu+
insert Factory:ParticleGroup 0 /Herwig/Particles/mu+
do Factory:EndParticleGroup
do Factory:StartParticleGroup mu-
insert Factory:ParticleGroup 0 /Herwig/Particles/mu-
do Factory:EndParticleGroup
do Factory:StartParticleGroup tau+
insert Factory:ParticleGroup 0 /Herwig/Particles/tau+
do Factory:EndParticleGroup
do Factory:StartParticleGroup tau-
insert Factory:ParticleGroup 0 /Herwig/Particles/tau-
do Factory:EndParticleGroup
do Factory:StartParticleGroup nu_e
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_e
do Factory:EndParticleGroup
do Factory:StartParticleGroup nu_mu
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_mu
do Factory:EndParticleGroup
do Factory:StartParticleGroup nu_tau
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_tau
do Factory:EndParticleGroup
do Factory:StartParticleGroup nu_ebar
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_ebar
do Factory:EndParticleGroup
do Factory:StartParticleGroup nu_mubar
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_mubar
do Factory:EndParticleGroup
do Factory:StartParticleGroup nu_taubar
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_taubar
do Factory:EndParticleGroup
do Factory:StartParticleGroup l
insert Factory:ParticleGroup 0 /Herwig/Particles/e+
insert Factory:ParticleGroup 0 /Herwig/Particles/mu+
insert Factory:ParticleGroup 0 /Herwig/Particles/e-
insert Factory:ParticleGroup 0 /Herwig/Particles/mu-
do Factory:EndParticleGroup
do Factory:StartParticleGroup nu
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_e
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_mu
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_ebar
insert Factory:ParticleGroup 0 /Herwig/Particles/nu_mubar
do Factory:EndParticleGroup
do Factory:StartParticleGroup l+
insert Factory:ParticleGroup 0 /Herwig/Particles/e+
insert Factory:ParticleGroup 0 /Herwig/Particles/mu+
do Factory:EndParticleGroup
do Factory:StartParticleGroup l-
insert Factory:ParticleGroup 0 /Herwig/Particles/e-
insert Factory:ParticleGroup 0 /Herwig/Particles/mu-
do Factory:EndParticleGroup
################################################################################
# Setup amplitudes
################################################################################
cd /Herwig/MatrixElements/Matchbox
mkdir Amplitudes
cd Amplitudes
create ColorFull::TraceBasis TraceBasis
create Herwig::MatchboxHybridAmplitude GenericProcesses
@LOAD_MADGRAPH@ HwMatchboxMadGraph.so
@CREATE_MADGRAPH@ Herwig::MadGraphAmplitude MadGraph
@SET_MADGRAPH@ MadGraph:ColourBasis TraceBasis
@LOAD_GOSAM@ HwMatchboxGoSam.so
@CREATE_GOSAM@ Herwig::GoSamAmplitude GoSam
@LOAD_NJET@ HwMatchboxNJet.so
@CREATE_NJET@ Herwig::NJetsAmplitude NJet
@DO_NJET@ NJet:Massless 5
@DO_NJET@ NJet:Massless -5
@LOAD_OPENLOOPS@ HwMatchboxOpenLoops.so
@CREATE_OPENLOOPS@ Herwig::OpenLoopsAmplitude OpenLoops
@LOAD_VBFNLO@ HwMatchboxVBFNLO.so
@CREATE_VBFNLO@ Herwig::VBFNLOAmplitude VBFNLO
mkdir Builtin
cd Builtin
create Herwig::SimpleColourBasis SimpleColourBasis
create Herwig::SimpleColourBasis2 SimpleColourBasis2
create Herwig::MatchboxAmplitudellbarqqbar Amplitudellbarqqbar
set Amplitudellbarqqbar:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudellbarqqbarg Amplitudellbarqqbarg
set Amplitudellbarqqbarg:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudellbarqqbargg Amplitudellbarqqbargg
set Amplitudellbarqqbargg:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudellbarqqbarqqbar Amplitudellbarqqbarqqbar
set Amplitudellbarqqbarqqbar:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudelnuqqbar Amplitudelnuqqbar
set Amplitudelnuqqbar:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudelnuqqbarg Amplitudelnuqqbarg
set Amplitudelnuqqbarg:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudelnuqqbargg Amplitudelnuqqbargg
set Amplitudelnuqqbargg:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudelnuqqbarqqbar Amplitudelnuqqbarqqbar
set Amplitudelnuqqbarqqbar:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudehgg Amplitudehgg
set Amplitudehgg:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudehggg Amplitudehggg
set Amplitudehggg:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudehqqbarg Amplitudehqqbarg
set Amplitudehqqbarg:ColourBasis SimpleColourBasis
create Herwig::MatchboxAmplitudeqqbarttbar Amplitudeqqbarttbar
set Amplitudeqqbarttbar:ColourBasis SimpleColourBasis2
create Herwig::MatchboxAmplitudeqqbarttbarg Amplitudeqqbarttbarg
set Amplitudeqqbarttbarg:ColourBasis SimpleColourBasis2
create Herwig::MatchboxAmplitudeggttbar Amplitudeggttbar
set Amplitudeggttbar:ColourBasis SimpleColourBasis2
create Herwig::MatchboxAmplitudeggttbarg Amplitudeggttbarg
set Amplitudeggttbarg:ColourBasis SimpleColourBasis2
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudellbarqqbar
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudellbarqqbarg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudellbarqqbargg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudellbarqqbarqqbar
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudelnuqqbar
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudelnuqqbarg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudelnuqqbargg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudelnuqqbarqqbar
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudehgg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudehggg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudehqqbarg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudeqqbarttbar
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudeqqbarttbarg
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudeggttbar
insert /Herwig/MatrixElements/Matchbox/Factory:Amplitudes 0 Amplitudeggttbarg
################################################################################
# Setup phasespace generators
################################################################################
cd /Herwig/MatrixElements/Matchbox
mkdir Phasespace
cd Phasespace
create Herwig::PhasespaceCouplings PhasespaceCouplings
create Herwig::MatchboxRambo Rambo
set Rambo:CouplingData PhasespaceCouplings
create Herwig::FlatInvertiblePhasespace InvertiblePhasespace
set InvertiblePhasespace:CouplingData PhasespaceCouplings
create Herwig::TreePhasespaceChannels TreePhasespaceChannels
create Herwig::TreePhasespace TreePhasespace
set TreePhasespace:ChannelMap TreePhasespaceChannels
set TreePhasespace:M0 0.0001*GeV
set TreePhasespace:MC 0.000001*GeV
set TreePhasespace:CouplingData PhasespaceCouplings
do TreePhasespace:SetPhysicalCoupling 21 -1 1 0.059
do TreePhasespace:SetPhysicalCoupling 21 -2 2 0.059
do TreePhasespace:SetPhysicalCoupling 21 -3 3 0.059
do TreePhasespace:SetPhysicalCoupling 21 -4 4 0.059
do TreePhasespace:SetPhysicalCoupling 21 -5 5 0.059
do TreePhasespace:SetPhysicalCoupling 21 -6 6 0.059
do TreePhasespace:SetPhysicalCoupling 21 1 -1 0.059
do TreePhasespace:SetPhysicalCoupling 21 2 -2 0.059
do TreePhasespace:SetPhysicalCoupling 21 3 -3 0.059
do TreePhasespace:SetPhysicalCoupling 21 4 -4 0.059
do TreePhasespace:SetPhysicalCoupling 21 5 -5 0.059
do TreePhasespace:SetPhysicalCoupling 21 6 -6 0.059
do TreePhasespace:SetPhysicalCoupling 1 21 1 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 2 21 2 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 3 21 3 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 4 21 4 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 5 21 5 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 6 21 6 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -1 21 -1 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -2 21 -2 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -3 21 -3 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -4 21 -4 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -5 21 -5 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -6 21 -6 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 1 1 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 2 2 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 3 3 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 4 4 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 5 5 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling 6 6 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -1 -1 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -2 -2 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -3 -3 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -4 -4 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -5 -5 21 0.15733333333333333333
do TreePhasespace:SetPhysicalCoupling -6 -6 21 0.15733333333333333333
do TreePhasespace:SetCoupling 25 -1 1 0
do TreePhasespace:SetCoupling 25 -2 2 0
do TreePhasespace:SetCoupling 25 -3 3 0.00000001184279069851
do TreePhasespace:SetCoupling 25 -4 4 0.00000205034465001885
do TreePhasespace:SetCoupling 25 -5 5 0.00002314757096085280
do TreePhasespace:SetCoupling 25 -6 6 0.03982017320025470767
do TreePhasespace:SetCoupling 25 -11 11 0.00000000000034264835
do TreePhasespace:SetCoupling 25 -12 12 0
do TreePhasespace:SetCoupling 25 -13 13 0.00000001464912263400
do TreePhasespace:SetCoupling 25 -14 14 0
do TreePhasespace:SetCoupling 25 -15 15 0.00000414359033108195
do TreePhasespace:SetCoupling 25 -16 16 0
do TreePhasespace:SetCoupling 22 -1 1 0.00083932358497608365
do TreePhasespace:SetCoupling 22 -2 2 0.00335729433990433461
do TreePhasespace:SetCoupling 22 -3 3 0.00083932358497608365
do TreePhasespace:SetCoupling 22 -4 4 0.00335729433990433461
do TreePhasespace:SetCoupling 22 -5 5 0.00083932358497608365
do TreePhasespace:SetCoupling 22 -6 6 0.00335729433990433461
do TreePhasespace:SetCoupling 22 -11 11 0.00755391226478475287
do TreePhasespace:SetCoupling 22 -13 13 0.00755391226478475287
do TreePhasespace:SetCoupling 22 -15 15 0.00755391226478475287
do TreePhasespace:SetCoupling 24 -2 1 0.01652748072644379386
do TreePhasespace:SetCoupling 24 -4 1 0.00382028458188709739
do TreePhasespace:SetCoupling 24 -6 1 0.00014707756360995175
do TreePhasespace:SetCoupling 24 -2 3 0.00382265953677814621
do TreePhasespace:SetCoupling 24 -4 3 0.01651340063673257587
do TreePhasespace:SetCoupling 24 -6 3 0.00068534412570265868
do TreePhasespace:SetCoupling 24 -2 5 0.00005954351191129535
do TreePhasespace:SetCoupling 24 -4 5 0.00069891529650865192
do TreePhasespace:SetCoupling 24 -6 5 0.01694947628265615369
do TreePhasespace:SetCoupling 24 -12 11 0.01696396350749155147
do TreePhasespace:SetCoupling 24 -14 13 0.01696396350749155147
do TreePhasespace:SetCoupling 24 -16 15 0.01696396350749155147
do TreePhasespace:SetCoupling -24 2 -1 0.01652748072644379386
do TreePhasespace:SetCoupling -24 4 -1 0.00382028458188709739
do TreePhasespace:SetCoupling -24 6 -1 0.00014707756360995175
do TreePhasespace:SetCoupling -24 2 -3 0.00382265953677814621
do TreePhasespace:SetCoupling -24 4 -3 0.01651340063673257587
do TreePhasespace:SetCoupling -24 6 -3 0.00068534412570265868
do TreePhasespace:SetCoupling -24 2 -5 0.00005954351191129535
do TreePhasespace:SetCoupling -24 4 -5 0.00069891529650865192
do TreePhasespace:SetCoupling -24 6 -5 0.01694947628265615369
do TreePhasespace:SetCoupling -24 12 -11 0.01696396350749155147
do TreePhasespace:SetCoupling -24 14 -13 0.01696396350749155147
do TreePhasespace:SetCoupling -24 16 -15 0.01696396350749155147
do TreePhasespace:SetCoupling 23 -1 1 0.00407649129960709158
do TreePhasespace:SetCoupling 23 -2 2 0.00317809816318353030
do TreePhasespace:SetCoupling 23 -3 3 0.00407649129960709158
do TreePhasespace:SetCoupling 23 -4 4 0.00317809816318353030
do TreePhasespace:SetCoupling 23 -5 5 0.00407649129960709158
do TreePhasespace:SetCoupling 23 -6 6 0.00317809816318353030
do TreePhasespace:SetCoupling 23 -11 11 0.00276049468148072129
do TreePhasespace:SetCoupling 23 -12 12 0.00545567409075140513
do TreePhasespace:SetCoupling 23 -13 13 0.00276049468148072129
do TreePhasespace:SetCoupling 23 -14 14 0.00545567409075140513
do TreePhasespace:SetCoupling 23 -15 15 0.00276049468148072129
do TreePhasespace:SetCoupling 23 -16 16 0.00545567409075140513
do TreePhasespace:SetCoupling 21 21 21 0.354
do TreePhasespace:SetCoupling 25 21 21 0.00000000016160437564
do TreePhasespace:SetCoupling 25 25 25 0.18719783125611995353
do TreePhasespace:SetCoupling 25 22 22 0.00000000006295673620
do TreePhasespace:SetCoupling 25 24 -24 219.30463760755686425818
do TreePhasespace:SetCoupling 25 23 23 362.91922658249853887524
do TreePhasespace:SetCoupling 22 24 -24 0.00755391226478475287
do TreePhasespace:SetCoupling 23 24 -24 0.02637401475019835008
@CREATE_VBFNLO@ Herwig::VBFNLOPhasespace VBFNLOPhasespace
@SET_VBFNLO@ VBFNLOPhasespace:CouplingData PhasespaceCouplings
set /Herwig/MatrixElements/Matchbox/Factory:Phasespace TreePhasespace
################################################################################
# Setup utilities for matching
################################################################################
cd /Herwig/MatrixElements/Matchbox
create Herwig::MEMatching MEMatching
set MEMatching:RestrictPhasespace On
set MEMatching:BornScaleInSubtraction BornScale
set MEMatching:RealEmissionScaleInSubtraction RealScale
set MEMatching:EmissionScaleInSubtraction RealScale
set MEMatching:BornScaleInSplitting ShowerScale
set MEMatching:RealEmissionScaleInSplitting ShowerScale
set MEMatching:EmissionScaleInSplitting ShowerScale
set MEMatching:TruncatedShower Yes
set MEMatching:MaxPtIsMuF Yes
set MEMatching:FFPtCut 1.0*GeV
set MEMatching:FIPtCut 1.0*GeV
set MEMatching:IIPtCut 1.0*GeV
create Herwig::ShowerApproximationGenerator MECorrectionHandler
set MECorrectionHandler:ShowerApproximation MEMatching
set MECorrectionHandler:Phasespace /Herwig/MatrixElements/Matchbox/Phasespace/InvertiblePhasespace
set MECorrectionHandler:FreezeGrid 100000
create Herwig::DipoleMatching DipoleMatching HwDipoleMatching.so
set DipoleMatching:RestrictPhasespace On
set DipoleMatching:BornScaleInSubtraction BornScale
set DipoleMatching:RealEmissionScaleInSubtraction BornScale
set DipoleMatching:EmissionScaleInSubtraction BornScale
set DipoleMatching:MaxPtIsMuF Yes
set DipoleMatching:FFPtCut 1.014259*GeV
set DipoleMatching:FIPtCut 1.0*GeV
set DipoleMatching:IIPtCut 1.0*GeV
create Herwig::QTildeMatching QTildeMatching HwQTildeMatching.so
set QTildeMatching:ShowerHandler /Herwig/Shower/ShowerHandler
# set this to off, if the shower pt veto is off
set QTildeMatching:RestrictPhasespace On
set QTildeMatching:BornScaleInSubtraction BornScale
set QTildeMatching:RealEmissionScaleInSubtraction BornScale
set QTildeMatching:EmissionScaleInSubtraction BornScale
set QTildeMatching:QTildeFinder /Herwig/Shower/PartnerFinder
set QTildeMatching:MaxPtIsMuF Yes
# just a dummy, since SudakovCommonn can't be used
# it's only used to get the value of the kinCutoffScale
set QTildeMatching:QTildeSudakov /Herwig/Shower/QtoQGSudakov
################################################################################
# Setup utilities for process generation
################################################################################
cd /Herwig/MatrixElements/Matchbox
mkdir Utility
cd Utility
create Herwig::Tree2toNGenerator DiagramGenerator
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/FFGVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/GGGVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/FFPVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/FFZVertex
cp /Herwig/Vertices/FFWVertex /Herwig/Vertices/FFWDiagonalVertex
set /Herwig/Vertices/FFWDiagonalVertex:Diagonal Yes
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/FFWDiagonalVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/WWHVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/WWWVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/FFHVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/HGGVertex
insert DiagramGenerator:Vertices 0 /Herwig/Vertices/HHHVertex
insert DiagramGenerator:ExcludeInternal 0 /Herwig/Particles/h0
create Herwig::ProcessData ProcessData
set /Herwig/MatrixElements/Matchbox/Factory:DiagramGenerator DiagramGenerator
set /Herwig/MatrixElements/Matchbox/Factory:ProcessData ProcessData
################################################################################
# Setup jet cuts
################################################################################
cd /Herwig/Cuts
create Herwig::MatchboxFactoryMatcher MatchboxJetMatcher
set MatchboxJetMatcher:Group j
create ThePEG::FastJetFinder JetFinder
set JetFinder:UnresolvedMatcher MatchboxJetMatcher
set JetFinder:Variant AntiKt
set JetFinder:RecombinationScheme E
set JetFinder:Mode Inclusive
set JetFinder:ConeRadius 0.7
create ThePEG::JetRegion FirstJet
set FirstJet:PtMin 20.*GeV
do FirstJet:YRange -5.0 5.0
set FirstJet:Fuzzy Yes
set FirstJet:EnergyCutWidth 4.0*GeV
set FirstJet:RapidityCutWidth 0.4
insert FirstJet:Accepts[0] 1
create ThePEG::JetRegion SecondJet
set SecondJet:PtMin 20.*GeV
do SecondJet:YRange -5.0 5.0
set SecondJet:Fuzzy Yes
set SecondJet:EnergyCutWidth 4.0*GeV
set SecondJet:RapidityCutWidth 0.4
insert SecondJet:Accepts[0] 2
create ThePEG::JetRegion ThirdJet
set ThirdJet:PtMin 20.*GeV
do ThirdJet:YRange -5.0 5.0
set ThirdJet:Fuzzy Yes
set ThirdJet:EnergyCutWidth 4.0*GeV
set ThirdJet:RapidityCutWidth 0.4
insert ThirdJet:Accepts[0] 3
create ThePEG::JetRegion FourthJet
set FourthJet:PtMin 20.*GeV
do FourthJet:YRange -5.0 5.0
set FourthJet:Fuzzy Yes
set FourthJet:EnergyCutWidth 4.0*GeV
set FourthJet:RapidityCutWidth 0.4
insert FourthJet:Accepts[0] 4
create ThePEG::NJetsCut NJetsCut
set NJetsCut:UnresolvedMatcher MatchboxJetMatcher
set NJetsCut:NJetsMin 2
create ThePEG::JetCuts JetCuts
set JetCuts:UnresolvedMatcher MatchboxJetMatcher
set JetCuts:Ordering OrderPt
-create Herwig::FrixionePhotonSeparationCut FrixionePhotonSeparationCut
create Herwig::IdentifiedParticleCut IdentifiedParticleCut
+
+cp IdentifiedParticleCut LeptonCut
+set LeptonCut:Matcher /Herwig/Matchers/Lepton
+
+cp IdentifiedParticleCut ChargedLeptonCut
+set ChargedLeptonCut:Matcher /Herwig/Matchers/ChargedLepton
+
+cp IdentifiedParticleCut TopQuarkCut
+set TopQuarkCut:Matcher /Herwig/Matchers/Top
+
+cp IdentifiedParticleCut WBosonCut
+set WBosonCut:Matcher /Herwig/Matchers/WBoson
+
+cp IdentifiedParticleCut ZBosonCut
+set ZBosonCut:Matcher /Herwig/Matchers/ZBoson
+
+cp IdentifiedParticleCut HiggsBosonCut
+set HiggsBosonCut:Matcher /Herwig/Matchers/HiggsBoson
+
+cp IdentifiedParticleCut PhotonCut
+set PhotonCut:Matcher /Herwig/Matchers/Photon
+
+create Herwig::FrixionePhotonSeparationCut PhotonIsolationCut
+set PhotonIsolationCut:UnresolvedMatcher MatchboxJetMatcher
+
create Herwig::MatchboxDeltaRCut MatchboxDeltaRCut
+
+cp MatchboxDeltaRCut LeptonDeltaRCut
+set LeptonDeltaRCut:FirstMatcher /Herwig/Matchers/Lepton
+set LeptonDeltaRCut:SecondMatcher /Herwig/Matchers/Lepton
+
+cp MatchboxDeltaRCut ChargedLeptonDeltaRCut
+set ChargedLeptonDeltaRCut:FirstMatcher /Herwig/Matchers/ChargedLepton
+set ChargedLeptonDeltaRCut:SecondMatcher /Herwig/Matchers/ChargedLepton
+
+create Herwig::InvariantMassCut InvariantMassCut
+
+cp InvariantMassCut LeptonPairMassCut
+set LeptonPairMassCut:FirstMatcher /Herwig/Matchers/Lepton
+set LeptonPairMassCut:SecondMatcher /Herwig/Matchers/Lepton
+
+cp InvariantMassCut ChargedLeptonPairMassCut
+set ChargedLeptonPairMassCut:FirstMatcher /Herwig/Matchers/ChargedLepton
+set ChargedLeptonPairMassCut:SecondMatcher /Herwig/Matchers/ChargedLepton
+
create Herwig::MissingPtCut MissingPtCut
-create Herwig::InvariantMassCut InvariantMassCut
+set MissingPtCut:Matcher /Herwig/Matchers/Neutrino
################################################################################
# Setup scale choices
################################################################################
cd /Herwig/MatrixElements/Matchbox
mkdir Scales
cd Scales
create Herwig::MatchboxScaleChoice SHatScale
cp SHatScale FixedScale
set FixedScale:FixedScale 100.*GeV
-create Herwig::MatchboxPtScale MaxptScale
-set MaxptScale:JetFinder /Herwig/Cuts/JetFinder
+create Herwig::MatchboxPtScale MaxJetPtScale
+set MaxJetPtScale:JetFinder /Herwig/Cuts/JetFinder
create Herwig::MatchboxLeptonMassScale LeptonPairMassScale
-create Herwig::MatchboxLeptonPtScale LeptonPtScale
+create Herwig::MatchboxLeptonPtScale LeptonPairPtScale
create Herwig::MatchboxHtScale HTScale
-create Herwig::MatchboxTopMassScale TopMassScale
+create Herwig::MatchboxTopMassScale TopPairMassScale
create Herwig::MatchboxTopMTScale TopMTScale
-create Herwig::MatchboxTopMinMTScale TopMinMTScale
set HTScale:JetFinder /Herwig/Cuts/JetFinder
set HTScale:IncludeMT No
cp HTScale HTPrimeScale
set HTPrimeScale:IncludeMT Yes
cp LeptonPairMassScale LeptonQ2Scale
set /Herwig/MatrixElements/Matchbox/Factory:ScaleChoice LeptonPairMassScale
################################################################################
# AlphaS
################################################################################
cd /Herwig/MatrixElements/Matchbox
mkdir AlphaS
cd AlphaS
create Herwig::O2AlphaS NLOAlphaS
set NLOAlphaS:LambdaType MSBar
insert NLOAlphaS:QuarkMasses[0] 0.005
insert NLOAlphaS:QuarkMasses[1] 0.0023
insert NLOAlphaS:QuarkMasses[2] 0.095
insert NLOAlphaS:QuarkMasses[3] 1.25
insert NLOAlphaS:QuarkMasses[4] 4.2
insert NLOAlphaS:QuarkMasses[5] 174.2
create ThePEG::O1AlphaS LOAlphaS O1AlphaS.so
insert LOAlphaS:QuarkMasses[0] 0.005
insert LOAlphaS:QuarkMasses[1] 0.0023
insert LOAlphaS:QuarkMasses[2] 0.095
insert LOAlphaS:QuarkMasses[3] 1.25
insert LOAlphaS:QuarkMasses[4] 4.2
insert LOAlphaS:QuarkMasses[5] 174.2
library HwDipoleShowerAlphaS.so
create matchbox::nlo_alpha_s MatchboxNLOAlphaS
set MatchboxNLOAlphaS:exact_evaluation large_scale
set MatchboxNLOAlphaS:freezing_scale 0.0*GeV
set MatchboxNLOAlphaS:min_active_flavours 3
set MatchboxNLOAlphaS:max_active_flavours 6
set MatchboxNLOAlphaS:input_scale 91.188*GeV
set MatchboxNLOAlphaS:input_alpha_s 0.1271103
insert MatchboxNLOAlphaS:QuarkMasses[0] 0.005
insert MatchboxNLOAlphaS:QuarkMasses[1] 0.0023
insert MatchboxNLOAlphaS:QuarkMasses[2] 0.095
insert MatchboxNLOAlphaS:QuarkMasses[3] 1.25
insert MatchboxNLOAlphaS:QuarkMasses[4] 4.2
insert MatchboxNLOAlphaS:QuarkMasses[5] 174.2
create matchbox::lo_alpha_s MatchboxLOAlphaS
set MatchboxLOAlphaS:freezing_scale 0.0*GeV
set MatchboxLOAlphaS:min_active_flavours 3
set MatchboxLOAlphaS:max_active_flavours 6
set MatchboxLOAlphaS:input_scale 91.188*GeV
set MatchboxLOAlphaS:input_alpha_s 0.1283827
insert MatchboxLOAlphaS:QuarkMasses[0] 0.005
insert MatchboxLOAlphaS:QuarkMasses[1] 0.0023
insert MatchboxLOAlphaS:QuarkMasses[2] 0.095
insert MatchboxLOAlphaS:QuarkMasses[3] 1.25
insert MatchboxLOAlphaS:QuarkMasses[4] 4.2
insert MatchboxLOAlphaS:QuarkMasses[5] 174.2
################################################################################
# Factories for different colliders
################################################################################
cd /Herwig/MatrixElements/Matchbox
cp Factory EEFactory
set EEFactory:PartonExtractor /Herwig/Partons/EEExtractor
set EEFactory:Cuts /Herwig/Cuts/EECuts
set EEFactory:FirstPerturbativePDF No
set EEFactory:SecondPerturbativePDF No
cp Factory DISFactory
set DISFactory:PartonExtractor /Herwig/Partons/DISExtractor
set DISFactory:Cuts /Herwig/Cuts/DISCuts
set DISFactory:FirstPerturbativePDF No
set DISFactory:SecondPerturbativePDF Yes
cp Factory PPFactory
set PPFactory:PartonExtractor /Herwig/Partons/QCDExtractor
set PPFactory:Cuts /Herwig/Cuts/QCDCuts
set PPFactory:FirstPerturbativePDF Yes
set PPFactory:SecondPerturbativePDF Yes
cd /

File Metadata

Mime Type
text/x-diff
Expires
Sat, Dec 21, 6:01 PM (9 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023731
Default Alt Text
(718 KB)

Event Timeline