Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -1,110 +1,109 @@
Makefile$
Makefile\.in$
\.deps$
\.libs$
\.l[ao]$
\.so$
\.so\.
\.o$
~$
\.pyc$
\.codereplace$
\.orig$
\.tar\.(gz|bz2)$
^autom4te.cache$
^config.herwig$
^config.log$
^config.status$
^configure$
^include/Herwig$
^Config/config.guess$
^Config/config.h$
^Config/config.h.in$
^Config/config.sub$
^Config/depcomp$
^Config/compile$
^Config/install-sh$
^Config/missing$
^Config/stamp-h1$
^Config/ar-lib$
^Contrib/make_makefiles.sh$
^Contrib/.*/.*\.(log|out|tex|run)$
^Utilities/hgstamp.inc$
^Doc/HerwigDefaults.in$
^Doc/refman-html$
^Doc/fixinterfaces.pl$
^Doc/refman.conf$
^Doc/refman.h$
^Doc/AllInterfaces.h$
^Doc/HerwigDefaults.rpo$
^Doc/Herwig-refman.tag$
^Doc/tagfileThePEG.tag$
^Doc/.*\.log$
^INSTALL$
^aclocal.m4$
^confdefs.h$
^conftest.c$
^conftest.err$
^include/done-all-links$
^libtool$
\.dirstamp$
^src/hgstamp.inc$
^src/herwigopts.h$
^src/herwigopts.c$
^src/defaults/Analysis.in$
^src/defaults/Decays.in$
^src/defaults/decayers.in$
^src/herwig-config$
^src/.*\.(run|tex|out|log|rpo|spc|top|dump|dot|aux|pdf|ps|png|svg|hepmc|dvi)$
^src/Makefile-UserModules$
^lib/done-all-links$
^lib/apple-fixes$
^src/defaults/PDF.in$
^src/defaults/done-all-links$
^src/tune$
^src/Herwig$
^src/Herwig-scratch$
^src/tests/.*\.(time|mult|Bmult|chisq)$
^src/Merging/test/*yoda
^src/Merging/test/Herwig*
^src/Merging/test/L*
^src/Merging/test/done-all-links
^src/Merging/done-all-links
^Tests/.*/.*\.(top|ps|pyc|info|dat|pdf|png)$
^Tests/.*\.(top|ps|pyc|info|dat|pdf|png|log|out)$
^Tests/.*\.(top|run|tex|mult|Bmult|aida|yoda)$
^Tests/Rivet-.*$
^Tests/Rivet/(LEP|DIS|LHC|TVT|Star|BFactory|ISR|SppS)-.*\.in$
^Tests/plots$
^Tests/Herwig$
^Tests/.*index.html$
^Herwig\-
^Models/Feynrules/python/Makefile-FR$
^MatrixElement/Matchbox/External/MadGraph/mg2herwig.py$
^MatrixElement/Matchbox/Scales/MatchboxScale.cc$
^Utilities/Statistics/herwig-combinedistributions$
^Utilities/Statistics/herwig-combineruns$
^Utilities/Statistics/herwig-makedistributions$
^src/defaults/MatchboxDefaults.in$
^src/defaults/setup.gosam.in$
^src/Matchbox/LO-DefaultShower.in$
^src/Matchbox/LO-DipoleShower.in$
^src/Matchbox/LO-NoShower.in$
^src/Matchbox/MCatLO-DefaultShower.in$
^src/Matchbox/MCatLO-DipoleShower.in$
^src/Matchbox/MCatNLO-DefaultShower.in$
^src/Matchbox/MCatNLO-DipoleShower.in$
^src/Matchbox/NLO-NoShower.in$
^src/Matchbox/Powheg-DefaultShower.in$
^src/Matchbox/Powheg-DipoleShower.in$
-^src/defaults/MatchboxMergeDefaults.in
^src/defaults/MatchboxMergingDefaults.in
^src/Matchbox/done-all-links$
^src/snippets/done-all-links$
^Utilities/XML/xml_test$
^Utilities/utilities_test$
^Utilities/versionstring.h$
test\.(log|trs)$
test-suite\.log$
^Config/test-driver$
param_card\.dat$
diff --git a/Contrib/AlpGen/AlpGenHandler.cc b/Contrib/AlpGen/AlpGenHandler.cc
--- a/Contrib/AlpGen/AlpGenHandler.cc
+++ b/Contrib/AlpGen/AlpGenHandler.cc
@@ -1,1392 +1,1394 @@
#include "AlpGenHandler.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Shower/QTilde/Base/PartnerFinder.h"
#include "Herwig/PDF/HwRemDecayer.h"
#include <queue>
#include "ThePEG/Utilities/Throw.h"
#include "Herwig/Shower/QTilde/Base/KinematicsReconstructor.h"
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "gsl/gsl_rng.h"
#include "gsl/gsl_randist.h"
using namespace Herwig;
bool recordEntry(PPtr i,PPtr j) {
return (i->number()<j->number());
}
bool pTsortFunction(PPtr i,PPtr j) {
return (i->momentum().perp2()>j->momentum().perp2());
}
bool ETsortFunction(pair<Energy, Lorentz5Momentum> i,pair<Energy, Lorentz5Momentum> j) {
return (i.first>j.first);
}
bool isMomLessThanEpsilon(Lorentz5Momentum p,Energy epsilon) {
return (abs(p.x())<epsilon&&abs(p.y())<epsilon&&
abs(p.z())<epsilon&&abs(p.t())<epsilon);
}
AlpGenHandler::AlpGenHandler()
: ncy_(100),ncphi_(60),ihvy_(-999),nph_(-999),nh_(-999),
etclusmean_(20*GeV),rclus_(0.4),etaclmax_(5.0),rclusfactor_(1.5),
ihrd_(-999),njets_(-999),drjmin_(-999), highestMultiplicity_(false),
ycmax_(5.4),ycmin_(-5.4),jetAlgorithm_(2),vetoIsTurnedOff_(false),
inputIsNLO_(false),highestNLOMultiplicity_(false),etclusfixed_(true),epsetclus_(2.5*GeV)
{}
void AlpGenHandler::doinitrun() {
ShowerHandler::doinitrun();
// et_ holds the ET deposited in the (ncy_ x ncphi_) calorimeter cells.
et_.resize(ncy_);
for(unsigned int ixx=0; ixx<et_.size(); ixx++) et_[ixx].resize(ncphi_);
// jetIdx_ for a given calorimeter cell this holds the index of the jet
// that the cell was clustered into.
jetIdx_.resize(ncy_);
for(unsigned int ixx=0; ixx<jetIdx_.size(); ixx++) jetIdx_[ixx].resize(ncphi_);
}
IBPtr AlpGenHandler::clone() const {
return new_ptr(*this);
}
IBPtr AlpGenHandler::fullclone() const {
return new_ptr(*this);
}
void AlpGenHandler::persistentOutput(PersistentOStream & os) const {
os << alphaS_
<< ncy_ << ncphi_ << ihvy_ << nph_ << nh_
<< ounit(etclusmean_,GeV) << rclus_ << etaclmax_ << rclusfactor_
<< ihrd_ << njets_ << drjmin_ << highestMultiplicity_
<< ycmax_ << ycmin_ << jetAlgorithm_ << vetoIsTurnedOff_
<< inputIsNLO_ << highestNLOMultiplicity_ << etclusfixed_
<< cphcal_ << sphcal_ << cthcal_ << sthcal_ << ounit(epsetclus_,GeV);
}
void AlpGenHandler::persistentInput(PersistentIStream & is, int) {
is >> alphaS_
>> ncy_ >> ncphi_ >> ihvy_ >> nph_ >> nh_
>> iunit(etclusmean_,GeV) >> rclus_ >> etaclmax_ >> rclusfactor_
>> ihrd_ >> njets_ >> drjmin_ >> highestMultiplicity_
>> ycmax_ >> ycmin_ >> jetAlgorithm_ >> vetoIsTurnedOff_
>> inputIsNLO_ >> highestNLOMultiplicity_ >> etclusfixed_
>> cphcal_ >> sphcal_ >> cthcal_ >> sthcal_ >> iunit(epsetclus_,GeV);
}
ClassDescription<AlpGenHandler> AlpGenHandler::initAlpGenHandler;
// Definition of the static class description member.
void AlpGenHandler::Init() {
static ClassDocumentation<AlpGenHandler> documentation
("The AlpGenHandler class performs MEPS merging "
"using the MLM procedure.");
static Reference<AlpGenHandler,ShowerAlpha> interfaceShowerAlpha
("ShowerAlpha",
"The object calculating the strong coupling constant",
&AlpGenHandler::alphaS_, false, false, true, false, false);
static Parameter<AlpGenHandler,unsigned int> interfaceNoCellsInRapidity
("NoCellsInRapidity",
"The number of cells spanning the rapidity interval of "
"the calorimeter",
&AlpGenHandler::ncy_, 100, 1, 10000,
false, false, Interface::limited);
static Parameter<AlpGenHandler,unsigned int> interfaceNoCellsInPhi
("NoCellsInPhi",
"The number of cells spanning the phi interval of "
"the calorimeter",
&AlpGenHandler::ncphi_, 60, 1, 10000,
false, false, Interface::limited);
static Parameter<AlpGenHandler,int> interfaceihvy
("ihvy",
"heavy flavour in WQQ,ZQQ,2Q etc (4=c, 5=b, 6=t)",
&AlpGenHandler::ihvy_, -999, -999, 7,
false, false, Interface::limited);
static Parameter<AlpGenHandler,int> interfacenph
("nph",
"Number of photons in the AlpGen process",
&AlpGenHandler::nph_, -999, -999, 7,
false, false, Interface::limited);
static Parameter<AlpGenHandler,int> interfacenh
("nh",
"Number of higgses in the AlpGen process",
&AlpGenHandler::nph_, -999, -999, 7,
false, false, Interface::limited);
static Parameter<AlpGenHandler,Energy> interfaceETClus
("ETClus",
"The ET threshold defining a jet in the merging procedure",
&AlpGenHandler::etclusmean_, GeV, 20*GeV, 0*GeV, 14000*GeV,
false, false, Interface::limited);
static Parameter<AlpGenHandler,double> interfaceRClus
("RClus",
"The cone size used to define a jet in the merging procedure",
&AlpGenHandler::rclus_, 0.4, 0.0, 4.0,
false, false, Interface::limited);
static Parameter<AlpGenHandler,double> interfaceEtaClusMax
("EtaClusMax",
"The maximum |eta| used to define a jet in the merging procedure",
&AlpGenHandler::etaclmax_, 5.0, 0.0, 15.0,
false, false, Interface::limited);
static Parameter<AlpGenHandler,double> interfaceRClusFactor
("RClusFactor",
"The prefactor for RClus used to define the jet-parton matching "
"distance",
&AlpGenHandler::rclusfactor_, 1.5, 0.0, 4.0,
false, false, Interface::limited);
static Parameter<AlpGenHandler,int> interfaceihrd
("ihrd",
"The AlpGen hard process code",
&AlpGenHandler::ihrd_, -999, 0, 10000,
false, false, Interface::limited);
static Parameter<AlpGenHandler,int> interfacenjets
("njets",
"The number of light jets in the AlpGen process (i.e. the "
"extra ones)",
&AlpGenHandler::njets_, -999, 0, 10000,
false, false, Interface::limited);
static Parameter<AlpGenHandler,double> interfacedrjmin
("drjmin",
"Mimimum parton-parton R-sep used for generation.",
&AlpGenHandler::drjmin_, 0.7, 0.0, 4.0,
false, false, Interface::limited);
static Parameter<AlpGenHandler,bool> interfacehighestMultiplicity
("highestMultiplicity",
"If true it indicates that this is the highest multiplicity input "
"ME-level configuration to be processed.",
&AlpGenHandler::highestMultiplicity_, 0, 0, 1,
false, false, Interface::limited);
static Parameter<AlpGenHandler,bool> interfacehighestNLOMultiplicity
("highestNLOMultiplicity",
"If true it indicates that this is the highest NLO multiplicity input "
"ME-level configuration to be processed.",
&AlpGenHandler::highestNLOMultiplicity_, 0, 0, 1,
false, false, Interface::limited);
static Parameter<AlpGenHandler,bool> interfaceETClusFixed
("ETClusFixed",
"If false, indicates that the jet merging scale, etclus_ is allowed to vary"
"according to epsetclus_",
&AlpGenHandler::etclusfixed_, 1, 0, 1,
false, false, Interface::limited);
static Parameter<AlpGenHandler,Energy> interfaceEpsilonETClus
("EpsilonETClus",
"The ET threshold defining a jet in the merging procedure",
&AlpGenHandler::epsetclus_, GeV, 2.5*GeV, 0*GeV, 100.0*GeV,
false, false, Interface::limited);
static Switch<AlpGenHandler,int> interfaceJetAlgorithm
("JetAlgorithm",
"Determines the jet algorithm for finding jets in parton-jet "
"matching in the MLM procedure.",
&AlpGenHandler::jetAlgorithm_, 2, false, false);
static SwitchOption AntiKt
(interfaceJetAlgorithm,
"AntiKt",
"The anti-kt jet algorithm.",
-1);
static SwitchOption CambridgeAachen
(interfaceJetAlgorithm,
"CambridgeAachen",
"The Cambridge-Aachen jet algorithm.",
0);
static SwitchOption Kt
(interfaceJetAlgorithm,
"Kt",
"The Kt jet algorithm.",
1);
static SwitchOption GetJet
(interfaceJetAlgorithm,
"GetJet",
"Calorimeter-based GetJet algorithm (default).",
2);
static Switch<AlpGenHandler,bool> interfaceVetoIsTurnedOff
("VetoIsTurnedOff",
"Allows the vetoing mechanism to be switched off.",
&AlpGenHandler::vetoIsTurnedOff_, false, false, false);
static SwitchOption VetoingIsOn
(interfaceVetoIsTurnedOff,
"VetoingIsOn",
"The MLM merging veto mechanism is switched ON.",
false);
static SwitchOption VetoingIsOff
(interfaceVetoIsTurnedOff,
"VetoingIsOff",
"The MLM merging veto mechanism is switched OFF.",
true);
static Switch<AlpGenHandler,bool> interfaceInputIsNLO
("InputIsNLO",
"Signals whether the input LH file is tree-level accurate "
"or contains NLO (Powheg) events.",
&AlpGenHandler::inputIsNLO_, false, false, false);
static SwitchOption InputIsNotNLO
(interfaceInputIsNLO,
"InputIsNotNLO",
"The input LH events have tree-level accuracy.",
false);
static SwitchOption InputIsNLO
(interfaceInputIsNLO,
"InputIsNLO",
"The input LH events have NLO accuracy.",
true);
}
void AlpGenHandler::dofinish() {
ShowerHandler::dofinish();
}
void AlpGenHandler::doinit() {
//print error if HardProcID is not set in input file
if(ihrd_ == -999) { cout << "Error: AlpGenHandler:ihrd not set!" << endl; exit(1); }
ShowerHandler::doinit();
// Compute calorimeter edges in rapidity for GetJet algorithm.
ycmax_=etaclmax_+rclus_;
ycmin_=-ycmax_;
// Initialise calorimeter.
calini_m();
}
// Throws a veto according to MLM strategy ... when we finish writing it.
bool AlpGenHandler::showerHardProcessVeto() {
+
if(vetoIsTurnedOff_) return false;
+
// Skip veto for processes in which merging is not implemented:
if(ihrd_==7||ihrd_==8||ihrd_==13) {
ostringstream wstring;
wstring << "AlpGenHandler::showerHardProcessVeto() - warning."
<< "MLM merging not implemented for AlpGen "
<< "processes 4Q (ihrd=7), QQh (ihrd=8), "
<< "(single) top (ihrd=13) \n";
generator()->logWarning( Exception(wstring.str(),
Exception::warning) );
return false;
}
// Fill preshowerISPs_ pair and preshowerFSPs_ particle pointer vector.
getPreshowerParticles();
// Fill showeredISHs_, showeredISPs and showeredRems pairs, as well as
// showeredFSPs_ particle pointer vector.
getShoweredParticles();
// Turn on some screen output debugging: 0 = none ---> 5 = very verbose.
doSanityChecks(0);
// Dimensions of each calorimter cell in y and phi.
dely_ = (ycmax_-ycmin_)/double(ncy_);
delphi_ = 2*M_PI/double(ncphi_);
// Fill partonsToMatch_ with only those pre-shower partons intended to
// used in jet-parton matching and fill particlesToCluster_ using only
// those final state particles (post-shower) which are supposed to go
// in the jet clustering used to do merging.
partonsToMatch_ = preshowerFSPs_;
particlesToCluster_ = showeredFSPs_ ; // <--- TO DO: add remnants in here ???
// Filter out all but the 'extra' light-parton progenitors and their
// associated final state particles.
caldel_m();
double prob(1);
//if etclusfixed_ then set the etclus_ to the fixed chosen value
if(etclusfixed_) {
etclus_ = etclusmean_;
} else {
//else, if we wish to vary etclus_, we use the probability distribution
//choose a probability between 0 and 1
prob = rnd();
etclus_ = etclusran_(prob);
}
if(jetAlgorithm_==2) {
// If using GetJet fill the calorimeter cells now from particlesToCluster_
calsim_m();
// Make jets from the calorimeter blobs.
getjet_m(rclus_,etclus_,etaclmax_);
} else {
// Cluster particlesToCluster_ into jets with FastJet.
getFastJets(rclus_,etclus_,etaclmax_);
}
// If there are less jets than partons then parton-jet matching is
// bound to fail: reject the event already. Also, if the input is
// an NLO event file it will 99.5% of the time contain a number of
// light partons in the F.S. equal to that in the real emission
// process in the NLO calculation, moreover, it has already
// effectively merged njets_-1 and njets jet events. So in that
// case we do not reject events on the grounds they have jet
// multiplicity less than partonsToMatch_.size() but rather less
// jets than partonsToMatch.size()-1; such events are better
// described by the lower-by-one-unit (partonsToMatch_.size()-1)
// of multiplicity NLO event file, or the lower-by-two-units
// (partonsToMatch_.size()-2) of multiplicity LO event file.
// If it is not jet production apply rejection criterion as above.
if(ihrd_!=9) {
if(!inputIsNLO_) {
if(pjet_.size() < partonsToMatch_.size()) return true;
} else {
if(pjet_.size() < partonsToMatch_.size()-1) return true;
}
// Otherwise, in the case of jet production allow the lowest
// contributing multiplicity process (just at NLO), namely,
// dijet production, to give rise to 1-jet and even 0-jet
// events, since these can contribute to, for example, the
// inclusive jet cross section i.e. in this case the rejection
// is only applied in the case of the next-to-lowest multiplicity
// processes (>2 parton events at LO and >3 parton events at NLO).
} else {
if(!inputIsNLO_) {
// KH - March 5th
// Removed the following line giving special treatment
// also to the LO events, to maintain consistency with
// the fortran algorithm, at least for now. So now jet
// production at LO is being treated the same as all
// other processes.
// if(partonsToMatch_.size()==2 && pjet_.size()<2) return false;
if(pjet_.size() < partonsToMatch_.size()) return true;
} else {
if(partonsToMatch_.size()<=3 && pjet_.size()<2) return false;
if(pjet_.size() < partonsToMatch_.size()-1) return true;
}
}
// Sort partonsToMatch_ from high to low pT.
sort(partonsToMatch_.begin(),partonsToMatch_.end(),pTsortFunction);
// Match light progenitors to jets.
vector<int> jetToPartonMap(pjet_.size(),-999);
Energy etmin(777e100*GeV);
// If the input is NLO events then don't do any jet-parton matching!
if(!inputIsNLO_) {
// For each parton, starting with the hardest one ...
for(unsigned int ixx=0; ixx<partonsToMatch_.size(); ixx++) {
// ... loop over all jets not already matched.
double DRmin(777e100);
int jetIndexForDRmin(-999);
for(unsigned int jxx=0; jxx<pjet_.size(); jxx++) {
// ... and tag closest of the remaining ones
double DRpartonJet(partonJetDeltaR(partonsToMatch_[ixx],pjet_[jxx]));
if(jetToPartonMap[jxx]<0&&DRpartonJet<DRmin) {
DRmin=DRpartonJet;
jetIndexForDRmin=jxx;
}
}
// If the parton-jet distance is less than the matching
// distance, the parton and jet match.
if(DRmin<rclus_*rclusfactor_&&jetIndexForDRmin>=0) {
jetToPartonMap[jetIndexForDRmin]=ixx;
if(ixx==0||etjet_[jetIndexForDRmin]<etmin)
etmin=etjet_[jetIndexForDRmin];
// Otherwise this parton is not matched so veto the event.
} else return true;
}
}
// Veto events with larger jet multiplicity from exclusive sample.
if(!highestMultiplicity_&&pjet_.size()>partonsToMatch_.size()
&& !inputIsNLO_) return true;
if(inputIsNLO_) {
if(!highestNLOMultiplicity_) {
if(pjet_.size()>partonsToMatch_.size()-1) return true;
} else {
if(!highestMultiplicity_&&pjet_.size()>partonsToMatch_.size())
return true;
}
}
// Veto events where matched jets are softer than non-matched ones,
// in the inclusive (highestMultiplicity_ = true) mode, unless we
// are dealing with NLO input events.
if(highestMultiplicity_ && !inputIsNLO_ ) {
for(unsigned int ixx=0; ixx<pjet_.size(); ixx++)
if(jetToPartonMap[ixx]<0&&etmin<etjet_[ixx]) return true;
}
-
+
// **************************************************************** //
// * Now look to the non-light partons for heavy quark processes. * //
// **************************************************************** //
if(ihrd_<=2||ihrd_==6||ihrd_==10||ihrd_==15||ihrd_==16) {
// Extract heavy quark progenitors and the radiation they
// produce and put it in the calorimeter.
caldel_hvq();
if(jetAlgorithm_==2) {
// If using GetJet fill the calorimeter cells now from particlesToCluster_
calsim_m();
// Make jets from the calorimeter blobs.
getjet_m(rclus_,etclus_,etaclmax_);
} else {
// Cluster particlesToCluster_ into jets with FastJet.
getFastJets(rclus_,etclus_,etaclmax_);
}
// If the radiation from the heavy quarks does not give rise
// to any jets we accept event.
if(pjet_.size() == 0) return false;
// If extra jets emerge from the jet clustering we only
// accept events where the jets formed by radiation from
// b and c quarks lies within drjmin_ of the heavy quark
// progenitor.
int nmjet(pjet_.size());
for(unsigned int ixx=0; ixx<pjet_.size(); ixx++) {
for(unsigned int jxx=0; jxx<partonsToMatch_.size(); jxx++) {
if(!(abs(partonsToMatch_[jxx]->id())==4||abs(partonsToMatch_[jxx]->id())==5)) continue;
if(partonJetDeltaR(partonsToMatch_[jxx],pjet_[ixx])<drjmin_) {
nmjet--; // Decrease the number of unmatched jets.
etjet_[ixx]=0*GeV; // Set jet ET to zero to indicate it is 'matched'.
}
}
}
// If every jet matched to _at_least_one_ progenitor accept the event.
if(nmjet<=0) return false;
else {
// If unmatched jets remain, reject the event if highestMultiplicity_!=1
if(!highestMultiplicity_) return true;
else {
// If unmatched jets remain and highestMultiplicity is true then check
// that these are softer than all the matched ones (from the light-parton
// matching round).
Energy etmax(0.*GeV);
for(unsigned int ixx=0; ixx<pjet_.size(); ixx++) etmax=max(etjet_[ixx],etmax);
if(etmax>etmin) return true;
}
}
}
// Otherwise we accept the event ...
return false;
}
/* Function that returns the R distance
between a particle and a jet. */
double AlpGenHandler::partonJetDeltaR(ThePEG::tPPtr partonptr, LorentzMomentum jetmom) {
LorentzMomentum partonmom(partonptr->momentum());
// Calculate DY, DPhi and then DR
double DY(partonmom.eta()-jetmom.eta());
double DPhi(partonmom.phi()-jetmom.phi());
if(DPhi>M_PI) DPhi=2*M_PI-DPhi;
double DR(sqrt(sqr(DY)+sqr(DPhi)));
return DR;
}
// Initialize calorimeter for calsim_m and getjet_m. Note that
// because initialization is separte calsim_m can be called more
// than once to simulate pileup of several events.
void AlpGenHandler::calini_m() {
// Making sure arrays are clear before filling;
cphcal_.clear(); sphcal_.clear();
cthcal_.clear(); sthcal_.clear();
// Fill array holding phi values of calorimeter cell centres.
double deltaPhi(2*M_PI/ncphi_);
for(unsigned int iphi=1; iphi<=ncphi_; iphi++) {
double phi(deltaPhi*(iphi-0.5)); // Goes phi~=0 to phi~=2*pi (iphi=0--->ncphi).
cphcal_.push_back(cos(phi)); // ==> goes from +1 ---> +1 (iphi=0--->ncphi).
sphcal_.push_back(sin(phi)); // ==> goes 0 -> 1 -> 0 -> -1 -> 0 (iphi=0--->ncphi).
}
// Fill array holding theta values of calorimeter cell centres in Y.
double deltaY((ycmax_-ycmin_)/double(ncy_));
for(unsigned int iy=1; iy<=ncy_; iy++) {
double Y(deltaY*(iy-0.5)+ycmin_);
double th(2*atan(exp(-Y))); // Goes bwds th~=pi to fwds th~=0 (iy=0--->ncy).
cthcal_.push_back(cos(th)); // ==> goes from -1 ---> +1 (iy=0--->ncy).
sthcal_.push_back(sin(th)); // ==> goes from 0 ---> +1 ---> 0 (iy=0--->ncy).
}
return;
}
// Get FastJets
void AlpGenHandler::getFastJets(double rjet, Energy ejcut, double etajcut) {
vector<fastjet::PseudoJet> particlesToCluster;
for(unsigned int ipar=0; ipar<particlesToCluster_.size(); ipar++) {
double y(particlesToCluster_[ipar]->momentum().eta());
if(y>=ycmin_&&y<=ycmax_) {
int absId(abs(particlesToCluster_[ipar]->id()));
// If it's not a lepton / top / photon it may go in the jet finder.
if(!(absId>=11&&absId<=16) && absId!=6 && absId!=22) {
// input particles into fastjet pseudojet
fastjet::PseudoJet p(particlesToCluster_[ipar]->momentum().x()/GeV,
particlesToCluster_[ipar]->momentum().y()/GeV,
particlesToCluster_[ipar]->momentum().z()/GeV,
particlesToCluster_[ipar]->momentum().e()/GeV);
p.set_user_index(ipar);
particlesToCluster.push_back(p);
}
}
}
fastjet::RecombinationScheme recombinationScheme = fastjet::E_scheme;
fastjet::Strategy strategy = fastjet::Best;
double R(rjet);
fastjet::JetDefinition theJetDefinition;
switch (jetAlgorithm_) {
case -1: theJetDefinition=fastjet::JetDefinition(fastjet::antikt_algorithm,
R,
recombinationScheme,
strategy); break;
case 0: theJetDefinition=fastjet::JetDefinition(fastjet::cambridge_algorithm,
R,
recombinationScheme,
strategy); break;
case 1: theJetDefinition=fastjet::JetDefinition(fastjet::kt_algorithm,
R,
recombinationScheme,
strategy); break;
default: theJetDefinition=fastjet::JetDefinition(fastjet::cambridge_algorithm,
R,
recombinationScheme,
strategy); break;
}
fastjet::ClusterSequence fastjetEvent(particlesToCluster,theJetDefinition);
vector<fastjet::PseudoJet> inclusiveJets = fastjetEvent.inclusive_jets();
inclusiveJets = fastjet::sorted_by_pt(inclusiveJets);
// Fill the array of jet momenta for the rest of the veto procedure.
pjet_.clear();
pjet_.resize(inclusiveJets.size());
etjet_.clear();
etjet_.resize(inclusiveJets.size());
for(unsigned int ffj=0; ffj<pjet_.size();ffj++) {
pjet_[ffj] = Lorentz5Momentum(inclusiveJets[ffj].px()*GeV,
inclusiveJets[ffj].py()*GeV,
inclusiveJets[ffj].pz()*GeV,
inclusiveJets[ffj].e()*GeV);
pjet_[ffj].rescaleMass();
etjet_[ffj] = pjet_[ffj].et();
}
// Throw the jet away if it's outside required eta region or
// has transverse energy below ejcut.
for(unsigned int fj=0; fj<pjet_.size(); fj++)
if(etjet_[fj]<ejcut||fabs(pjet_[fj].eta())>etajcut) {
pjet_.erase(pjet_.begin()+fj);
etjet_.erase(etjet_.begin()+fj);
fj--;
}
// Sort jets from high to low ET.
vector<pair<Energy, Lorentz5Momentum> > etjet_pjet;
for(unsigned int ixx=0; ixx<etjet_.size(); ixx++)
etjet_pjet.push_back(make_pair(etjet_[ixx],pjet_[ixx]));
sort(etjet_pjet.begin(),etjet_pjet.end(),ETsortFunction);
for(unsigned int ixx=0; ixx<etjet_.size(); ixx++) {
etjet_[ixx]=etjet_pjet[ixx].first;
pjet_[ixx]=etjet_pjet[ixx].second;
}
return;
}
// Simple calorimeter simulation - assume uniform Y and phi bins.
void AlpGenHandler::calsim_m() {
// Reset transverse energies of all calorimter cells ready for new fill.
for(unsigned int ixx=0; ixx<et_.size(); ixx++)
for(unsigned int iyy=0; iyy<et_[ixx].size(); iyy++)
et_[ixx][iyy]=0*GeV;
// Assign ET to each calorimeter cell (mostly 0's).
for(unsigned int ipar=0; ipar<particlesToCluster_.size(); ipar++) {
double y(particlesToCluster_[ipar]->momentum().eta());
if(y>=ycmin_&&y<=ycmax_) {
int absId(abs(particlesToCluster_[ipar]->id()));
// If it's not a lepton / top / photon it goes in the calorimeter.
if(!(absId>=11&&absId<=16) && absId!=6 && absId!=22) {
double phi(atan2(particlesToCluster_[ipar]->momentum().y()/GeV,
particlesToCluster_[ipar]->momentum().x()/GeV));
if(phi<0) phi+=2*M_PI;
unsigned int iy(int((y-ycmin_)/dely_));
unsigned int iphi(int(phi/delphi_));
et_[iy][iphi]+=particlesToCluster_[ipar]->momentum().e()*sthcal_[iy];
}
}
}
return;
}
// Find highest remaining cell > etstop and sum surrounding cells
// with -- delta(y)^2+delta(phi)^2 < Rjet^2 , ET>eccut. Keep sets
// with ET>ejcut and abs(eta)<etacut.
void AlpGenHandler::getjet_m(double rjet, Energy ejcut, double etajcut) {
// Minimum ET the calorimeter can "see".
Energy eccut(0.1*GeV);
// So long as the cell remaining with the highest ET has
// ET < etstop we try to cluster the surrounding cells into
// it to potentially form a jet.
Energy etstop(1.5*GeV);
// Reset the vector holding the jet-index each calo cell
// was clustered into.
for(unsigned int iy=0; iy<ncy_; iy++)
for(unsigned int iphi=0; iphi<ncphi_; iphi++)
jetIdx_[iy][iphi]=-777;
// Reset the vector that will hold the jet momenta.
pjet_.clear();
// # cells spanned by cone radius in phi dir., _rounded_down_.
unsigned int nphi1(rjet/delphi_);
// # cells spanned by cone radius in eta dir., _rounded_down_.
unsigned int ny1(rjet/dely_);
// Vector to hold the "ET" of each jet, where here ET really means
// the scalar sum of ETs in each calo cell clustered into the jet.
// Note that this is _not_ the same as the ET you would compute from
// the final momentum worked out for each jet.
etjet_.clear();
// The ET of the highest ET cell found.
Energy etmax(777e100*GeV);
// Counter for number of highest ET calo cells found.
unsigned int ipass(0);
// Start finding jets.
while(etmax>=etstop) {
// Find the cell with the highest ET from
// those not already assigned to a jet.
etmax=0*GeV;
int iymx(0), iphimx(0);
for(unsigned int iphi=0; iphi<ncphi_; iphi++)
for(unsigned int iy=0; iy<ncy_; iy++)
if(et_[iy][iphi]>etmax&&jetIdx_[iy][iphi]<0) {
etmax = et_[iy][iphi];
iymx = iy;
iphimx = iphi;
}
// If the remaining cell with the highest ET has ET < etstop, stop.
if(etmax<etstop) break;
// You cannot have more cells with the highest ET
// so far than you have cells in the calorimeter.
ipass++;
if(ipass>(ncy_*ncphi_)) {
cout << "AlpGenHandler::getjet_m() - Fatal error." << endl;
cout << "We found " << ipass << " calo cells with the highest ET so"
<< "far\nbut the calorimeter only has " << ncy_*ncphi_ << " "
<< "cells in it!" << endl;
exit(10);
}
// Add a jet vector (may get deleted if jet fails ET / eta cuts).
etjet_.push_back(0*GeV);
pjet_.push_back(Lorentz5Momentum(0.*GeV,0.*GeV,0.*GeV,0.*GeV,0.*GeV));
// Loop over all calo cells in range iphimx +/- nphi1 (inclusive)
// wrapping round in azimuth if required.
for(unsigned int iphi1=0; iphi1<=2*nphi1; iphi1++) {
int iphix(iphimx-nphi1+iphi1);
if(iphix<0) iphix += ncphi_;
if(iphix>=int(ncphi_)) iphix -= ncphi_;
// Loop over all calo cells in range iymx +/- ny1 (inclusive).
for(unsigned int iy1=0; iy1<=2*ny1; iy1++) {
int iyx(iymx-ny1+iy1);
// If the cell is outside the calorimeter OR if it was already
// associated to a jet then skip to the next loop.
if(iyx>=0&&iyx<int(ncy_)&&jetIdx_[iyx][iphix]<0) {
// N.B. iyx-iymx = iy1-ny1 and iphix-iphimx = iphi1-nphi1
// hence the following is the distance in R between the
// centre of the cell we are looking at and the one
// with the highest ET.
double r2(sqr( dely_*(double(iy1) -double(ny1) ))
+sqr(delphi_*(double(iphi1)-double(nphi1))));
if(r2<sqr(rjet)&&et_[iyx][iphix]>=eccut) {
Energy ECell(et_[iyx][iphix]/sthcal_[iyx]);
pjet_.back()+=LorentzMomentum(ECell*sthcal_[iyx]*cphcal_[iphix], // px
ECell*sthcal_[iyx]*sphcal_[iphix], // py
ECell*cthcal_[iyx],ECell); // pz, E.
// N.B. This is the same reln as in ThePEG between phi and x,y.
etjet_.back()+=et_[iyx][iphix];
jetIdx_[iyx][iphix] = pjet_.size()-1; // Identify cell with this jet.
}
}
}
}
// Compute the current jet's mass.
pjet_.back().rescaleMass();
// Throw the jet away if it's ET is less than ejcut.
if(etjet_.back()<ejcut||fabs(pjet_.back().eta())>etajcut) {
pjet_.pop_back();
etjet_.pop_back();
}
}
// Sort jets from high to low ET.
vector<pair<Energy, Lorentz5Momentum> > etjet_pjet;
for(unsigned int ixx=0; ixx<etjet_.size(); ixx++)
etjet_pjet.push_back(make_pair(etjet_[ixx],pjet_[ixx]));
sort(etjet_pjet.begin(),etjet_pjet.end(),ETsortFunction);
for(unsigned int ixx=0; ixx<etjet_.size(); ixx++) {
etjet_[ixx]=etjet_pjet[ixx].first;
pjet_[ixx]=etjet_pjet[ixx].second;
}
return;
}
// Deletes particles from partonsToMatch_ and particlesToCluster_
// vectors so that these contain only the partons to match to the
// jets and the particles used to build jets respectively. By and
// large the candidates for deletion are: vector bosons and their
// decay products, Higgs bosons, photons as well as _primary_, i.e.
// present in the lowest multiplicity process, heavy quarks and
// any related decay products.
void AlpGenHandler::getDescendents(PPtr theParticle) {
ParticleVector theChildren(theParticle->children());
for (unsigned int ixx=0; ixx<theChildren.size(); ixx++)
if(theChildren[ixx]->children().size()==0)
tmpList_.push_back(theChildren[ixx]);
else
getDescendents(theChildren[ixx]);
return;
}
void AlpGenHandler::caldel_m() {
preshowerFSPsToDelete_.clear();
showeredFSPsToDelete_.clear();
for(unsigned int ixx=0; ixx<preshowerFSPs_.size(); ixx++) {
tmpList_.clear();
if(ihrd_<=2) {
/* wqq... , zqq... */
/* Exclude the heavy quarks and any children they may
have produced as well as the v.boson and any children
it may have produced from the jet parton matching. */
if(abs(preshowerFSPs_[ixx]->parents()[0]->id())==23||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
if(abs(preshowerFSPs_[ixx]->id())==ihvy_&&ixx<2) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=4) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "wqq / zqq process should have 4 particles to omit from"
<< "jet-parton matching for ihvy=" << ihvy_ << "." << Exception::eventerror;
}
} else if(ihrd_<=4) {
/* zjet... */
/* Exclude the v.boson and any children
it may have produced from the jet parton matching. */
if(abs(preshowerFSPs_[ixx]->parents()[0]->id())==23||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=2) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "zjet process should have 2 particles to omit from"
<< "jet-parton matching." << Exception::eventerror;
}
} else if(ihrd_==5) {
/* vbjet... */
/* Exclude the v.bosons and any children they may
have produced from the jet parton matching. */
if(abs(preshowerFSPs_[ixx]->parents()[0]->id())==23||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24||
abs(preshowerFSPs_[ixx]->id())==22||
abs(preshowerFSPs_[ixx]->id())==25) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
} else if(ihrd_==6) {
/* 2Q... */
/* Exclude the heavy quarks and any children
they may have produced from the jet parton matching. */
if(ihvy_==6) {
if(abs(preshowerFSPs_[ixx]->parents()[0]->id())==6||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
}
if(abs(preshowerFSPs_[ixx]->parents()[0]->id())==6) {
getDescendents(preshowerFSPs_[ixx]->parents()[0]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=6) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "2Q process should have 6 particles to omit from"
<< "jet-parton matching for ihvy=" << ihvy_ << "." << Exception::eventerror;
}
} else {
if(abs(preshowerFSPs_[ixx]->id())==ihvy_&&ixx<2) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=2) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "2Q process should have 2 particles to omit from"
<< "jet-parton matching for ihvy=" << ihvy_ << "." << Exception::eventerror;
}
}
} else if(ihrd_==7) {
/* 4Q... */
/* There are no light jets for this process, so nothing to match. */
} else if(ihrd_==9) {
/* Njet... */
} else if(ihrd_==10) {
/* wcjet... */
/* Exclude the charm quark and any children it may
have produced as well as the v.boson and any children
it may have produced from the jet parton matching. */
if((abs(preshowerFSPs_[ixx]->id())==4&&ixx<1)||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=3) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "wcjet process should have 3 particles to omit from"
<< "jet-parton matching." << Exception::eventerror;
}
} else if(ihrd_==11) {
/* phjet... */
/* Exclude the hard photons from the jet parton matching. */
if(abs(preshowerFSPs_[ixx]->id())==22) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
unsigned int tmpUnsignedInt(nph_);
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=tmpUnsignedInt) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "phjet process should have " << nph_ << " particles to omit from"
<< "jet-parton matching." << Exception::eventerror;
}
} else if(ihrd_==12) {
/* hjet... */
/* Exclude the higgs and any children it may have
produced from the jet parton matching. */
if(abs(preshowerFSPs_[ixx]->id())==25) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=1) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "hjet process should have 1 particle to omit from"
<< "jet-parton matching." << Exception::eventerror;
}
} else if(ihrd_==14) {
/* wphjet... */
/* Exclude the v.boson and any children it may have
produced from the jet parton matching. */
// AND WHAT ABOUT THE PHOTON? <--- CHECK THIS WITH AlpGen GUYs.
if(abs(preshowerFSPs_[ixx]->id())==22||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
unsigned int tmpUnsignedInt(2+nph_);
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=tmpUnsignedInt) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "wphjet process should have " << 2+nph_ << " particles to omit from"
<< "jet-parton matching." << Exception::eventerror;
}
} else if(ihrd_==15) {
/* wphqq... <--- N.B. if q = top, it is not decayed. */
/* Exclude the heavy quarks and any children they may
have produced as well as the v.boson and any children
it may have produced from the jet parton matching. */
// AND WHAT ABOUT THE PHOTON? <--- CHECK THIS WITH AlpGen GUYs.
if(abs(preshowerFSPs_[ixx]->id())==22||
(abs(preshowerFSPs_[ixx]->id())==ihvy_&&ixx==(preshowerFSPs_.size()-(2+nph_+1)))||
(abs(preshowerFSPs_[ixx]->id())==ihvy_&&ixx==(preshowerFSPs_.size()-(2+nph_+2)))||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
unsigned int tmpUnsignedInt(4+nph_);
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=tmpUnsignedInt) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "wphjet process should have " << 4+nph_ << " particles to omit from"
<< "jet-parton matching." << Exception::eventerror;
}
} else if(ihrd_==16) {
/* 2Qph... <--- if Q is a top it will decay. */
/* Exclude the hard photons and any children they
may have produced from the jet parton matching
as well as the heavy quarks and any children it
may have produced. */
// AND WHAT ABOUT THE PHOTON?
if(ihvy_==6) {
if(abs(preshowerFSPs_[ixx]->id())==22||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==6||
abs(preshowerFSPs_[ixx]->parents()[0]->id())==24) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
unsigned int tmpUnsignedInt(6+nph_);
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=tmpUnsignedInt) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "wphjet process should have " << 6+nph_ << " particles to omit from"
<< "jet-parton matching for ihvy=" << ihvy_ << "." << Exception::eventerror;
}
} else {
if(abs(preshowerFSPs_[ixx]->id())==22||
(abs(preshowerFSPs_[ixx]->id())==ihvy_&&ixx<2)) {
preshowerFSPsToDelete_.push_back(preshowerFSPs_[ixx]);
getDescendents(preshowerFSPs_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
unsigned int tmpUnsignedInt(2+nph_);
if(ixx==preshowerFSPs_.size()-1&&preshowerFSPsToDelete_.size()!=tmpUnsignedInt) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "wphjet process should have " << 2+nph_ << " particles to omit from"
<< "jet-parton matching for ihvy=" << ihvy_ << "." << Exception::eventerror;
}
}
}
}
for(unsigned int ixx=0; ixx<preshowerFSPsToDelete_.size(); ixx++) {
for(unsigned int jxx=0; jxx<partonsToMatch_.size(); jxx++) {
if(preshowerFSPsToDelete_[ixx]==partonsToMatch_[jxx]) {
partonsToMatch_.erase(partonsToMatch_.begin()+jxx);
break;
}
}
}
for(unsigned int ixx=0; ixx<showeredFSPsToDelete_.size(); ixx++) {
for(unsigned int jxx=0; jxx<particlesToCluster_.size(); jxx++) {
if(showeredFSPsToDelete_[ixx]==particlesToCluster_[jxx]) {
particlesToCluster_.erase(particlesToCluster_.begin()+jxx);
break;
}
}
}
// Sanity check!
if(partonsToMatch_.size()>particlesToCluster_.size()) {
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "No. of ME level partons to be matched to jets = "
<< partonsToMatch_.size() << "\n"
<< "No. of showered particles to build jets from = "
<< particlesToCluster_.size() << "\n"
<< "There should be at least as many partons to\n"
<< "cluster as there are partons to match to.\n"
<< Exception::eventerror;
}
// Acid test.
unsigned int tmpUnsignedInt(njets_);
if(!inputIsNLO_&&partonsToMatch_.size()!=tmpUnsignedInt) {
for(unsigned int ixx=0; ixx<partonsToMatch_.size(); ixx++) {
if(abs(partonsToMatch_[ixx]->id())>=6&&
abs(partonsToMatch_[ixx]->id())!=21)
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "Found a parton to match to which is not a quark or gluon!"
<< *partonsToMatch_[ixx] << "\n"
<< Exception::eventerror;
}
throw Exception()
<< "AlpGenHandler::caldel_m() - ERROR!\n"
<< "No. of ME level partons to be matched to jets = "
<< partonsToMatch_.size() << "\n"
<< "No. of light jets (njets) in AlpGen process = "
<< njets_ << "\n"
<< "These should be equal." << "\n"
<< Exception::eventerror;
}
return;
}
// This looks for all descendents of a top up to but not including
// the W and b children.
void AlpGenHandler::getTopRadiation(PPtr theParticle) {
ParticleVector theChildren(theParticle->children());
for (unsigned int ixx=0; ixx<theChildren.size(); ixx++)
if(theChildren[ixx]->children().size()==0)
tmpList_.push_back(theChildren[ixx]);
else if(abs(theChildren[ixx]->id())==5||abs(theChildren[ixx]->id())==24)
return;
else
getTopRadiation(theChildren[ixx]);
return;
}
void AlpGenHandler::caldel_hvq() {
// Fill partonsToMatch_ with only those pre-shower partons intended to
// be used in heavy-quark-jet matching and fill particlesToCluster_ using
// only those final state particles (post-shower) which are supposed
// in the heavy-quark-jet clustering used to do merging. To begin with
// these are made from the corresponding sets of particles that were
// omitted from the initial jet-parton matching run.
partonsToMatch_ = preshowerFSPsToDelete_;
particlesToCluster_.resize(showeredFSPsToDelete_.size());
for(unsigned int ixx=0; ixx<showeredFSPsToDelete_.size(); ixx++)
particlesToCluster_[ixx] = showeredFSPsToDelete_[ixx];
// Reset the arrays of particles to delete so that the partonsToMatch_
// and particlesToCluster_ vectors can undergo further filtering.
preshowerFSPsToDelete_.clear();
showeredFSPsToDelete_.clear();
// Determine further particles in partonsToMatch_ and particlesToCluster_
// for deletion.
for(unsigned int ixx=0; ixx<partonsToMatch_.size(); ixx++) {
// If the progenitor particle is not a heavy
// quark we delete it and its descendents.
if(abs(partonsToMatch_[ixx]->id())<4||abs(partonsToMatch_[ixx]->id())>6) {
preshowerFSPsToDelete_.push_back(partonsToMatch_[ixx]);
tmpList_.clear();
getDescendents(partonsToMatch_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
// If the progenitor is a b quark from a top decay drop
// it & it's descendents too!
} else if(abs(partonsToMatch_[ixx]->id())==5&&
partonsToMatch_[ixx]->parents().size()>0&&
abs(partonsToMatch_[ixx]->parents()[0]->id())==6) {
preshowerFSPsToDelete_.push_back(partonsToMatch_[ixx]);
tmpList_.clear();
getDescendents(partonsToMatch_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
// If (it's a hvy quark not from a top decay and) it has a W/Z/H
// as a parent [ditto].
} else if(partonsToMatch_[ixx]->parents().size()>0&&
(abs(partonsToMatch_[ixx]->parents()[0]->id())==23||
abs(partonsToMatch_[ixx]->parents()[0]->id())==24||
abs(partonsToMatch_[ixx]->parents()[0]->id())==25)) {
preshowerFSPsToDelete_.push_back(partonsToMatch_[ixx]);
tmpList_.clear();
getDescendents(partonsToMatch_[ixx]);
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
showeredFSPsToDelete_.push_back(tmpList_[jxx]);
}
}
// Now do the necessary deleting from partonsToMatch_ and
// particlesToCluster_.
for(unsigned int ixx=0; ixx<preshowerFSPsToDelete_.size(); ixx++) {
for(unsigned int jxx=0; jxx<partonsToMatch_.size(); jxx++) {
if(preshowerFSPsToDelete_[ixx]==partonsToMatch_[jxx]) {
partonsToMatch_.erase(partonsToMatch_.begin()+jxx);
break;
}
}
}
for(unsigned int ixx=0; ixx<showeredFSPsToDelete_.size(); ixx++) {
for(unsigned int jxx=0; jxx<particlesToCluster_.size(); jxx++) {
if(showeredFSPsToDelete_[ixx]==particlesToCluster_[jxx]) {
particlesToCluster_.erase(particlesToCluster_.begin()+jxx);
break;
}
}
}
// Now we return to get the decaying top quarks and any
// radiation they produced.
ParticleVector intermediates(lastXCombPtr()->subProcess()->intermediates());
for(unsigned int ixx=0; ixx<intermediates.size(); ixx++) {
if(abs(intermediates[ixx]->id())==6) {
partonsToMatch_.push_back(intermediates[ixx]);
tmpList_.clear();
getTopRadiation(partonsToMatch_.back());
for(unsigned int jxx=0; jxx<tmpList_.size(); jxx++)
particlesToCluster_.push_back(tmpList_[jxx]);
}
}
// If there are any heavy quark progenitors we have to remove
// the final (showered) instance of them from particlesToCluster.
ParticleVector evolvedHeavyQuarks;
for(unsigned int ixx=0; ixx<partonsToMatch_.size(); ixx++) {
if(abs(partonsToMatch_[ixx]->id())>=4&&abs(partonsToMatch_[ixx]->id())<=6) {
theProgenitor = partonsToMatch_[ixx];
// Follow the heavy quark line down to where it stops branching.
while(theProgenitor->children().size()>0) {
theLastProgenitor = theProgenitor;
for(unsigned int jxx=0; jxx<theProgenitor->children().size(); jxx++) {
if(theProgenitor->children()[jxx]->id()==theProgenitor->id())
theProgenitor=theProgenitor->children()[jxx];
}
// If the progenitor had children but none of them had
// the same particle id as it, then it must have undergone
// a decay rather than a branching, i.e. it is the end of
// the evolution line, so,
if(theProgenitor==theLastProgenitor) break;
}
evolvedHeavyQuarks.push_back(theProgenitor);
}
}
// Now delete the evolved heavy quark from the particlesToCluster.
for(unsigned int ixx=0; ixx<evolvedHeavyQuarks.size(); ixx++) {
for(unsigned int jxx=0; jxx<particlesToCluster_.size(); jxx++) {
if(evolvedHeavyQuarks[ixx]==particlesToCluster_[jxx]) {
particlesToCluster_.erase(particlesToCluster_.begin()+jxx);
break;
}
}
}
return;
}
void AlpGenHandler::getPreshowerParticles() {
// LH file initial-state partons:
preshowerISPs_ = lastXCombPtr()->subProcess()->incoming();
// LH file final-state partICLEs:
preshowerFSPs_ = lastXCombPtr()->subProcess()->outgoing();
return;
}
void AlpGenHandler::getShoweredParticles() {
// Post-shower initial-state hadrons:
showeredISHs_ = eventHandler()->currentEvent()->incoming();
// Post-shower initial-state partons:
for(unsigned int ixx=0; ixx<(showeredISHs_.first)->children().size(); ixx++)
if(((showeredISHs_.first)->children()[ixx]->id())<6||
((showeredISHs_.first)->children()[ixx]->id())==21)
showeredISPs_.first=(showeredISHs_.first)->children()[ixx];
for(unsigned int ixx=0; ixx<(showeredISHs_.second)->children().size(); ixx++)
if(((showeredISHs_.second)->children()[ixx]->id())<6||
((showeredISHs_.second)->children()[ixx]->id())==21)
showeredISPs_.second=(showeredISHs_.second)->children()[ixx];
// Post-shower final-state partICLEs plus remnants (to be removed later):
showeredFSPs_ = eventHandler()->currentEvent()->getFinalState();
// Post-shower final-state remnants:
for(unsigned int ixx=0; ixx<showeredFSPs_.size(); ixx++) {
if(showeredFSPs_[ixx]->PDGName()=="Rem:p+"||
showeredFSPs_[ixx]->PDGName()=="Rem:pbar-") {
if(showeredFSPs_[ixx]->parents()[0]->parents()[0]==
showeredISHs_.first)
showeredRems_.first=showeredFSPs_[ixx];
else if(showeredFSPs_[ixx]->parents()[0]->parents()[0]==
showeredISHs_.second)
showeredRems_.second=showeredFSPs_[ixx];
}
}
// Now delete found remnants from the showeredFSPs vector for consistency.
for(unsigned int ixx=0; ixx<showeredFSPs_.size(); ixx++)
if(showeredFSPs_[ixx]->PDGName()=="Rem:p+")
showeredFSPs_.erase(showeredFSPs_.begin()+ixx);
for(unsigned int ixx=0; ixx<showeredFSPs_.size(); ixx++)
if(showeredFSPs_[ixx]->PDGName()=="Rem:pbar-")
showeredFSPs_.erase(showeredFSPs_.begin()+ixx);
sort(showeredFSPs_.begin(),showeredFSPs_.end(),recordEntry);
return;
}
void AlpGenHandler::doSanityChecks(int debugLevel) {
// When checking momentum conservation in the form
// p_in - p_out, any momentum component bigger / less
// than + / - epsilon will result in the p_in - p_out
// vector being flagged as "non-null", triggering a
// warning that momentum conservation is violated.
Energy epsilon(0.5*GeV);
if(debugLevel>=5) epsilon=1e-9*GeV;
// Print out what was found for the incoming and outgoing
// partons in the lastXCombPtr regardless.
if(debugLevel>=5) {
cout << "\n\n\n\n";
cout << "****************************************************" << endl;
cout << " The following are the hard subprocess momenta from " << "\n"
<< " lastXCombPtr and should be basically identical to " << "\n"
<< " the input LH file momenta." << "\n\n";
cout << " Incoming particles:" << "\n"
<< *(preshowerISPs_.first) << "\n"
<< *(preshowerISPs_.second) << endl;
cout << " Outgoing particles:" << endl;
for(unsigned int ixx=0; ixx<preshowerFSPs_.size(); ixx++)
cout << *(preshowerFSPs_[ixx]) << endl;
}
// Print out what was found for the incoming and outgoing
// partons after the shower.
if(debugLevel>=5) {
cout << "\n\n";
cout << "****************************************************" << endl;
cout << " The following are the particles left at the end of" << "\n"
<< " the showering step." << "\n\n";
cout << " Incoming hadrons:" << "\n"
<< *(showeredISHs_.first) << "\n"
<< *(showeredISHs_.second) << endl;
cout << " Incoming partons:" << "\n"
<< *(showeredISPs_.first) << "\n"
<< *(showeredISPs_.second) << endl;
cout << " Outgoing partons:" << endl;
for(unsigned int ixx=0; ixx<showeredFSPs_.size(); ixx++)
cout << *(showeredFSPs_[ixx]) << endl;
cout << " Outgoing remnants:" << "\n"
<< *(showeredRems_.first) << "\n"
<< *(showeredRems_.second) << endl;
}
// Check if we correctly identified all initial and final-state
// particles by testing momentum is conserved.
if(debugLevel>=4) {
Lorentz5Momentum tmpMom;
tmpMom += showeredISPs_.first->momentum();
tmpMom += showeredISPs_.second->momentum();
for(unsigned int ixx=0; ixx<showeredFSPs_.size(); ixx++)
tmpMom -= showeredFSPs_[ixx]->momentum();
if(!isMomLessThanEpsilon(tmpMom,epsilon))
cout << "Total parton mom.in - total parton mom.out = "
<< tmpMom/GeV << endl;
tmpMom = showeredISHs_.first->momentum()
- showeredRems_.first->momentum() -showeredISPs_.first->momentum();
if(!isMomLessThanEpsilon(tmpMom,epsilon))
cout << "First p_hadron-p_remnant-p_incoming " << tmpMom/GeV << endl;
tmpMom = showeredISHs_.second->momentum()
- showeredRems_.second->momentum()-showeredISPs_.second->momentum();
if(!isMomLessThanEpsilon(tmpMom,epsilon))
cout << "Second p_hadron-p_remnant-p_incoming " << tmpMom/GeV << endl;
}
// Check if what we found to be the remnant is consistent with
// what we identified as the parent incoming hadron i.e. p+
// goes with Rem:p+ and pbar- goes with Rem:pbar-.
if(debugLevel>=0) {
string tmpString;
tmpString=showeredRems_.first->PDGName();
tmpString=tmpString.substr(tmpString.find_first_of(":")+1,
string::npos);
if(showeredISHs_.first->PDGName()!=tmpString) {
cout << "AlpGenHandler::showerHardProcessVeto" << "\n"
<< "Fatal error in pairing of remnant and parent hadron." << "\n"
<< "Remnant = " << *(showeredRems_.first) << "\n"
<< "Parent hadron = " << *(showeredISHs_.first)
<< endl;
cout << showeredISHs_.first->PDGName() << endl;
cout << tmpString << endl;
}
tmpString=showeredRems_.second->PDGName();
tmpString=tmpString.substr(tmpString.find_first_of(":")+1,
string::npos);
if(showeredISHs_.second->PDGName()!=tmpString) {
cout << "AlpGenHandler::showerHardProcessVeto" << "\n"
<< "Fatal error in pairing of remnant and parent hadron." << "\n"
<< "Remnant = " << *(showeredRems_.second) << "\n"
<< "Parent hadron = " << *(showeredISHs_.second)
<< endl;
cout << showeredISHs_.second->PDGName() << endl;
cout << tmpString << endl;
}
}
return;
}
void AlpGenHandler::printMomVec(vector<Lorentz5Momentum> momVec) {
cout << "\n\n";
// Label columns.
printf("%5s %9s %9s %9s %9s %9s %9s %9s %9s %9s\n",
"jet #",
"px","py","pz","E",
"eta","phi","pt","et","mass");
// Print out the details for each jet
for (unsigned int ixx=0; ixx<momVec.size(); ixx++) {
printf("%5u %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
ixx,
double(momVec[ixx].x()/GeV),double(momVec[ixx].y()/GeV),
double(momVec[ixx].z()/GeV),double(momVec[ixx].t()/GeV),
double(momVec[ixx].eta()) ,double(momVec[ixx].phi()),
double(momVec[ixx].perp()/GeV),
double(momVec[ixx].et()/GeV),
double(momVec[ixx].m()/GeV));
}
}
Energy AlpGenHandler::etclusran_(double petc) {
return (((2 * epsetclus_)/M_PI) * asin(2 * petc - 1) + etclusmean_);
}
diff --git a/Contrib/AlpGen/AlpGenToLH.cc b/Contrib/AlpGen/AlpGenToLH.cc
--- a/Contrib/AlpGen/AlpGenToLH.cc
+++ b/Contrib/AlpGen/AlpGenToLH.cc
@@ -1,1533 +1,1402 @@
//A few standard headers
#include <iostream>
#include <sstream>
#include <cstring>
#include <fstream>
#include <cmath>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iomanip>
using namespace std;
double sqr(double x);
inline int nInt(double x) {
int theCeiling=int(ceil(x));
int theFloor=int(floor(x));
if((theCeiling-theFloor!=1&&theCeiling!=theFloor)
||theCeiling-x>1.0||x-theFloor>1.0||x<theFloor||x>theCeiling) {
cout << "nInt:\n"
<< "Fatal double to integer conversion error.\n"
<< "input double = " << x << "\n"
<< "integer ceiling = " << theCeiling << "\n"
<< "integer floor = " << theFloor << "\n"
<< "Quitting ...";
exit(1);
}
return (theCeiling-x) < (x-theFloor) ? theCeiling : theFloor;
}
int ndnsToLHAPDF(int ndns);
-string ndnsToLHAPDF_str(int ndns);
-
-
double parstrToparval(string varName,
vector<string> * parstrPtr,
vector<double> * parvalPtr);
void doIndividualHardProcessAssignments(int ihrd , double * nup,
vector<double> * idup , vector<double> * istup,
vector<double> * mothup1, vector<double> * mothup2,
vector<double> * icolup1, vector<double> * icolup2,
vector<vector<double> > * pup,
vector<double> masses , int itopprc);
//*****************************//
//*****************************//
//*****************************//
// //
// ATTENTION!!!! //
// ATTENTION!!!! //
// ATTENTION!!!! //
// //
// Remember to uncomment all //
// of the currently commented //
// commands outputting to //
// the HW++ input file for //
// the variables not yet //
// declared and interfaced //
// in the AlpGenHandler!! //
// These should only be the //
// ones commented out by _4_ //
// consecutive forward slashes //
// '////' in the function //
// writeHWPPinFile(...) //
// //
// These are only commented //
// as the AlpGenHandler isn't //
// ready for them yet! //
// //
//*****************************//
//*****************************//
//*****************************//
void writeHWPPinFile(string prefix, int ihrd, int unwev,
int lhapdf, int idbmup0, int idbmup1, int idwtup,
double aqcdup, int nloop,
vector<double> * massesPtr,
vector<double> * parvalPtr,
vector<string> * parstrPtr);
string trim(string theString);
int main(int argc, char *argv[]) {
bool usePowhegBoxConventions(true); // Control
int debugging(3); // To validate
cout << "\n";
cout << "------------------------------------------------------------------\n";
cout << " AlpGenToLH: Convert Alpgen Les Houches to Herwig Les Houches \n";
cout << " v2.0-beta \n";
cout << "------------------------------------------------------------------\n";
cout << "\n";
char* prefix;
if(argv[1]) { prefix = argv[1]; } else {
cout << "Use: ./AlpGenToLH [input string] [number of events (optional)]\n"; exit(1);
cout << "Note: As of version 2, the .stat and _unw.par files are "
<< "required to read the generation parameters.\n";
}
int maxevents(0); int eventcount(0);
if(argc>2) { maxevents=(atoi(argv[2])); }
string lheFilename = string(prefix) + string(".lhe");
string unwFilename = string(prefix) + string(".unw");
string unwparFilename = string(prefix) + string("_unw.par");
string statFilename = string(prefix) + string(".stat");
cout << "Opening input files ...\n";
cout << "-----------------------\n";
cout << "Unweighted events in " << unwFilename << ".\n"
<< "Generation settings in "
<< unwparFilename << " and " << statFilename << ".\n\n";
ifstream unwStream;
ifstream unwparStream;
ifstream statStream;
ofstream lheStream;
unwStream.open(unwFilename.c_str());
unwparStream.open(unwparFilename.c_str());
statStream.open(statFilename.c_str());
lheStream.open(lheFilename.c_str());
if(!unwStream) {
cerr << "error: Failed to open input file " << unwFilename << "\n";
exit(1);
}
if(!unwparStream) {
cerr << "error: Failed to open input file " << unwparFilename << "\n";
exit(1);
}
if(!statStream) {
cerr << "error: Failed to open input file " << statFilename << "\n";
exit(1);
}
// ******************************************************************** //
// Dump the AlpGen *_unw.par file into the LH header (it's not so big). //
// ******************************************************************** //
string tmpString;
lheStream << "<LesHouchesEvents version =\"1.0\">\n";
lheStream << "<!--\n";
lheStream << "File generated using AlpGen and converted with AlpGenToLH \n";
while(unwparStream) {
getline(unwparStream,tmpString);
lheStream << tmpString << "\n";
}
lheStream << "\n\n\n" << "-->\n";
unwparStream.close();
// ***************************************** //
// Read in all relevant info from *_unw.par. //
// ***************************************** //
int ihrd; // AlpGen convention hard process code.
double mc,mb,mt,mw,mz,mh; // C, B, Top, W, Z & Higgs mass from *_unw.par
double avgwgt,errwgt; // Average weight and its error.
int unwev; // Number of unweighted events.
double totlum; // Effective luminosity.
vector<double> parval(200,-999.0); // AlpGen parameters.
vector<string> parstr(200,"----"); // AlpGen parameter (variable) names.
vector<double> alpgenParticleMasses;
unwparStream.open(unwparFilename.c_str());
while(unwparStream) {
getline(unwparStream,tmpString);
if(tmpString.find("hard process code") != string::npos) {
tmpString=tmpString.substr(0,tmpString.find("!"));
tmpString=trim(tmpString);
ihrd=atoi(tmpString.c_str());
}
if(tmpString.find("mc,mb,mt,mw,mz,mh") != string::npos) {
tmpString=trim(tmpString.substr(0,tmpString.find("!")));
mc=atof((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
alpgenParticleMasses.push_back(mc);
tmpString=trim(tmpString.substr(tmpString.find_first_of(" ")));
mb=atof((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
alpgenParticleMasses.push_back(mb);
tmpString=trim(tmpString.substr(tmpString.find_first_of(" ")));
mt=atof((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
alpgenParticleMasses.push_back(mt);
tmpString=trim(tmpString.substr(tmpString.find_first_of(" ")));
mw=atof((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
alpgenParticleMasses.push_back(mw);
tmpString=trim(tmpString.substr(tmpString.find_first_of(" ")));
mz=atof((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
alpgenParticleMasses.push_back(mz);
tmpString=trim(tmpString.substr(tmpString.find_first_of(" ")));
mh=atof((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
alpgenParticleMasses.push_back(mh);
}
if(tmpString.find("Crosssection +- error (pb)") != string::npos) {
tmpString=trim(tmpString.substr(0,tmpString.find("!")));
avgwgt=atof(trim(tmpString.substr(0,tmpString.find(" "))).c_str());
errwgt=atof(trim(tmpString.substr(tmpString.find(" "))).c_str());
}
if(tmpString.find("unwtd events, lum (pb-1)") != string::npos) {
tmpString=trim(tmpString.substr(0,tmpString.find("!")));
unwev=atoi(trim(tmpString.substr(0,tmpString.find(" "))).c_str());
totlum=atof(trim(tmpString.substr(tmpString.find(" "))).c_str());
}
}
if(maxevents > unwev) {
cout << "-------------------------------\n";
cout << "requested " << maxevents << " > " << unwev << " (contained in file), will use all events.\n"; maxevents = 0; }
if(debugging>=4) {
cout << "\nDebugging initial reading of *_unw.par:\n";
cout << "ihrd = " << ihrd << "\n";
cout << "mc,mb,mt,mw,mz,mh = "
<< mc << " " << mb << " "
<< mt << " " << mw << " "
<< mz << " " << mh << "\n";
cout << "Cross section +/- error = "
<< avgwgt << " +/- " << errwgt << "\n";
cout << "Number of unweighted events = " << unwev << "\n";
cout << "Effective luminosity = " << totlum << "\n";
}
unwparStream.close();
unwparStream.open(unwparFilename.c_str());
int index;
while(unwparStream) {
getline(unwparStream,tmpString);
if(tmpString.find("!")==string::npos||
tmpString.find("hard process code")!=string::npos||
tmpString.find("mc,mb,mt,mw,mz,mh")!=string::npos||
tmpString.find("Crosssection +- error (pb)")!=string::npos||
tmpString.find("unwtd events, lum (pb-1)")!=string::npos) continue;
tmpString=trim(tmpString);
if(debugging>=4) cout << "\nDebugging reading paramters in *_unw.par:\n";
if(debugging>=4) cout << "File says: " << tmpString << "\n";
index = atoi((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
tmpString=trim(tmpString.substr(tmpString.find_first_of(" ")));
parval[index]=atof((tmpString.substr(0,tmpString.find_first_of(" "))).c_str());
tmpString=trim(tmpString.substr(tmpString.find_first_of("!")+1));
parstr[index]=tmpString;
if(debugging>=4) cout << "We say: "
<< index << " "
<< parval[index] << " "
<< parstr[index] << "\n\n\n\n\n";
}
unwparStream.close();
// Variables defined in parval array read from *_unw.par:
// PDG codes for the beam particles.
int idbmup[2]={0,0};
if(parstrToparval("ih1",&parstr,&parval)==1) idbmup[0] = 2212;
else if(parstrToparval("ih1",&parstr,&parval)==-1) idbmup[0] = -2212;
else idbmup[0] = 2212;
if(parstrToparval("ih2",&parstr,&parval)==1) idbmup[1] = 2212;
else if(parstrToparval("ih2",&parstr,&parval)==-1) idbmup[1] = -2212;
else idbmup[1] = 2212;
// Energies of the beam particles --- implementation implicitly assumes
// these are equal!
double ebmup[2]={0,0};
ebmup[0]=parstrToparval("ebeam",&parstr,&parval);
ebmup[1]=ebmup[0];
// LH accord pdf info variables for <init> block:
int pdfgup[2];
pdfgup[0]=-1; // Simply set to 1 as in POWHEG-BOX.
pdfgup[1]=-1;
int pdfsup[2];
// LHAPDF index: (note in POWHEG-BOX it is set to just -1).
pdfsup[0]=ndnsToLHAPDF(int(parstrToparval("ndns",&parstr,&parval)));
pdfsup[1]=pdfsup[0];
// LH accord flag defining weight scheme:
// N.B. AlpGen alpsho.f UPINIT uses idwtup = 3 (this is likely better from the
// point of view of combining events of diff multiplicity together in real life
// i.e. in ATLAS - so we should probably use it!).
int idwtup( 3); // As in POWHEG-BOX withnegweights 0 mode: unit wgts +1 only.
// int idwtup(-4); // As in POWHEG-BOX withnegweights 1 mode: +/- |xsecup| wgts only.
// Number of processes in the file (assume all one process as
// with alpsho.f UPINIT).
int nprup(1);
// Cross section, it's error, the maximum weight in the file.
double xsecup,xerrup,xmaxup;
xsecup = avgwgt;
xerrup = errwgt;
xmaxup = xsecup;
// Process id code (to be augmented by jet multiplicity - see just below).
int lprup(ihrd*100);
// We augment the process code (for the LH file only) by the number of
// (light) jets, just in case we end up connecting many different files
// to the shower MC in parallel (otherwise it likely won't distinguish
// between X+0,1,2,3,...,n jet processes).
int njets(int(parstrToparval("njets",&parstr,&parval)));
lprup+=njets;
// Write out some bits of info to the screen.
cout << "No. of jets: " << njets << "\n";
cout << "Total xsec in pb (all processes): " << scientific
<< xsecup << " +/- " << xerrup << "\n\n";
// NOW write out <init> block:
lheStream << "<init>\n";
lheStream << setw(9) << idbmup[0];
lheStream << setw(9) << idbmup[1];
lheStream << scientific << setprecision(5) << setw(13) << ebmup[0];
lheStream << scientific << setprecision(5) << setw(13) << ebmup[1];
lheStream << setw(7) << pdfgup[0];
lheStream << setw(7) << pdfgup[1];
if(usePowhegBoxConventions) {
lheStream << setw(7) << -1;
lheStream << setw(7) << -1;
} else {
lheStream << setw(7) << pdfsup[0];
lheStream << setw(7) << pdfsup[1];
}
lheStream << setw(7) << idwtup;
lheStream << setw(7) << nprup << "\n";
lheStream << scientific << setprecision(5) << setw(13) << xsecup;
lheStream << scientific << setprecision(5) << setw(13) << xerrup;
if(usePowhegBoxConventions)
lheStream << scientific << setprecision(5) << setw(13) << 1.0;
else // else put in more info (xmaxup=xsecup).
lheStream << scientific << setprecision(5) << setw(13) << xmaxup;
lheStream << setw(7) << lprup << "\n";
lheStream << "</init>\n";
// ************************************************* //
// All done with the init section of the LH file! //
// ************************************************* //
// ***************************************************************** //
// To write the HW++ .in file we have everything we could possibly //
// want except maybe the QCD coupling and no. of loops for running. //
// These are the only numbers we get / use from *.stat now. //
// ***************************************************************** //
double aqedup(-999),aqedStat(-999);
double aqcdup(-999),aqcdStat(-999);
int nloop(-999);
// Fish around for the QCD and QED alphas in .stat.
while(statStream) {
getline(statStream,tmpString);
if(tmpString.find("as(MZ)") != string::npos) {
aqcdup=atof(trim(tmpString.substr(tmpString.find_last_of("=")+1,
tmpString.length())).c_str());
tmpString=trim(tmpString.substr(tmpString.find_first_of("nloop=")));
tmpString=trim(tmpString.substr(tmpString.find_first_of(" ")));
tmpString=trim(tmpString.substr(0,tmpString.find_first_of("]")));
nloop=atoi(tmpString.c_str());
}
if(tmpString.find("aem(mZ)") != string::npos) {
tmpString=tmpString.substr(tmpString.find("aem(mZ)="));
tmpString=tmpString.substr(tmpString.find_first_of(" "));
tmpString=trim(tmpString);
aqedup=atof(tmpString.c_str());
aqedup=1/aqedup;
}
}
statStream.close();
aqedStat=aqedup;
aqcdStat=aqcdup;
// Write out a couple more bits of info to the screen.
cout << "aqcdup [as(MZ)] from stat file: " << aqcdup << "\n";
cout << "nloop for as from stat file : " << nloop << "\n";
cout << "aqedup [inverse] from stat file: " << 1/aqedup << "\n";
cout << "\n";
writeHWPPinFile(prefix,ihrd,unwev,pdfsup[0], idbmup[0], idbmup[1], idwtup,
aqcdup,nloop,
&alpgenParticleMasses,
&parval,&parstr);
// *********************************************************** //
// All done writing the HW++ .in file! //
// *********************************************************** //
// *********************************************************** //
// Start reading AlpGen events and writing them as LH events: //
// *********************************************************** //
int nupMax(20);
// First line of an event contains:
double nup(0),idprup(0),xwgtup(0),scalup(0);
// Subsequent lines for particle content contain:
vector<double> idup,istup;
vector<double> mothup1,mothup2; // WARNING: not implemented ... YET!
vector<double> icolup1,icolup2;
vector<double> vtimup,spinup; // WARNING: not implemented (but safe).
vector<vector<double> > pup;
pup.resize(5);
for (int ixx = 0; ixx <= 4; ++ixx)
pup[ixx].resize(nupMax);
// Initialise pup matrix (not really necessary):
for(unsigned int jup=0; jup < nupMax; jup++)
for(unsigned int ixx=0; ixx<5; ixx++) pup[ixx][jup]=0;
// Control reading AlpGen file:
int iup(0);
int counter(0);
bool readInWholeEvent(false),beginNewEvent(true);
double stringdoub;
// Needed as input to doIndividualHardProcessAssignments only:
int itopprc(nInt(parstrToparval("itopprc",&parstr,&parval)));
while(unwStream && (eventcount < maxevents || maxevents==0)) { // So long as we haven't hit the EOF do ...
if(beginNewEvent) {
// Rest / set control variables:
beginNewEvent=false;
readInWholeEvent=false;
counter=0;
iup=0;
// Reset variables for first line of LH event:
nup=0; idprup=0; xwgtup=0; scalup=0; aqedup=0; aqcdup=0;
// Reset variables for all individual particles in LH event:
idup.clear() ; istup.clear();
mothup1.clear(); mothup2.clear();
icolup1.clear(); icolup2.clear();
vtimup.clear() ; spinup.clear();
for(unsigned int jup=0; jup < nupMax; jup++)
for(unsigned int ixx=0; ixx<5; ixx++) pup[ixx][jup]=0;
}
// Read in next thing starting from last position in
// the file (int/real) as a double
unwStream >> stringdoub;
// counter counts the number of numbers read-in for a given
// event. On starting to read a new event counter will be 0.
counter++;
switch (counter) {
case 1: if(int(stringdoub)!=0) {
// if(int(stringdoub)%100==0)
// cout << "Processed " << fixed << setprecision(0)
// << stringdoub/unwev*100
// << " % of events ..." << "\r" << flush;
}
break;
case 2: idprup = stringdoub; break;
case 3: nup = stringdoub; break;
case 4: xwgtup = stringdoub; break;
case 5: scalup = stringdoub; break;
// N.B. There are no aqedup / aqcdup variables from AlpGen.
// Initial state particle +z direction:
case 6: idup.push_back(stringdoub) ;
istup.push_back(-1); break;
case 7: icolup1.push_back(stringdoub);
mothup1.push_back(0); break; // ATTENTION: not given by AlpGen
case 8: icolup2.push_back(stringdoub);
mothup2.push_back(0); break; // ATTENTION: not given by AlpGen
case 9: pup[2][iup]=stringdoub ;
pup[3][iup]=fabs(stringdoub) ; iup++ ; break;
// Initial state particle -z direction:
case 10: idup.push_back(stringdoub) ;
istup.push_back(-1); break;
case 11: icolup1.push_back(stringdoub);
mothup1.push_back(0); break; // ATTENTION: not given by AlpGen
case 12: icolup2.push_back(stringdoub);
mothup2.push_back(0); break; // ATTENTION: not given by AlpGen
case 13: pup[2][iup]=stringdoub;
pup[3][iup]=fabs(stringdoub) ; iup++ ; break;
}
if(debugging<5) idprup=lprup;
if(counter<14) continue;
// Final state particles:
if(counter==0+7*iup) idup.push_back(stringdoub);
// istup gets assigned later on to just -1/+1 (I.S. / F.S.).
if(counter==1+7*iup) { icolup1.push_back(stringdoub);
mothup1.push_back(1.); } // ATTENTION: not given by AlpGen
if(counter==2+7*iup) { icolup2.push_back(stringdoub);
mothup2.push_back(2.); } // ATTENTION: not given by AlpGen
if(counter==3+7*iup) pup[0][iup] = stringdoub;
if(counter==4+7*iup) pup[1][iup] = stringdoub;
if(counter==5+7*iup) pup[2][iup] = stringdoub;
if(counter==6+7*iup) pup[4][iup] = stringdoub;
if(counter==6+7*iup) istup.push_back(1.);
if(counter==6+7*iup) iup+=1;
if(counter==7*nup-1) readInWholeEvent = true;
for(int jup = 0; jup < nup; jup++) {
pup[3][jup] = sqrt( sqr(pup[4][jup]) + sqr(pup[0][jup])
+ sqr(pup[1][jup]) + sqr(pup[2][jup]) );
vtimup.push_back(0.); // ATTENTION: not implemented - so taking
spinup.push_back(9.); // POWHEG-BOX default values (should be v.safe).
}
// ***************************************************************** //
// Now consider assignments specific to individual hard processes: //
// ***************************************************************** //
if(readInWholeEvent)
doIndividualHardProcessAssignments(ihrd, &nup, &idup, &istup,
&mothup1 , &mothup2,
&icolup1 , &icolup2,
&pup ,
alpgenParticleMasses, itopprc);
if(readInWholeEvent) {
lheStream << "<event>\n";
if(debugging>=5) {
lheStream << nup << "\t" << idprup << "\t" << xwgtup << "\t"
<< scalup << "\t" << "0.007297352" << "\t" << "0.118\n";
} else {
// Bit about signing of xwgtup here is redundant as
// AlpGen only gives +ve weight events ...
double signOfXwgtup = xwgtup >= 0 ? 1 : -1;
xwgtup = idwtup==3 ? 1 : xsecup*signOfXwgtup;
// N.B. There are no aqedup / aqcdup variables from AlpGen
// events only the stat file has related information.
aqedup=aqedStat;
aqcdup=aqcdStat;
if(usePowhegBoxConventions) aqedup=-1;
lheStream << setw(7) << int(nup);
lheStream << setw(7) << int(idprup);
lheStream << scientific << setprecision(5) << setw(13) << xwgtup;
lheStream << scientific << setprecision(5) << setw(13) << scalup;
lheStream << scientific << setprecision(5) << setw(13) << aqedup;
lheStream << scientific << setprecision(5) << setw(13) << aqcdup;
lheStream << "\n";
}
for(int jup = 0; jup < nup; jup++) {
if(debugging>=5) {
lheStream << idup[jup] << "\t" << istup[jup] << "\t"
<< mothup1[jup] << "\t" << mothup2[jup] << "\t"
<< icolup1[jup] << "\t" << icolup2[jup] << "\t";
lheStream << pup[0][jup] << "\t" << pup[1][jup] << "\t"
<< pup[2][jup] << "\t" << pup[3][jup] << "\t"
<< pup[4][jup] << "\t";
lheStream << "0" << "\t" << "1\n";
} else {
if(icolup1[jup]!=0) icolup1[jup]+=500;
if(icolup2[jup]!=0) icolup2[jup]+=500;
lheStream << setw(8) << int(idup[jup]);
lheStream << setw(6) << int(istup[jup])
<< setw(6) << int(mothup1[jup])
<< setw(6) << int(mothup2[jup])
<< setw(6) << int(icolup1[jup])
<< setw(6) << int(icolup2[jup]);
lheStream << scientific << setprecision(9) << setw(17) << pup[0][jup];
lheStream << scientific << setprecision(9) << setw(17) << pup[1][jup];
lheStream << scientific << setprecision(9) << setw(17) << pup[2][jup];
lheStream << scientific << setprecision(9) << setw(17) << pup[3][jup];
lheStream << scientific << setprecision(9) << setw(17) << pup[4][jup];
lheStream << scientific << setprecision(5) << setw(13) << vtimup[jup];
lheStream << scientific << setprecision(3) << setw(11) << vtimup[jup];
lheStream << "\n";
}
}
lheStream << "</event>\n";
eventcount++;
cout << "Processed " << eventcount << " events ..." << "\r" << flush;
beginNewEvent=true;
}
}
cout << "\n\n";
if( maxevents!=0 ) {
cout << "All done (" << maxevents << " out of " << unwev << " events).\n";
} else {
cout << "All done (" << eventcount << " events).\n";
}
cout << "\n\n"
<< "Wrote a LH event file " << lheFilename
<< " and a HW++ MLM merging input file "
<< prefix+string(".in") << ".\n\n";
return 0;
}
inline double sqr(double x) { return x*x; }
int ndnsToLHAPDF(int ndns) {
// The information in this function is based on
// subroutine PRNTSF from alplib/alppdf.f, LHAPDF's
// PDFsets.index and, finally, the .stat output that
// results when the relevant ndns value is entered
// in the input file.
string Set("no PDF set found");
double Lambda_4(0),Lambda_5_2loop(0);
string Scheme("no PDF scheme");
int LHAPDFindex(-999);
string tmpString("");
if(ndns==1) {
Set = "CTEQ4M" ; Lambda_4 = 0.298 ; Lambda_5_2loop = 0.202 ; Scheme = "MS" ;
LHAPDFindex = 19150;
} else if(ndns==2) {
Set = "CTEQ4L" ; Lambda_4 = 0.298 ; Lambda_5_2loop = 0.202 ; Scheme = "MS" ;
LHAPDFindex = 19170;
} else if(ndns==3) {
Set = "CTEQ4HJ" ; Lambda_4 = 0.298 ; Lambda_5_2loop = 0.202 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==4) {
Set = "CTEQ5M" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex = 19050;
} else if(ndns==5) {
Set = "CTEQ5L" ; Lambda_4 = 0.192 ; Lambda_5_2loop = 0.144 ; Scheme = "MS" ;
LHAPDFindex = 19070;
} else if(ndns==6) {
Set = "CTEQ5HJ" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==7) {
Set = "CTEQ6M" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex= 10050;
} else if(ndns==8) {
Set = "CTEQ6L" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex = 10041;
} else if(ndns==9) {
Set = "CTEQ6L1" ; Lambda_4 = 0.215 ; Lambda_5_2loop = 0.167 ; Scheme = "MS" ;
LHAPDFindex = 10042;
} else if(ndns>=10&&ndns<=50) {
Set = "CTEQ6xx" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex = 10150+(ndns-10);
} else if(ndns==101) {
Set = "MRST99" ; Lambda_4 = 0.321 ; Lambda_5_2loop = 0.220 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==102) {
Set = "MRST01" ; Lambda_4 = 0.342 ; Lambda_5_2loop = 0.239 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==103) {
Set = "MRST01" ; Lambda_4 = 0.310 ; Lambda_5_2loop = 0.214 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==104) {
Set = "MRST01" ; Lambda_4 = 0.378 ; Lambda_5_2loop = 0.267 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==105) {
Set = "MRST01J" ; Lambda_4 = 0.378 ; Lambda_5_2loop = 0.267 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==106) {
Set = "MRST02LO" ; Lambda_4 = 0.215 ; Lambda_5_2loop = 0.167 ; Scheme = "MS" ;
LHAPDFindex = -99999;
} else if(ndns==201) {
Set = "MSTW2008lo" ; Lambda_4 = 0.322 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
LHAPDFindex = 21000;
} else if(ndns==202) {
Set = "MSTW2008nlo" ; Lambda_4 = 0.365 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
LHAPDFindex = 21100;
} else if(ndns>=203&&ndns<=242) {
Set = "MSTW2008lo68cl"; Lambda_4 = 0.322 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
LHAPDFindex = 21000+(ndns-202);
} else if(ndns==243) {
Set = "MRST LO*" ; Lambda_4 = 0.365 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
LHAPDFindex = 20650;
} else if(ndns==244) {
Set = "MRST LO**" ; Lambda_4 = 0.280 ; Lambda_5_2loop = 0.190 ; Scheme = "MS" ;
LHAPDFindex = 20651;
} else if(ndns==301 ) {
Set = "CTQ6.6" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex = 10550;
} else if(ndns>=302&&ndns<=345) {
Set = "CTQ66" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex = 10550+(ndns-301);
} else if(ndns==346) {
Set = "CT09MC1" ; Lambda_4 = 0.215 ; Lambda_5_2loop = 0.167 ; Scheme = "MS" ;
LHAPDFindex = 10771;
} else if(ndns==347) {
Set = "CT09MC2" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
LHAPDFindex = 10772;
}
cout << "-------------------------------\n";
cout << "ndnsToLHAPDF found: \n";
cout << "PDF set = " << Set << "\n";
cout << "ndns index = " << ndns << "\n";
cout << "LHAPDF index = " << LHAPDFindex << "\n";
cout << "-------------------------------\n\n";
return LHAPDFindex;
}
-string ndnsToLHAPDF_str(int ndns) {
- // The information in this function is based on
- // subroutine PRNTSF from alplib/alppdf.f, LHAPDF's
- // PDFsets.index and, finally, the .stat output that
- // results when the relevant ndns value is entered
- // in the input file.
- string Set("no PDF set found");
- double Lambda_4(0),Lambda_5_2loop(0);
- string Scheme("no PDF scheme");
- int LHAPDFindex(-999);
- string tmpString("");
- string lhastring("");
-
- if(ndns==1) {
- Set = "CTEQ4M" ; Lambda_4 = 0.298 ; Lambda_5_2loop = 0.202 ; Scheme = "MS" ;
- LHAPDFindex = 19150;
- lhastring = "cteq6m";
- } else if(ndns==2) {
- Set = "CTEQ4L" ; Lambda_4 = 0.298 ; Lambda_5_2loop = 0.202 ; Scheme = "MS" ;
- LHAPDFindex = 19170;
- lhastring = "cteq4l";
- } else if(ndns==3) {
- Set = "CTEQ4HJ" ; Lambda_4 = 0.298 ; Lambda_5_2loop = 0.202 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- lhastring = "cteq4hj";
- } else if(ndns==4) {
- Set = "CTEQ5M" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex = 19050;
- lhastring = "cteq5m";
- } else if(ndns==5) {
- Set = "CTEQ5L" ; Lambda_4 = 0.192 ; Lambda_5_2loop = 0.144 ; Scheme = "MS" ;
- LHAPDFindex = 19070;
- lhastring = "cteq5l";
-
- } else if(ndns==6) {
- Set = "CTEQ5HJ" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- lhastring = "cteq5hj";
- } else if(ndns==7) {
- Set = "CTEQ6M" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex= 10050;
- lhastring = "cteq6m";
- } else if(ndns==8) {
- Set = "CTEQ6L" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex = 10041;
- lhastring = "cteq6l";
- } else if(ndns==9) {
- Set = "CTEQ6L1" ; Lambda_4 = 0.215 ; Lambda_5_2loop = 0.167 ; Scheme = "MS" ;
- LHAPDFindex = 10042;
- lhastring = "cteq6l1";
- } else if(ndns>=10&&ndns<=50) {
- Set = "CTEQ6xx" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex = 10150+(ndns-10);
- lhastring = "cteq6xx";
- } else if(ndns==101) {
- Set = "MRST99" ; Lambda_4 = 0.321 ; Lambda_5_2loop = 0.220 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- lhastring = "mrst99";
- } else if(ndns==102) {
- Set = "MRST01" ; Lambda_4 = 0.342 ; Lambda_5_2loop = 0.239 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- lhastring = "mrst01";
- } else if(ndns==103) {
- Set = "MRST01" ; Lambda_4 = 0.310 ; Lambda_5_2loop = 0.214 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- } else if(ndns==104) {
- Set = "MRST01" ; Lambda_4 = 0.378 ; Lambda_5_2loop = 0.267 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- lhastring = "mrst01";
- } else if(ndns==105) {
- Set = "MRST01J" ; Lambda_4 = 0.378 ; Lambda_5_2loop = 0.267 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- lhastring = "mrst01j";
- } else if(ndns==106) {
- Set = "MRST02LO" ; Lambda_4 = 0.215 ; Lambda_5_2loop = 0.167 ; Scheme = "MS" ;
- LHAPDFindex = -99999;
- lhastring = "mrst02lo";
- } else if(ndns==201) {
- Set = "MSTW2008lo" ; Lambda_4 = 0.322 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
- LHAPDFindex = 21000;
- } else if(ndns==202) {
- Set = "MSTW2008nlo" ; Lambda_4 = 0.365 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
- LHAPDFindex = 21100;
- lhastring = "mstw2008nlo";
- } else if(ndns>=203&&ndns<=242) {
- Set = "MSTW2008lo68cl"; Lambda_4 = 0.322 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
- LHAPDFindex = 21000+(ndns-202);
- lhastring = "mstw2008lo68cl";
- } else if(ndns==243) {
- Set = "MRST LO*" ; Lambda_4 = 0.365 ; Lambda_5_2loop = 0.255 ; Scheme = "MS" ;
- LHAPDFindex = 20650;
- lhastring = "MRST2007lomod";
- } else if(ndns==244) {
- Set = "MRST LO**" ; Lambda_4 = 0.280 ; Lambda_5_2loop = 0.190 ; Scheme = "MS" ;
- LHAPDFindex = 20651;
- lhastring = "MRSTMCal";
-
- } else if(ndns==301 ) {
- Set = "CTQ6.6" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex = 10550;
- lhastring = "cteq66";
- } else if(ndns>=302&&ndns<=345) {
- Set = "CTQ66" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex = 10550+(ndns-301);
- lhastring = "cteq66";
- } else if(ndns==346) {
- Set = "CT09MC1" ; Lambda_4 = 0.215 ; Lambda_5_2loop = 0.167 ; Scheme = "MS" ;
- LHAPDFindex = 10771;
- lhastring = "CT09MC1";
- } else if(ndns==347) {
- Set = "CT09MC2" ; Lambda_4 = 0.326 ; Lambda_5_2loop = 0.226 ; Scheme = "MS" ;
- LHAPDFindex = 10772;
- lhastring = "CT09MC2";
- }
-
- cout << "-------------------------------\n";
- cout << "ndnsToLHAPDF found: \n";
- cout << "PDF set = " << Set << "\n";
- cout << "ndns index = " << ndns << "\n";
- cout << "LHAPDF index = " << LHAPDFindex << "\n";
- cout << "-------------------------------\n\n";
- return lhastring;
-
-}
-
-
double parstrToparval(string varName,
vector<string> * parstrPtr,
vector<double> * parvalPtr) {
for(unsigned int index=0; index<parvalPtr->size(); index++)
if(varName==parstrPtr->at(index))
return parvalPtr->at(index);
return -999.0;
}
string trim(string theString) {
int endStr = theString.find_last_not_of(" ");
int beginStr = theString.find_first_not_of(" ");
if(beginStr==0&&endStr==theString.length()-1) return theString; // No lead / trail spaces.
theString = theString.substr(beginStr,endStr-beginStr+1);
return theString;
}
void writeHWPPinFile(string prefix, int ihrd, int unwev,
int lhapdf, int idbmup0, int idbmup1, int idwtup,
double aqcdup, int nloop,
vector<double> * massesPtr,
vector<double> * parvalPtr,
vector<string> * parstrPtr) {
ofstream hwpp;
hwpp.open(string(prefix+".in").c_str());
hwpp << "#############################################################\n";
hwpp << "# Create an event generator taking the default LHCGenerator #\n";
hwpp << "# as the starting point ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/Generators\n";
hwpp << "# Copy the default LHCGenerator with its settings to a new \n";
hwpp << "# which will be the basis of the one we use for showering: \n";
hwpp << "cp LHCGenerator theGenerator\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Create a LH event handler (set up & assigned below) ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/EventHandlers\n";
hwpp << "library LesHouches.so\n";
hwpp << "create ThePEG::LesHouchesEventHandler theLesHouchesHandler\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Create a LH reader (set up & assigned below) ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/EventHandlers\n";
hwpp << "#library BasicLesHouchesFileReader.so\n";
hwpp << "#create Herwig::BasicLesHouchesFileReader theLHReader\n";
hwpp << "library LesHouches.so\n";
hwpp << "create ThePEG::LesHouchesFileReader theLHReader\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Create an AlpGenHandler (set up & assigned below) ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/Shower\n";
hwpp << "library AlpGenHandler.so\n";
hwpp << "create Herwig::AlpGenHandler AlpGenHandler\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Create an LHAPDF (set up & assigned below) ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/Partons\n";
hwpp << "create ThePEG::LHAPDF thePDFset ThePEGLHAPDF.so\n";
hwpp << "\n";
hwpp << "############################################################\n";
hwpp << "# Create a cuts object ... #\n";
hwpp << "############################################################\n";
hwpp << "cd /Herwig/EventHandlers\n";
hwpp << "create ThePEG::Cuts /Herwig/Cuts/NoCuts\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Setup the LH event handler ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/EventHandlers\n";
hwpp << "insert theLesHouchesHandler:LesHouchesReaders 0 theLHReader\n";
if(idwtup==3) {
hwpp << "set theLesHouchesHandler:WeightOption UnitWeight\n";
} else if(idwtup==-3) {
hwpp << "set theLesHouchesHandler:WeightOption NegUnitWeight\n";
} else if(idwtup==4) {
hwpp << "set theLesHouchesHandler:WeightOption VarWeight\n";
} else {
hwpp << "set theLesHouchesHandler:WeightOption VarNegWeight\n";
}
hwpp << "set theLesHouchesHandler:PartonExtractor "
<< "/Herwig/Partons/QCDExtractor\n";
hwpp << "set theLesHouchesHandler:CascadeHandler "
<< "/Herwig/Shower/AlpGenHandler\n";
hwpp << "set theLesHouchesHandler:HadronizationHandler "
<< "/Herwig/Hadronization/ClusterHadHandler\n";
hwpp << "set theLesHouchesHandler:DecayHandler "
<< "/Herwig/Decays/DecayHandler\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Set up the Evolver to veto hard emissions > scalup ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/Shower\n";
hwpp << "# MaxTry 100 sets the maximum number of times to try \n";
hwpp << "# showering a given shower tree to 100. \n";
hwpp << "# HardVetoMode Yes to veto emissions with pT greater than pT_max.\n";
hwpp << "# HardVetoScaleSource Read means pT_max comes from hepeup.SCALUP.\n";
hwpp << "# This is what you need to set _along_with_ HardVetoMode Yes in \n";
hwpp << "# the case of Powheg external events _AND_ mc@nlo (we know this \n";
hwpp << "# from looking at the *MCinput file that mc@nlo generates). \n";
hwpp << "# MeCorrMode No turns off ME corrs. IntrinsicPtGaussian 2.2*GeV \n";
hwpp << "# is the RMS of intrinsic pT of Gaussian distribution: \n";
hwpp << "# 2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS) \n";
hwpp << "set Evolver:MaxTry 100\n";
hwpp << "set Evolver:HardVetoMode Yes\n";
hwpp << "set Evolver:HardVetoScaleSource Read\n";
hwpp << "set Evolver:HardVetoReadOption PrimaryCollision\n";
hwpp << "set Evolver:MECorrMode No\n";
hwpp << "# Intrinsic pT etc should be set as part of a tune i.e. it \n";
hwpp << "# should either be left alone (default) or set by reading in \n";
hwpp << "# one of the tunes before theGenerator is created by copying \n";
hwpp << "# LHCGenerator (second line of this file). The following \n";
hwpp << "# settings were extracted from LHC-UE-EE-3-CTEQ6L1.in - In \n";
hwpp << "# light of some bad experience with MPI we prefer to set \n";
hwpp << "# these here manually rather than read try to read that .in. \n";
if(idbmup0 == 2212 && idbmup1 == -2212) {
- hwpp << "#set /Herwig/UnderlyingEvent/KtCut:MinKT 2.26 \n";
- hwpp << "#set /Herwig/UnderlyingEvent/UECuts:MHatMin 4.52 \n";
- hwpp << "#set /Herwig/Shower/Evolver:IntrinsicPtGaussian 1.9*GeV \n";
+ hwpp << "set /Herwig/UnderlyingEvent/KtCut:MinKT 2.26 \n";
+ hwpp << "set /Herwig/UnderlyingEvent/UECuts:MHatMin 4.52 \n";
+ hwpp << "set /Herwig/Shower/Evolver:IntrinsicPtGaussian 1.9*GeV \n";
} else {
- hwpp << "#set /Herwig/UnderlyingEvent/KtCut:MinKT 2.752 \n";
- hwpp << "#set /Herwig/UnderlyingEvent/UECuts:MHatMin 5.504 \n";
- hwpp << "#set /Herwig/Shower/Evolver:IntrinsicPtGaussian 2.34*GeV \n";
+ hwpp << "set /Herwig/UnderlyingEvent/KtCut:MinKT 2.752 \n";
+ hwpp << "set /Herwig/UnderlyingEvent/UECuts:MHatMin 5.504 \n";
+ hwpp << "set /Herwig/Shower/Evolver:IntrinsicPtGaussian 2.34*GeV \n";
}
hwpp << "# Colour reconnection (re)settings \n";
- hwpp << "#set /Herwig/Hadronization/ColourReconnector:ColourReconnection Yes \n";
- hwpp << "#set /Herwig/Hadronization/ColourReconnector:ReconnectionProbability 0.61\n";
+ hwpp << "set /Herwig/Hadronization/ColourReconnector:ColourReconnection Yes \n";
+ hwpp << "set /Herwig/Hadronization/ColourReconnector:ReconnectionProbability 0.61\n";
hwpp << "# Colour Disrupt settings \n";
- hwpp << "#set /Herwig/Partons/RemnantDecayer:colourDisrupt 0.75 \n";
+ hwpp << "set /Herwig/Partons/RemnantDecayer:colourDisrupt 0.75 \n";
hwpp << "# Inverse hadron radius \n";
- hwpp << "#set /Herwig/UnderlyingEvent/MPIHandler:InvRadius 1.35 \n";
- hwpp << "#set /Herwig/UnderlyingEvent/MPIHandler:softInt Yes \n";
- hwpp << "#set /Herwig/UnderlyingEvent/MPIHandler:twoComp Yes \n";
- hwpp << "#set /Herwig/UnderlyingEvent/MPIHandler:DLmode 2 \n";
+ hwpp << "set /Herwig/UnderlyingEvent/MPIHandler:InvRadius 1.35 \n";
+ hwpp << "set /Herwig/UnderlyingEvent/MPIHandler:softInt Yes \n";
+ hwpp << "set /Herwig/UnderlyingEvent/MPIHandler:twoComp Yes \n";
+ hwpp << "set /Herwig/UnderlyingEvent/MPIHandler:DLmode 2 \n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Set up kinematics reconstructor (relevant only to mc@nlo) #\n";
hwpp << "#############################################################\n";
hwpp << "# Options for QTildeReconstructor - not needed for Powheg but\n";
hwpp << "# critical for mc@nlo. If using Powheg you may either leave \n";
hwpp << "# the next two settings as they are or comment them out as \n";
hwpp << "# you wish, for mc@nlo though you must leave them as they \n";
hwpp << "# are! ReconstructionOption General was the old default, it \n";
hwpp << "# ignores the colour structure for all processes - mc@nlo \n";
hwpp << "# will give you garbage unless you set this! \n";
hwpp << "# ReconstructionOption Colour is the new default - use the \n";
hwpp << "# colour structure of the process to determine the \n";
hwpp << "# reconstruction procedure. InitialInitialBoostOption \n";
hwpp << "# determines how the boost from the system before ISR to that\n";
hwpp << "# after ISR is applied. mc@nlo requires the old kinematics \n";
hwpp << "# reconstruction method: \n";
hwpp << "# InitialInitialBoostOption LongTransBoost - first apply a \n";
hwpp << "# longitudinal and then a transverse boost. Whereas the \n";
hwpp << "# default method now is InitialInitialBoostOption OneBoost - \n";
hwpp << "# apply one boost from old CMS to new CMS. Both options \n";
hwpp << "# should work with Powheg but probably it's best to use the \n";
hwpp << "# defaults in that case by simply commenting this setting. \n";
- hwpp << "#set KinematicsReconstructor:ReconstructionOption General \n";
- hwpp << "#set KinematicsReconstructor:InitialInitialBoostOption LongTransBoost\n";
+ hwpp << "set KinematicsReconstructor:ReconstructionOption General \n";
+ hwpp << "set KinematicsReconstructor:InitialInitialBoostOption LongTransBoost\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Set up the AlpGenHandler ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/Shower\n";
hwpp << "set AlpGenHandler:MPIHandler /Herwig/UnderlyingEvent/MPIHandler\n";
hwpp << "set AlpGenHandler:RemDecayer /Herwig/Partons/RemnantDecayer\n";
hwpp << "set AlpGenHandler:Evolver Evolver\n";
hwpp << "set AlphaQCD:AlphaMZ " << aqcdup << "\n";
hwpp << "set AlphaQCD:NumberOfLoops " << nloop << "\n";
hwpp << "set AlpGenHandler:ShowerAlpha AlphaQCD\n";
hwpp << "# Calorimeter granularity settings used by GetJet algorithm\n";
hwpp << "set AlpGenHandler:NoCellsInRapidity 100\n";
hwpp << "set AlpGenHandler:NoCellsInPhi 60\n";
// AlpGen hard process code.
hwpp << "# AlpGen hard process code.\n";
hwpp << "set AlpGenHandler:ihrd " << ihrd << "\n";
// Number of (light) jets.
int njets(int(parstrToparval("njets",parstrPtr,parvalPtr)));
hwpp << "# No. of light jets in AlpGen process (the \"extra\" ones).\n";
hwpp << "set AlpGenHandler:njets " << njets << "\n";
// Mimimum jet pT use for generation.
double ptjmin(parstrToparval("ptjmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:ptjmin " << ptjmin << "*GeV\n";
// Mimimum parton-parton R-sep used for generation.
double drjmin(parstrToparval("drjmin",parstrPtr,parvalPtr));
hwpp << "# Mimimum parton-parton R-sep used for generation.\n";
hwpp << "set AlpGenHandler:drjmin " << drjmin << "\n";
// Max |eta| for partons in generation.
double etajmax(parstrToparval("etajmax",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:etajmax " << etajmax << "\n";
// Also probably want these variables fed to AlpGenHandler too ---
// they get set in the alpsho.f AHspar routine (note the list below
// does not include some variables from AHspar because they are already
// included in the above eg the PDFs are already handled so I removed
// ndns and also ptjmin drjmin are written out for the AlpGenHandler above).
int ickkw(int(parstrToparval("ickkw",parstrPtr,parvalPtr)));
//// hwpp << "set AlpGenHandler:ickkw " << ickkw << "\n";
int ihvy(int(parstrToparval("ihvy",parstrPtr,parvalPtr)));
hwpp << "# heavy flavour in WQQ,ZQQ,2Q etc (4=c, 5=b, 6=t):\n";
hwpp << "set AlpGenHandler:ihvy " << ihvy << "\n";
int ihvy2(int(parstrToparval("ihvy2",parstrPtr,parvalPtr)));
//// hwpp << "set AlpGenHandler:ihvy2 " << ihvy2 << "\n";
int itopprc(nInt(parstrToparval("itopprc",parstrPtr,parvalPtr)));
//// hwpp << "set AlpGenHandler:itopprc " << itopprc << "\n";
int nw(int(parstrToparval("nw",parstrPtr,parvalPtr)));
if(ihrd==13) {
nw=1; // N.B. nw is reassigned in this way
if(itopprc>=3) nw=2; // by UPEVNT (after UPINIT).
}
//// hwpp << "set AlpGenHandler:nw " << nw << "\n";
int nz(int(parstrToparval("nz",parstrPtr,parvalPtr)));
//// hwpp << "set AlpGenHandler:nz " << nz << "\n";
int nh(int(parstrToparval("nh",parstrPtr,parvalPtr)));
hwpp << "# Number of Higgses in the AlpGen process:\n";
hwpp << "set AlpGenHandler:nh " << nh << "\n";
int nph(int(parstrToparval("nph",parstrPtr,parvalPtr)));
hwpp << "# Number of photons in the AlpGen process:\n";
hwpp << "set AlpGenHandler:nph " << nph << "\n";
double ptbmin(parstrToparval("ptbmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:ptbmin " << ptbmin << "\n";
double ptcmin(parstrToparval("ptcmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:ptcmin " << ptcmin << "\n";
double ptlmin(parstrToparval("ptlmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:ptlmin " << ptlmin << "\n";
double metmin(parstrToparval("metmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:metmin " << metmin << "\n";
double ptphmin(parstrToparval("ptphmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:ptphmin " << ptphmin << "\n";
double etabmax(parstrToparval("etabmax",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:etabmax " << etabmax << "\n";
double etacmax(parstrToparval("etacmax",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:etacmax " << etacmax << "\n";
double etalmax(parstrToparval("etalmax",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:etalmax " << etalmax << "\n";
double etaphmax(parstrToparval("etaphmax",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:etaphmax " << etaphmax << "\n";
double drbmin(parstrToparval("drbmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:drbmin " << drbmin << "\n";
double drcmin(parstrToparval("drcmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:drcmin " << drcmin << "\n";
double drlmin(parstrToparval("drlmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:drlmin " << drlmin << "\n";
double drphjmin(parstrToparval("drphjmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:drphjmin " << drphjmin << "\n";
double drphlmin(parstrToparval("drphlmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:drphlmin " << drphlmin << "\n";
double drphmin(parstrToparval("drphmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:drphmin " << drphmin << "\n";
double mllmin(parstrToparval("mllmin",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:mllmin " << mllmin << "\n";
double mllmax(parstrToparval("mllmax",parstrPtr,parvalPtr));
//// hwpp << "set AlpGenHandler:mllmax " << mllmax << "\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Set up the LH reader ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/EventHandlers\n";
hwpp << "set theLHReader:WeightWarnings false\n";
hwpp << "# Input event file name:\n";
hwpp << "set theLHReader:FileName " << prefix << ".lhe\n";
hwpp << "set theLHReader:MomentumTreatment RescaleEnergy\n";
hwpp << "# set theLHReader:IgnoreIDPRUP Yes\n";
hwpp << "set theLHReader:Cuts /Herwig/Cuts/NoCuts\n";
hwpp << "#set theLHReader:OverSampling ForbidOverSampling\n";
hwpp << "\n";
hwpp << "#############################################################\n";
hwpp << "# Set up the LHAPDF ... #\n";
hwpp << "#############################################################\n";
hwpp << "cd /Herwig/Partons\n";
hwpp << "# Don't try and find PDF index out from the LH file ...\n";
hwpp << "set /Herwig/EventHandlers/theLHReader:InitPDFs false\n";
hwpp << "# Instead set them explicitly here:\n";
- // hwpp << "set thePDFset:PDFNumber " << lhapdf << "\n";
hwpp << "set thePDFset:PDFNumber " << lhapdf << "\n";
-
hwpp << "set thePDFset:RemnantHandler HadronRemnants\n";
hwpp << "set /Herwig/EventHandlers/theLHReader:PDFA thePDFset\n";
hwpp << "set /Herwig/EventHandlers/theLHReader:PDFB thePDFset\n";
hwpp << "set /Herwig/Particles/p+:PDF thePDFset\n";
hwpp << "set /Herwig/Particles/pbar-:PDF thePDFset\n";
hwpp << "# The PDF for beam particles A/B - overrides particle's own "
<< "PDF above\n";
hwpp << "set /Herwig/Shower/AlpGenHandler:PDFA thePDFset\n";
hwpp << "set /Herwig/Shower/AlpGenHandler:PDFB thePDFset\n";
hwpp << "set /Herwig/Shower/ShowerHandler:PDFA thePDFset\n";
hwpp << "set /Herwig/Shower/ShowerHandler:PDFB thePDFset\n";
hwpp << "\n";
hwpp << "####################################################\n";
hwpp << "# Set up the generator ... #\n";
hwpp << "####################################################\n";
hwpp << "cd /Herwig/Generators\n";
hwpp << "set theGenerator:EventHandler "
<< "/Herwig/EventHandlers/theLesHouchesHandler\n";
hwpp << "set theGenerator:NumberOfEvents " << unwev << "\n";
hwpp << "set theGenerator:RandomNumberGenerator:Seed 31122001\n";
hwpp << "set theGenerator:PrintEvent 10\n";
hwpp << "set theGenerator:MaxErrors 10000\n";
hwpp << "\n";
hwpp << "###################################################################\n";
hwpp << "# ReDefine particle data like it is in the AlpGen parameter file. #\n";
hwpp << "###################################################################\n";
hwpp << "\ncd /Herwig/Particles/ \n";
// 'if' statements needed here to protect against mc<ms (i.e. if AlpGen has mc=0
// for example). If this occurs then the QCD coupling can't initialise and the
// HW++ read step fails (due to matching at flavour thresholds etc).
if(massesPtr->at(0)>1.0) {
hwpp << "set c:NominalMass " << massesPtr->at(0) << "*GeV\n";
hwpp << "set cbar:NominalMass " << massesPtr->at(0) << "*GeV\n";
}
// Ditto.
if(massesPtr->at(0)>4.0) {
hwpp << "set b:NominalMass " << massesPtr->at(1) << "*GeV\n";
hwpp << "set bbar:NominalMass " << massesPtr->at(1) << "*GeV\n";
}
hwpp << "set t:NominalMass " << massesPtr->at(2) << "*GeV\n";
hwpp << "set tbar:NominalMass " << massesPtr->at(2) << "*GeV\n";
hwpp << "set W+:NominalMass " << massesPtr->at(3) << "*GeV\n";
hwpp << "set W-:NominalMass " << massesPtr->at(3) << "*GeV\n";
hwpp << "set Z0:NominalMass " << massesPtr->at(4) << "*GeV\n";
hwpp << "set h0:NominalMass " << massesPtr->at(5) << "*GeV\n";
hwpp << "\n\n\n\n\n";
hwpp << "######################################################### \n";
hwpp << "######################################################### \n";
hwpp << "## # \n";
hwpp << "## --- USER SERVICEABLE PART BELOW HERE ONLY ! --- # \n";
hwpp << "## # \n";
hwpp << "######################################################### \n";
hwpp << "######################################################### \n";
hwpp << "\n\n\n\n\n";
hwpp << "######################################################### \n";
hwpp << "# Option to off shower / hadronization / decays / MPI. # \n";
hwpp << "######################################################### \n";
hwpp << "cd /Herwig/EventHandlers \n";
hwpp << "# set theLesHouchesHandler:CascadeHandler NULL \n";
- hwpp << "#set theLesHouchesHandler:HadronizationHandler NULL \n";
- hwpp << "#set theLesHouchesHandler:DecayHandler NULL \n";
+ hwpp << "set theLesHouchesHandler:HadronizationHandler NULL \n";
+ hwpp << "set theLesHouchesHandler:DecayHandler NULL \n";
hwpp << "# The handler for multiple parton interactions \n";
- hwpp << "#set /Herwig/Shower/AlpGenHandler:MPIHandler NULL \n";
+ hwpp << "set /Herwig/Shower/AlpGenHandler:MPIHandler NULL \n";
hwpp << "\n\n";
hwpp << "######################################################### \n";
hwpp << "# Recommended key MLM merging parameters below - change # \n";
hwpp << "# for systematic error studies and / or at your peril. # \n";
hwpp << "######################################################### \n";
hwpp << "cd /Herwig/Shower\n";
hwpp << "# Is this the highest multiplicity ME in merging? \n";
hwpp << "# 0 = no, 1 = yes . \n";
hwpp << "set AlpGenHandler:highestMultiplicity 0 \n";
hwpp << "# Jet ET cut to apply in jet clustering in merging.\n";
double etclus(max(ptjmin+5,1.2*ptjmin));
hwpp << "set AlpGenHandler:ETClus " << etclus << "*GeV\n";
hwpp << "# Cone size used in clustering in merging.\n";
double rclus(drjmin);
hwpp << "set AlpGenHandler:RClus " << rclus << "\n";
hwpp << "# Max |eta| for jets in clustering in merging.\n";
double etaclmax(etajmax);
hwpp << "set AlpGenHandler:EtaClusMax " << etaclmax << "\n";
hwpp << "# Default 1.5 factor used to decide if a jet matches a parton\n";
hwpp << "# in merging: if DR(parton,jet)<rclusfactor*rclus the parton \n";
hwpp << "# and jet are said to have been matched.\n";
double rclusfactor(1.5);
hwpp << "set AlpGenHandler:RClusFactor " << rclusfactor << "\n";
hwpp << "\n\n";
hwpp << "################ \n";
hwpp << "# Save the run # \n";
hwpp << "################ \n";
hwpp << "cd /Herwig/Generators \n";
hwpp << "saverun " << prefix << " theGenerator\n";
}
// Now consider assignments specific to individual hard processes:
void doIndividualHardProcessAssignments(int ihrd , double * nup,
vector<double> * idup , vector<double> * istup,
vector<double> * mothup1, vector<double> * mothup2,
vector<double> * icolup1, vector<double> * icolup2,
vector<vector<double> > * pup,
vector<double> masses , int itopprc) {
int iwch(0);
// W/Z/gamma b bbar + jets ( wcjet*, ihrd=10 / wphjet*, ihrd=14 / wphqq*,
// ihrd=15 ), or W/Z + jets ( wjet*, ihrd=3 / zjet*, ihrd=4 ):
// In this case we add to the list of particles the single intermediate
// boson (at the end of the list) appropriately, and assign the relevant
// parent-daughter and colour flow indices.
if (ihrd<=4||ihrd==10||ihrd==14||ihrd==15) {
iwch=0; // <--- used to determine type: W/Z/gamma
for(int iup=int(*nup)-2; iup<int(*nup); iup++) {
(*mothup1)[iup]=*nup+1; // Assigning, to-be-added boson, as
(*mothup2)[iup]=0; // the parent of each decay prod.
if(ihrd!=2) iwch = iwch - (int((*idup)[iup])%2);
// electron+nubar -> 11 + (-12) => -(1)+0 = -1 => W-
// positron+nu -> -11+ 12 => -(-1)+0 = -1 => W+
// u dbar -> 2 -1 => 0 -(-1) = 1 => W+
// c dbar -> 4 -1 => W+
// etc.
}
// Now we start adding the intermediate boson entry:
int iup=nInt(*nup);
if(iwch>0) (*idup).push_back( 24);
else if(iwch<0) (*idup).push_back(-24);
else (*idup).push_back( 23);
(*istup).push_back(2);
(*mothup1).push_back(1);
(*mothup2).push_back(2);
(*pup).push_back(vector<double>(5));
double tmp = (*pup)[3][iup-2]+(*pup)[3][iup-1]; // Vector boson energy.
(*pup)[3][iup] = tmp;
tmp = sqr(tmp);
for(unsigned int ixx=0; ixx<=2; ixx++) {
(*pup)[ixx][iup] = (*pup)[ixx][iup-2]+(*pup)[ixx][iup-1];
tmp = tmp-sqr((*pup)[ixx][iup]); // Vector boson mass^2 when loop ends.
}
(*pup)[4][iup] = sqrt(tmp); // Set vector boson mass.
(*icolup1).push_back(0); // Set 1st colour line for vector boson.
(*icolup2).push_back(0); // Set 2nd colour line for vector boson.
(*nup) = (*nup)+1; // Increment number of particles to be read in the event.
}
// nW + mZ + kH + jets ( vbjet* / ihrd=5 ):
else if(ihrd==5) {
unsigned int ivstart(0),ivend(0);
// Identify the range of the Z and W bosons in the event (AlpGen conventions).
// Note the Z's and W's are the only things that decay - Higgs's and photons
// do not.
vector<unsigned int> bosonIndex;
for(unsigned int ixx=0; ixx<(*nup); ixx++)
if(abs((*idup)[ixx])==24||(*idup)[ixx]==23) {
(*istup)[ixx]=2; // Set the W/Z boson status to intermediate.
bosonIndex.push_back(ixx+1); // W/Z boson index in LH event record (1->nup).
}
unsigned int bosonCounter(nInt(*nup)-2*bosonIndex.size());
for(unsigned int ixx=0; ixx<bosonIndex.size(); ixx++) {
(*mothup1)[bosonCounter]=bosonIndex[ixx];
(*mothup2)[bosonCounter]=0;
bosonCounter++;
(*mothup1)[bosonCounter]=bosonIndex[ixx];
(*mothup2)[bosonCounter]=0;
bosonCounter++;
}
}
// t tbar + jets [ + photons ] ( 2Q*, ihrd=6 [ 2Qph*, ihrd=16 ] ):
else if ((ihrd==6||ihrd==16)&&abs((*idup)[2])==6) {
// Redefine the tops as intermediates in the event record.
(*istup)[2]=2;
(*istup)[3]=2;
unsigned int it(3),itb(4); // Index of t & tbar in evt.record (LH index).
if((*idup)[2]!=6) swap(it,itb);
// Reconstruct intermediate W's from the decay products.
for(unsigned int ixx=0; ixx<4;ixx++) {
(*idup).push_back(0);
(*istup).push_back(0);
(*mothup1).push_back(0);
(*mothup2).push_back(0);
(*icolup1).push_back(0);
(*icolup2).push_back(0);
(*pup).push_back(vector<double>(5));
}
for(unsigned int iw=1; iw<=2; iw++) {
int iwdec(nInt(*nup)-5+2*iw); // First of decay products for this W (iw).
int iwup(nInt(*nup)+iw); // Where the reco. W will go in evt.record (LH index).
int ibup(iwup+2); // Where the reco. b will go in evt.record (under the Ws).
int iwch(0);
for(unsigned int iup=iwdec; iup<=iwdec+1; iup++) {
(*mothup1)[iup-1]=iwup;
(*mothup2)[iup-1]=0;
iwch=iwch-int((*idup)[iup-1])%2; // iwch = charge of W boson.
// electron+nubar -> 11 + (-12) = -1 => W-
// d + ubar -> 1 + (-2) = -1 => W-
// positron+nu -> -11+ 12 = 1 => W+
// u + dbar -> 2 + (-1) = 1 => W+
}
// Make space for the b and W:
// Fill in b and W LH record entries:
if(iwch>0) {
(*idup)[iwup-1]=24;
(*idup)[ibup-1]=5;
(*mothup1)[iwup-1]=it;
(*mothup2)[iwup-1]=0;
(*mothup1)[ibup-1]=it;
(*mothup2)[ibup-1]=0;
} else if (iwch<0) {
(*idup)[iwup-1]=-24;
(*idup)[ibup-1]=-5;
(*mothup1)[iwup-1]=itb;
(*mothup2)[iwup-1]=0;
(*mothup1)[ibup-1]=itb;
(*mothup2)[ibup-1]=0;
}
(*istup)[iwup-1]=2; // The W is an intermediate and the
(*istup)[ibup-1]=1; // b is a final-state particle.
// Now reconstruct W boson momentum
double tmp=(*pup)[3][iwdec-1]+(*pup)[3][iwdec];
(*pup)[3][iwup-1]=tmp; // W energy.
tmp=sqr(tmp);
for(unsigned int ixx=0; ixx<=2; ixx++) {
(*pup)[ixx][iwup-1] = (*pup)[ixx][iwdec-1] // W's 3-mom.
+ (*pup)[ixx][iwdec];
tmp=tmp-sqr((*pup)[ixx][iwup-1]); // Equals m^2 at the end of the loop.
}
(*pup)[4][iwup-1]=sqrt(tmp); // W mass.
// Reconstruct b momentum
int itmp(nInt((*mothup1)[iwup-1]));
tmp=(*pup)[3][itmp-1]-(*pup)[3][iwup-1];
(*pup)[3][ibup-1]=tmp; // b energy.
tmp=sqr(tmp);
for(unsigned int ixx=0; ixx<=2; ixx++) {
(*pup)[ixx][ibup-1] = (*pup)[ixx][nInt((*mothup1)[iwup-1])-1] // b's 3mom.
- (*pup)[ixx][iwup-1];
tmp=tmp-sqr((*pup)[ixx][ibup-1]); // Equals m^2 at the end of the loop.
}
(*pup)[4][ibup-1]=sqrt(tmp); // b mass.
(*icolup1)[iwup-1]=0; // W has no colour
(*icolup2)[iwup-1]=0; // lines.
(*icolup1)[ibup-1]=(*icolup1)[nInt((*mothup1)[iwup-1])-1]; // b shares top
(*icolup2)[ibup-1]=(*icolup2)[nInt((*mothup1)[iwup-1])-1]; // colour line.
}
(*nup)+=4;
}
// H t tbar + jets ( QQh*, ihrd=8 ):
else if (ihrd==8&&abs((*idup)[3])==6) {
// Redefine the tops as intermediates in the event record.
(*istup)[3]=2;
(*istup)[4]=2;
unsigned int it(4),itb(5); // Index of t & tbar in evt.record (LH index).
if((*idup)[3]!=6) swap(it,itb);
// Reconstruct intermediate W's from the decay products.
for(unsigned int ixx=0; ixx<4;ixx++) {
(*idup).push_back(0);
(*istup).push_back(0);
(*mothup1).push_back(0);
(*mothup2).push_back(0);
(*icolup1).push_back(0);
(*icolup2).push_back(0);
(*pup).push_back(vector<double>(5));
}
for(unsigned int iw=1; iw<=2; iw++) {
int iwdec(nInt(*nup)-5+2*iw); // First of decay products for this W (iw).
int iwup(nInt(*nup)+iw); // Where the reco. W will go in evt.record (LH index).
int ibup(iwup+2); // Where the reco. b will go in evt.record (under the Ws).
int iwch(0);
for(unsigned int iup=iwdec; iup<=iwdec+1; iup++) {
(*mothup1)[iup-1]=iwup;
(*mothup2)[iup-1]=0;
iwch=iwch-int((*idup)[iup-1])%2; // iwch = charge of W boson.
// electron+nubar -> 11 + (-12) = -1 => W-
// d + ubar -> 1 + (-2) = -1 => W-
// positron+nu -> -11+ 12 = 1 => W+
// u + dbar -> 2 + (-1) = 1 => W+
}
if(iwch>0) {
(*idup)[iwup-1]=24;
(*idup)[ibup-1]=5;
(*mothup1)[iwup-1]=it;
(*mothup2)[iwup-1]=0;
(*mothup1)[ibup-1]=it;
(*mothup2)[ibup-1]=0;
} else if (iwch<0) {
(*idup)[iwup-1]=-24;
(*idup)[ibup-1]=-5;
(*mothup1)[iwup-1]=itb;
(*mothup2)[iwup-1]=0;
(*mothup1)[ibup-1]=itb;
(*mothup2)[ibup-1]=0;
}
(*istup)[iwup-1]=2; // The W is an intermediate and the
(*istup)[ibup-1]=1; // b is a final-state particle.
// Now reconstruct W boson momentum
double tmp=(*pup)[3][iwdec-1]+(*pup)[3][iwdec];
(*pup)[3][iwup-1]=tmp; // W energy.
tmp=sqr(tmp);
for(unsigned int ixx=0; ixx<=2; ixx++) {
(*pup)[ixx][iwup-1] = (*pup)[ixx][iwdec-1] // W's 3-mom.
+ (*pup)[ixx][iwdec];
tmp=tmp-sqr((*pup)[ixx][iwup-1]); // Equals m^2 at the end of the loop.
}
(*pup)[4][iwup-1]=sqrt(tmp); // W mass.
// Reconstruct b momentum
tmp=(*pup)[3][nInt((*mothup1)[iwup-1])-1]-(*pup)[3][iwup-1];
(*pup)[3][ibup-1]=tmp; // b energy.
tmp=sqr(tmp);
for(unsigned int ixx=0; ixx<=2; ixx++) {
(*pup)[ixx][ibup-1] = (*pup)[ixx][nInt((*mothup1)[iwup-1])-1] // b's 3mom.
- (*pup)[ixx][iwup-1];
tmp=tmp-sqr((*pup)[ixx][ibup-1]); // Equals m^2 at the end of the loop.
}
(*pup)[4][ibup-1]=sqrt(tmp); // b mass.
(*icolup1)[iwup-1]=0; // W has no colour
(*icolup2)[iwup-1]=0; // lines.
(*icolup1)[ibup-1]=(*icolup1)[nInt((*mothup1)[iwup-1])-1]; // b shares top
(*icolup2)[ibup-1]=(*icolup2)[nInt((*mothup1)[iwup-1])-1]; // colour line.
}
(*nup)+=4;
}
// Single top production ( top*, ihrd=13):
else if (ihrd==13) {
int nw=1;
if(itopprc>=3) nw=2;
// Assign a mass to the incoming bottom quark, if there is one,
// rescaling the energy to accommodate the mass.
for(unsigned int ixx=1; ixx<=2; ixx++) {
if(abs((*idup)[ixx-1])==5) {
(*pup)[4][ixx-1]=masses[1];
(*pup)[3][ixx-1]=sqrt(sqr((*pup)[2][ixx-1])+sqr((*pup)[4][ixx-1]));
}
}
// Set the top status to that of an intermediate.
(*istup)[2]=2;
// Get the index of the t / tbar in the evt. record (LH convention: 1->nup).
unsigned int it=0;
unsigned itb=0;
if((*idup)[2]==6) it=3;
else if((*idup)[2]==-6) itb=3;
else {
cout << "doIndividualHardProcessAssignments:\n"
<< "wrong assumption about top position.\n"
<< "Quitting ...";
exit(1);
}
// Reconstruct intermediate W's from the decay products.
// iwdec is the index of the first W decay product
unsigned int iwdec(nInt(*nup)-1); // LH conventions: 1->nup.
if(nw==2) iwdec=nInt(*nup)-3;
// The W and b will go at the end of the record.
unsigned int iwup(nInt(*nup)+1);
unsigned int ibup(nInt(*nup)+2);
int iwch(0);
for(unsigned int iup=iwdec; iup<=iwdec+1; iup++) {
(*mothup1)[iup-1]=iwup;
(*mothup2)[iup-1]=0;
iwch=iwch-int((*idup)[iup-1])%2; // iwch = charge of W boson.
// electron+nubar -> 11 + (-12) = -1 => W-
// d + ubar -> 1 + (-2) = -1 => W-
// positron+nu -> -11+ 12 = 1 => W+
// u + dbar -> 2 + (-1) = 1 => W+
}
for(unsigned int ixx=0; ixx<2;ixx++) {
(*idup).push_back(0);
(*istup).push_back(0);
(*mothup1).push_back(0);
(*mothup2).push_back(0);
(*icolup1).push_back(0);
(*icolup2).push_back(0);
(*pup).push_back(vector<double>(5));
}
if(iwch>0) {
(*idup)[iwup-1]=24;
(*idup)[ibup-1]=5;
(*mothup1)[iwup-1]=it;
(*mothup2)[iwup-1]=0;
(*mothup1)[ibup-1]=it;
(*mothup2)[ibup-1]=0;
} else if (iwch<0) {
(*idup)[iwup-1]=-24;
(*idup)[ibup-1]=-5;
(*mothup1)[iwup-1]=itb;
(*mothup2)[iwup-1]=0;
(*mothup1)[ibup-1]=itb;
(*mothup2)[ibup-1]=0;
}
(*istup)[iwup-1]=2;
(*istup)[ibup-1]=1;
// Now reconstruct W boson momentum
double tmp=(*pup)[3][iwdec-1]+(*pup)[3][iwdec];
(*pup)[3][iwup-1]=tmp; // W energy.
tmp=sqr(tmp);
for(unsigned int ixx=0; ixx<=2; ixx++) {
(*pup)[ixx][iwup-1] = (*pup)[ixx][iwdec-1] // W's 3-mom.
+ (*pup)[ixx][iwdec];
tmp=tmp-sqr((*pup)[ixx][iwup-1]); // Equals m^2 at the end of the loop.
}
(*pup)[4][iwup-1]=sqrt(tmp); // W mass.
// Reconstruct b momentum
tmp=(*pup)[3][nInt((*mothup1)[iwup-1])-1]-(*pup)[3][iwup-1];
(*pup)[3][ibup-1]=tmp; // b energy.
tmp=sqr(tmp);
for(unsigned int ixx=0; ixx<=2; ixx++) {
(*pup)[ixx][ibup-1] = (*pup)[ixx][nInt((*mothup1)[iwup-1])-1] // b's 3mom.
- (*pup)[ixx][iwup-1];
tmp=tmp-sqr((*pup)[ixx][ibup-1]); // Equals m^2 at the end of the loop.
}
(*pup)[4][ibup-1]=sqrt(tmp); // b mass.
(*icolup1)[iwup-1]=0;
(*icolup2)[iwup-1]=0;
(*icolup1)[ibup-1]=(*icolup1)[nInt((*mothup1)[iwup-1])-1];
(*icolup2)[ibup-1]=(*icolup2)[nInt((*mothup1)[iwup-1])-1];
(*nup)=(*nup)+2;
if(nw==2) {
// W DECAY
// iwdec is the index of the first W decay product.
iwdec=nInt(*nup)-3;
// iwup is the index of the W in the event record (LH conventions: 1->nup).
iwup=nInt(*nup)-6;
iwch=0;
int iwch(0);
for(unsigned int iup=iwdec; iup<=iwdec+1; iup++) {
(*mothup1)[iup-1]=iwup;
(*mothup2)[iup-1]=0;
iwch=iwch-int((*idup)[iup-1])%2; // iwch = charge of W boson.
// electron+nubar -> 11 + (-12) = -1 => W-
// d + ubar -> 1 + (-2) = -1 => W-
// positron+nu -> -11+ 12 = 1 => W+
// u + dbar -> 2 + (-1) = 1 => W+
}
(*istup)[iwup-1]=2;
(*icolup1)[iwup-1]=0;
(*icolup2)[iwup-1]=0;
}
}
return;
}
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,1988 +1,1821 @@
// -*- C++ -*-
//
// MatchboxMEBase.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxMEBase class.
//
#include "MatchboxMEBase.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDF/PDF.h"
#include "ThePEG/PDT/PDT.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Handlers/StdXCombGroup.h"
#include "ThePEG/EventRecord/SubProcess.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig/MatrixElement/Matchbox/Utility/DiagramDrawer.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include "Herwig/Utilities/RunDirectories.h"
#include "Herwig/MatrixElement/ProductionMatrixElement.h"
#include "Herwig/MatrixElement/HardVertex.h"
#include <boost/foreach.hpp>
#include <cctype>
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
MatchboxMEBase::MatchboxMEBase()
: MEBase(),
theOneLoop(false),
theOneLoopNoBorn(false),
theOneLoopNoLoops(false),
theNoCorrelations(false),
theHavePDFs(false,false), checkedPDFs(false),
theDiagramWeightVerboseDown(10000000000000.),
theDiagramWeightVerboseUp(0.) {}
MatchboxMEBase::~MatchboxMEBase() {}
Ptr<MatchboxFactory>::tptr MatchboxMEBase::factory() const { return theFactory; }
void MatchboxMEBase::factory(Ptr<MatchboxFactory>::tptr f) { theFactory = f; }
Ptr<Tree2toNGenerator>::tptr MatchboxMEBase::diagramGenerator() const { return factory()->diagramGenerator(); }
Ptr<ProcessData>::tptr MatchboxMEBase::processData() const { return factory()->processData(); }
unsigned int MatchboxMEBase::getNLight() const { return factory()->nLight(); }
vector<int> MatchboxMEBase::getNLightJetVec() const { return factory()->nLightJetVec(); }
vector<int> MatchboxMEBase::getNHeavyJetVec() const { return factory()->nHeavyJetVec(); }
vector<int> MatchboxMEBase::getNLightProtonVec() const { return factory()->nLightProtonVec(); }
double MatchboxMEBase::factorizationScaleFactor() const { return factory()->factorizationScaleFactor(); }
double MatchboxMEBase::renormalizationScaleFactor() const { return factory()->renormalizationScaleFactor(); }
bool MatchboxMEBase::fixedCouplings() const { return factory()->fixedCouplings(); }
bool MatchboxMEBase::fixedQEDCouplings() const { return factory()->fixedQEDCouplings(); }
bool MatchboxMEBase::checkPoles() const { return factory()->checkPoles(); }
bool MatchboxMEBase::verbose() const { return factory()->verbose(); }
bool MatchboxMEBase::initVerbose() const { return factory()->initVerbose(); }
void MatchboxMEBase::getDiagrams() const {
if ( diagramGenerator() && processData() ) {
vector<Ptr<Tree2toNDiagram>::ptr> diags;
vector<Ptr<Tree2toNDiagram>::ptr>& res =
processData()->diagramMap()[subProcess().legs];
if ( res.empty() ) {
res = diagramGenerator()->generate(subProcess().legs,orderInAlphaS(),orderInAlphaEW());
}
copy(res.begin(),res.end(),back_inserter(diags));
processData()->fillMassGenerators(subProcess().legs);
if ( diags.empty() )
return;
for ( vector<Ptr<Tree2toNDiagram>::ptr>::iterator d = diags.begin();
d != diags.end(); ++d ) {
add(*d);
}
return;
}
throw Exception()
<< "MatchboxMEBase::getDiagrams() expects a Tree2toNGenerator and ProcessData object.\n"
<< "Please check your setup." << Exception::runerror;
}
Selector<MEBase::DiagramIndex>
MatchboxMEBase::diagrams(const DiagramVector & diags) const {
if ( phasespace() ) {
return phasespace()->selectDiagrams(diags);
}
throw Exception()
<< "MatchboxMEBase::diagrams() expects a MatchboxPhasespace object.\n"
<< "Please check your setup." << Exception::runerror;
return Selector<MEBase::DiagramIndex>();
}
Selector<const ColourLines *>
MatchboxMEBase::colourGeometries(tcDiagPtr diag) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->haveColourFlows() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
return matchboxAmplitude()->colourGeometries(diag);
}
}
Ptr<Tree2toNDiagram>::tcptr tdiag =
dynamic_ptr_cast<Ptr<Tree2toNDiagram>::tcptr>(diag);
assert(diag && processData());
vector<ColourLines*>& flows = processData()->colourFlowMap()[tdiag];
if ( flows.empty() ) {
list<list<list<pair<int,bool> > > > cflows =
ColourBasis::colourFlows(tdiag);
for ( list<list<list<pair<int,bool> > > >::const_iterator fit =
cflows.begin(); fit != cflows.end(); ++fit ) {
flows.push_back(new ColourLines(ColourBasis::cfstring(*fit)));
}
}
Selector<const ColourLines *> res;
for ( vector<ColourLines*>::const_iterator f = flows.begin();
f != flows.end(); ++f )
res.insert(1.0,*f);
return res;
}
void MatchboxMEBase::constructVertex(tSubProPtr sub, const ColourLines* cl) {
if ( !canFillRhoMatrix() || !factory()->spinCorrelations() )
return;
assert(matchboxAmplitude());
assert(matchboxAmplitude()->colourBasis());
// get the colour structure for the selected colour flow
size_t cStructure =
matchboxAmplitude()->colourBasis()->tensorIdFromFlow(lastXComb().lastDiagram(),cl);
// hard process for processing the spin info
tPVector hard;
hard.push_back(sub->incoming().first);
hard.push_back(sub->incoming().second);
vector<PDT::Spin> out;
for ( size_t k = 0; k < sub->outgoing().size(); ++k ) {
out.push_back(sub->outgoing()[k]->data().iSpin());
hard.push_back(sub->outgoing()[k]);
}
// calculate dummy wave functions to fill the spin info
static vector<VectorWaveFunction> dummyPolarizations;
static vector<SpinorWaveFunction> dummySpinors;
static vector<SpinorBarWaveFunction> dummyBarSpinors;
for ( size_t k = 0; k < hard.size(); ++k ) {
if ( hard[k]->data().iSpin() == PDT::Spin1Half ) {
if ( hard[k]->id() > 0 && k > 1 ) {
SpinorBarWaveFunction(dummyBarSpinors,hard[k],
outgoing, true);
} else if ( hard[k]->id() < 0 && k > 1 ) {
SpinorWaveFunction(dummySpinors,hard[k],
outgoing, true);
} else if ( hard[k]->id() > 0 && k < 2 ) {
SpinorWaveFunction(dummySpinors,hard[k],
incoming, false);
} else if ( hard[k]->id() < 0 && k < 2 ) {
SpinorBarWaveFunction(dummyBarSpinors,hard[k],
incoming, false);
}
}
else if ( hard[k]->data().iSpin() == PDT::Spin1 ) {
VectorWaveFunction(dummyPolarizations,hard[k],
k > 1 ? outgoing : incoming,
k > 1 ? true : false,
hard[k]->data().hardProcessMass() == ZERO);
}
else if (hard[k]->data().iSpin() == PDT::Spin0 ) {
ScalarWaveFunction(hard[k],k > 1 ? outgoing : incoming,
k > 1 ? true : false);
}
else
assert(false);
}
// fill the production matrix element
ProductionMatrixElement pMe(mePartonData()[0]->iSpin(),
mePartonData()[1]->iSpin(),
out);
for ( map<vector<int>,CVector>::const_iterator lamp = lastLargeNAmplitudes().begin();
lamp != lastLargeNAmplitudes().end(); ++lamp ) {
vector<unsigned int> pMeHelicities
= matchboxAmplitude()->physicalHelicities(lamp->first);
pMe(pMeHelicities) = lamp->second[cStructure];
}
// set the spin information
HardVertexPtr hardvertex = new_ptr(HardVertex());
hardvertex->ME(pMe);
if ( sub->incoming().first->spinInfo() )
sub->incoming().first->spinInfo()->productionVertex(hardvertex);
if ( sub->incoming().second->spinInfo() )
sub->incoming().second->spinInfo()->productionVertex(hardvertex);
for ( ParticleVector::const_iterator p = sub->outgoing().begin();
p != sub->outgoing().end(); ++p ) {
if ( (**p).spinInfo() )
(**p).spinInfo()->productionVertex(hardvertex);
}
}
unsigned int MatchboxMEBase::orderInAlphaS() const {
return subProcess().orderInAlphaS;
}
unsigned int MatchboxMEBase::orderInAlphaEW() const {
return subProcess().orderInAlphaEW;
}
void MatchboxMEBase::setXComb(tStdXCombPtr xc) {
MEBase::setXComb(xc);
lastMatchboxXComb(xc);
if ( phasespace() )
phasespace()->setXComb(xc);
if ( scaleChoice() )
scaleChoice()->setXComb(xc);
if ( matchboxAmplitude() )
matchboxAmplitude()->setXComb(xc);
- if (theMerger) {
+ if (theMerger)
theMerger->setXComb(this,xc, theProjectorStage);
- }
}
-void MatchboxMEBase::setKinematics() {
- MEBase::setKinematics();
- if ( theMerger ) {
- theMerger->setKinematics(this);
- }
-}
-
-void MatchboxMEBase::clearKinematics() {
- MEBase::clearKinematics();
- if ( theMerger ) {
- theMerger->clearKinematics(this);
- }
-
-}
-
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();
if (theMerger&&!theMerger->generateKinematics(this,r))
return false;
logGenerateKinematics(r);
assert(lastMatchboxXComb());
if ( nDimAmplitude() > 0 ) {
amplitudeRandomNumbers().resize(nDimAmplitude());
copy(r + nDimPhasespace(),
r + nDimPhasespace() + nDimAmplitude(),
amplitudeRandomNumbers().begin());
}
if ( nDimInsertions() > 0 ) {
insertionRandomNumbers().resize(nDimInsertions());
copy(r + nDimPhasespace() + nDimAmplitude(),
r + nDimPhasespace() + nDimAmplitude() + nDimInsertions(),
insertionRandomNumbers().begin());
}
return true;
}
throw Exception()
<< "MatchboxMEBase::generateKinematics() expects a MatchboxPhasespace object.\n"
<< "Please check your setup." << Exception::runerror;
return false;
}
int MatchboxMEBase::nDim() const {
if ( lastMatchboxXComb() )
return nDimPhasespace() + nDimAmplitude() + nDimInsertions();
int ampAdd = 0;
if ( matchboxAmplitude() ) {
ampAdd = matchboxAmplitude()->nDimAdditional();
}
int insertionAdd = 0;
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
insertionAdd = max(insertionAdd,(**v).nDimAdditional());
}
return nDimBorn() + ampAdd + insertionAdd;
}
int MatchboxMEBase::nDimBorn() const {
if ( lastMatchboxXComb() )
return nDimPhasespace();
if ( phasespace() )
return phasespace()->nDim(diagrams().front()->partons());
throw Exception()
<< "MatchboxMEBase::nDim() expects a MatchboxPhasespace object.\n"
<< "Please check your setup." << Exception::runerror;
return 0;
}
void MatchboxMEBase::setScale(Energy2 ren,Energy2 fac) const {
if ( haveX1X2() ) {
lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
}
Energy2 fcscale = fac==ZERO?factorizationScale():fac;
Energy2 fscale = fcscale*sqr(factorizationScaleFactor());
Energy2 rscale = (ren==ZERO?renormalizationScale():ren)*sqr(renormalizationScaleFactor());
Energy2 ewrscale = renormalizationScaleQED();
lastXCombPtr()->lastScale(fscale);
lastXCombPtr()->lastCentralScale(fcscale);
lastXCombPtr()->lastShowerScale(showerScale());
lastMatchboxXComb()->lastRenormalizationScale(rscale);
if ( !fixedCouplings() ) {
if ( rscale > lastCuts().scaleMin() )
lastXCombPtr()->lastAlphaS(SM().alphaS(rscale));
else
lastXCombPtr()->lastAlphaS(SM().alphaS(lastCuts().scaleMin()));
} else {
lastXCombPtr()->lastAlphaS(SM().alphaS());
}
if ( !fixedQEDCouplings() ) {
lastXCombPtr()->lastAlphaEM(SM().alphaEMME(ewrscale));
} else {
lastXCombPtr()->lastAlphaEM(SM().alphaEMMZ());
}
logSetScale();
}
Energy2 MatchboxMEBase::factorizationScale() const {
if ( scaleChoice() ) {
return scaleChoice()->factorizationScale();
}
throw Exception()
<< "MatchboxMEBase::factorizationScale() expects a MatchboxScaleChoice object.\n"
<< "Please check your setup." << Exception::runerror;
return ZERO;
}
Energy2 MatchboxMEBase::renormalizationScale() const {
if ( scaleChoice() ) {
return scaleChoice()->renormalizationScale();
}
throw Exception()
<< "MatchboxMEBase::renormalizationScale() expects a MatchboxScaleChoice object.\n"
<< "Please check your setup." << Exception::runerror;
return ZERO;
}
Energy2 MatchboxMEBase::renormalizationScaleQED() const {
if ( scaleChoice() ) {
return scaleChoice()->renormalizationScaleQED();
}
return renormalizationScale();
}
Energy2 MatchboxMEBase::showerScale() const {
if ( scaleChoice() ) {
return scaleChoice()->showerScale();
}
throw Exception()
<< "MatchboxMEBase::showerScale() expects a MatchboxScaleChoice object.\n"
<< "Please check your setup." << Exception::runerror;
return ZERO;
}
void MatchboxMEBase::setVetoScales(tSubProPtr) const {}
bool MatchboxMEBase::havePDFWeight1() const {
if ( checkedPDFs )
return theHavePDFs.first;
theHavePDFs.first =
factory()->isIncoming(mePartonData()[0]) &&
lastXCombPtr()->partonBins().first->pdf();
theHavePDFs.second =
factory()->isIncoming(mePartonData()[1]) &&
lastXCombPtr()->partonBins().second->pdf();
checkedPDFs = true;
return theHavePDFs.first;
}
bool MatchboxMEBase::havePDFWeight2() const {
if ( checkedPDFs )
return theHavePDFs.second;
theHavePDFs.first =
factory()->isIncoming(mePartonData()[0]) &&
lastXCombPtr()->partonBins().first->pdf();
theHavePDFs.second =
factory()->isIncoming(mePartonData()[1]) &&
lastXCombPtr()->partonBins().second->pdf();
checkedPDFs = true;
return theHavePDFs.second;
}
void MatchboxMEBase::getPDFWeight(Energy2 factorizationScale) const {
if ( !havePDFWeight1() && !havePDFWeight2() ) {
lastMEPDFWeight(1.0);
logPDFWeight();
return;
}
double w = 1.;
if ( havePDFWeight1() )
w *= pdf1(factorizationScale);
if ( havePDFWeight2() )
w *= pdf2(factorizationScale);
lastMEPDFWeight(w);
logPDFWeight();
}
double MatchboxMEBase::pdf1(Energy2 fscale, double xEx, double xFactor) const {
assert(lastXCombPtr()->partonBins().first->pdf());
if ( xEx < 1. && lastX1()*xFactor >= xEx ) {
return
( ( 1. - lastX1()*xFactor ) / ( 1. - xEx ) ) *
lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
lastPartons().first->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
xEx)/xEx;
}
return lastXCombPtr()->partonBins().first->pdf()->xfx(lastParticles().first->dataPtr(),
lastPartons().first->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
lastX1()*xFactor)/lastX1()/xFactor;
}
double MatchboxMEBase::pdf2(Energy2 fscale, double xEx, double xFactor) const {
assert(lastXCombPtr()->partonBins().second->pdf());
if ( xEx < 1. && lastX2()*xFactor >= xEx ) {
return
( ( 1. - lastX2()*xFactor ) / ( 1. - xEx ) ) *
lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
lastPartons().second->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
xEx)/xEx;
}
return lastXCombPtr()->partonBins().second->pdf()->xfx(lastParticles().second->dataPtr(),
lastPartons().second->dataPtr(),
fscale == ZERO ? lastScale() : fscale,
lastX2()*xFactor)/lastX2()/xFactor;
}
double MatchboxMEBase::me2() const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
double res =
matchboxAmplitude()->me2()*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::me2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() ) {
largeNBasis->prepare(mePartonData(),false);
matchboxAmplitude()->prepareAmplitudes(this);
}
double res =
matchboxAmplitude()->largeNME2(largeNBasis)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::largeNME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::finalStateSymmetry() const {
if ( symmetryFactor() > 0.0 )
return symmetryFactor();
double sFactor = 1.;
map<long,int> counts;
cPDVector checkData;
copy(mePartonData().begin()+2,mePartonData().end(),back_inserter(checkData));
cPDVector::iterator p = checkData.begin();
while ( !checkData.empty() ) {
if ( counts.find((**p).id()) != counts.end() ) {
counts[(**p).id()] += 1;
} else {
counts[(**p).id()] = 1;
}
checkData.erase(p);
p = checkData.begin();
continue;
}
for ( map<long,int>::const_iterator c = counts.begin();
c != counts.end(); ++c ) {
if ( c->second == 1 )
continue;
if ( c->second == 2 )
sFactor /= 2.;
else if ( c->second == 3 )
sFactor /= 6.;
else if ( c->second == 4 )
sFactor /= 24.;
}
symmetryFactor(sFactor);
return symmetryFactor();
}
double MatchboxMEBase::me2Norm(unsigned int addAlphaS) const {
// assume that we always have incoming
// spin-1/2 or massless spin-1 particles
double fac = 1./4.;
if ( hasInitialAverage() )
fac = 1.;
double couplings = 1.0;
if ( (orderInAlphaS() > 0 || addAlphaS != 0) && !hasRunningAlphaS() ) {
fac *= pow(lastAlphaS()/SM().alphaS(),double(orderInAlphaS()+addAlphaS));
couplings *= pow(lastAlphaS(),double(orderInAlphaS()+addAlphaS));
}
if ( orderInAlphaEW() > 0 && !hasRunningAlphaEW() ) {
fac *= pow(lastAlphaEM()/SM().alphaEMMZ(),double(orderInAlphaEW()));
couplings *= pow(lastAlphaEM(),double(orderInAlphaEW()));
}
lastMECouplings(couplings);
if ( !hasInitialAverage() ) {
if ( mePartonData()[0]->iColour() == PDT::Colour3 ||
mePartonData()[0]->iColour() == PDT::Colour3bar )
fac /= SM().Nc();
else if ( mePartonData()[0]->iColour() == PDT::Colour8 )
fac /= (SM().Nc()*SM().Nc()-1.);
if ( mePartonData()[1]->iColour() == PDT::Colour3 ||
mePartonData()[1]->iColour() == PDT::Colour3bar )
fac /= SM().Nc();
else if ( mePartonData()[1]->iColour() == PDT::Colour8 )
fac /= (SM().Nc()*SM().Nc()-1.);
}
return !hasFinalStateSymmetry() ? finalStateSymmetry()*fac : fac;
}
CrossSection MatchboxMEBase::dSigHatDR(double diffAlpha) const {
getPDFWeight();
if (theMerger&&theMerger->calculateInNode()) {
lastMECrossSection(1.0*nanobarn);
return lastMECrossSection();
}
if (!theMerger&&!subNode()&& !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;
setLastBorndSigHatDR((sqr(hbarc)/(2.*lastSHat())) * jacobian()* lastMEPDFWeight() * xme2/nanobarn);
if ( !oneLoopNoBorn() )
res +=
(sqr(hbarc)/(2.*lastSHat())) *
jacobian()* lastMEPDFWeight() * xme2;
if ( oneLoop() && !oneLoopNoLoops() )
res +=
(sqr(hbarc)/(2.*lastSHat())) *
jacobian()* lastMEPDFWeight() * vme2;
if ( (oneLoop() &&!onlyOneLoop())||diffAlpha!=1. ) {
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
(**v).setXComb(lastXCombPtr());
if (diffAlpha==1.) {
res += (**v).dSigHatDR();
}else {
CrossSection x= (**v).dSigHatDR();
factory()->setAlphaParameter(diffAlpha);
(**v).setXComb(lastXCombPtr());
x -= (**v).dSigHatDR();
factory()->setAlphaParameter(1.);
res -=x;
}
}
if ( checkPoles() && oneLoop() )
logPoles();
}
double weight = 0.0;
bool applied = false;
for ( vector<Ptr<MatchboxReweightBase>::ptr>::const_iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
(**rw).setXComb(lastXCombPtr());
if ( !(**rw).apply() )
continue;
weight += (**rw).evaluate();
applied = true;
}
if ( applied )
res *= weight;
lastMECrossSection(res);
return lastMECrossSection();
}
double MatchboxMEBase::oneLoopInterference() const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->oneLoopAmplitudes() )
matchboxAmplitude()->prepareOneLoopAmplitudes(this);
double res =
matchboxAmplitude()->oneLoopInterference()*
me2Norm(1);
return res;
}
throw Exception()
<< "MatchboxMEBase::oneLoopInterference() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
MatchboxMEBase::AccuracyHistogram::AccuracyHistogram(double low,
double up,
unsigned int nbins)
: lower(low), upper(up),
sameSign(0), oppositeSign(0), nans(0),
overflow(0), underflow(0) {
double step = (up-low)/nbins;
for ( unsigned int k = 1; k <= nbins; ++k )
bins[lower + k*step] = 0.0;
}
void MatchboxMEBase::AccuracyHistogram::book(double a, double b) {
if ( isnan(a) || isnan(b) ||
isinf(a) || isinf(b) ) {
++nans;
return;
}
if ( a*b >= 0. )
++sameSign;
if ( a*b < 0. )
++oppositeSign;
double r = 1.;
if ( abs(a) != 0.0 )
r = abs(1.-abs(b/a));
else if ( abs(b) != 0.0 )
r = abs(b);
if ( log10(r) < lower || r == 0.0 ) {
++underflow;
return;
}
if ( log10(r) > upper ) {
++overflow;
return;
}
map<double,double>::iterator bin =
bins.upper_bound(log10(r));
if ( bin == bins.end() )
return;
bin->second += 1.;
}
void MatchboxMEBase::AccuracyHistogram::dump(const std::string& folder, const std::string& prefix,
const cPDVector& proc) const {
ostringstream fname("");
for ( cPDVector::const_iterator p = proc.begin();
p != proc.end(); ++p )
fname << (**p).PDGName();
ofstream out((folder+"/"+prefix+fname.str()+".dat").c_str());
out << "# same sign : " << sameSign << " opposite sign : "
<< oppositeSign << " nans : " << nans
<< " overflow : " << overflow
<< " underflow : " << underflow << "\n";
for ( map<double,double>::const_iterator b = bins.begin();
b != bins.end(); ++b ) {
map<double,double>::const_iterator bp = b; --bp;
if ( b->second != 0. ) {
if ( b != bins.begin() )
out << bp->first;
else
out << lower;
out << " " << b->first
<< " " << b->second
<< "\n" << flush;
}
}
ofstream gpout((folder+"/"+prefix+fname.str()+".gp").c_str());
gpout << "set terminal png\n"
<< "set xlabel 'accuracy of pole cancellation [decimal places]'\n"
<< "set ylabel 'counts\n"
<< "set xrange [-20:0]\n"
<< "set output '" << prefix << fname.str() << ".png'\n"
<< "plot '" << prefix << fname.str() << ".dat' using (0.5*($1+$2)):3 with linespoints pt 7 ps 1 not";
}
void MatchboxMEBase::AccuracyHistogram::persistentOutput(PersistentOStream& os) const {
os << lower << upper << bins
<< sameSign << oppositeSign << nans
<< overflow << underflow;
}
void MatchboxMEBase::AccuracyHistogram::persistentInput(PersistentIStream& is) {
is >> lower >> upper >> bins
>> sameSign >> oppositeSign >> nans
>> overflow >> underflow;
}
void MatchboxMEBase::logPoles() const {
double res2me = oneLoopDoublePole();
double res1me = oneLoopSinglePole();
double res2i = 0.;
double res1i = 0.;
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
res2i += (**v).oneLoopDoublePole();
res1i += (**v).oneLoopSinglePole();
}
if (res2me != 0.0 || res2i != 0.0) epsilonSquarePoleHistograms[mePartonData()].book(res2me,res2i);
if (res1me != 0.0 || res1i != 0.0) epsilonPoleHistograms[mePartonData()].book(res1me,res1i);
}
bool MatchboxMEBase::haveOneLoop() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->haveOneLoop();
return false;
}
bool MatchboxMEBase::onlyOneLoop() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->onlyOneLoop();
return false;
}
bool MatchboxMEBase::isDRbar() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isDRbar();
return false;
}
bool MatchboxMEBase::isDR() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isDR();
return false;
}
bool MatchboxMEBase::isCS() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isCS();
return false;
}
bool MatchboxMEBase::isBDK() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isBDK();
return false;
}
bool MatchboxMEBase::isExpanded() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->isExpanded();
return false;
}
Energy2 MatchboxMEBase::mu2() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->mu2();
return 0*GeV2;
}
double MatchboxMEBase::oneLoopDoublePole() const {
if ( matchboxAmplitude() ) {
return
matchboxAmplitude()->oneLoopDoublePole()*
me2Norm(1);
}
return 0.;
}
double MatchboxMEBase::oneLoopSinglePole() const {
if ( matchboxAmplitude() ) {
return
matchboxAmplitude()->oneLoopSinglePole()*
me2Norm(1);
}
return 0.;
}
vector<Ptr<SubtractionDipole>::ptr>
MatchboxMEBase::getDipoles(const vector<Ptr<SubtractionDipole>::ptr>& dipoles,
const vector<Ptr<MatchboxMEBase>::ptr>& borns,bool slim) 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,slim);
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;
if ( theMerger) {
dname << fullName();
- if (theOneLoopNoBorn) dname << ".projected-virtual." << theProjectorStage << "." ;
+ if (theOneLoopNoBorn) dname << ".virtual." << theProjectorStage << "." ;
dname << (**b).name() << "."
<< (**d).name() << ".[("
<< emitter << "," << emission << ")," << spectator << "]";
} else {
dname << fullName() << "." << (**b).name() << "."
<< (**d).name() << ".[("
<< emitter << "," << emission << ")," << spectator << "]";
}
if ( ! (generator()->preinitRegister(nDipole,dname.str()) ) )
throw Exception() << "MatchboxMEBase::getDipoles(): Dipole " << dname.str() << " already existing." << Exception::runerror;
if ( !factory()->reweighters().empty() ) {
for ( vector<ReweightPtr>::const_iterator rw = factory()->reweighters().begin();
rw != factory()->reweighters().end(); ++rw )
nDipole->addReweighter(*rw);
}
if ( !factory()->preweighters().empty() ) {
for ( vector<ReweightPtr>::const_iterator rw = factory()->preweighters().begin();
rw != factory()->preweighters().end(); ++rw )
nDipole->addPreweighter(*rw);
}
nDipole->cloneDependencies(dname.str(),slim);
}
}
}
}
}
}
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;
}
-
-
-
-
-int
-MatchboxMEBase::numberOfSplittings(const vector<Ptr<SubtractionDipole>::ptr>& dipoles,
- const vector<Ptr<MatchboxMEBase>::ptr>& reals) const {
-
- // 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;
-
-
- vector<Ptr<MatchboxMEBase>::ptr> filteredreals;
-
-
- cPDVector bornrep=diagrams().front()->partons();
-
- int lesssplittings=0;
- for (vector<Ptr<MatchboxMEBase>::ptr>::const_iterator it=reals.begin(); it!=reals.end(); it++) {
-
-
-
-
- cPDVector rep = (*it)->diagrams().front()->partons();
-
- int nreal = rep.size();
- if(rep[0]->id()!=bornrep[0]->id()&&rep[1]->id()!=bornrep[1]->id())continue;
- if(rep[0]->id()<=6&&bornrep[0]->id()<=6&&rep[0]->id()!=bornrep[0]->id())continue;
- if(rep[1]->id()<=6&&bornrep[1]->id()<=6&&rep[1]->id()!=bornrep[1]->id())continue;
- int matches=0;
- //cout<<"\nreal: ";
- for (int born=0; born < int(bornrep.size());born++){
- for ( int emitter = 0; emitter < nreal; ++emitter ) {
- if(rep[emitter]->id()==bornrep[born]->id())matches++;
- }
- }
- if (matches<int(bornrep.size()-1))continue;
- // 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 = (*it)->diagrams().begin(); d != (*it)->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;
-
- if ( done.find(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*it,*d)))
- != done.end() ) continue;
- // now get to work
- (**d).clearBookkeeping();
- (**d).factory(factory());
- (**d).realEmitter(emitter);
- (**d).realEmission(emission);
- (**d).realSpectator(spectator);
- (**d).realEmissionME(*it);
- (**d).underlyingBornME(const_cast<MatchboxMEBase*>(this));
- (**d).setupBookkeeping(mergeInfo,true);
- if ( !((**d).empty()) ) {
- done.insert(make_pair(make_pair(make_pair(emitter,emission),spectator),make_pair(*it,*d)));
- if ( (*d)->isSymmetric() ){
- lesssplittings++;
- done.insert(make_pair(make_pair(make_pair(emission,emitter),spectator),make_pair(*it,*d)));
- }
- }else{
- // cout<<"\nsetupBookkeeping returned empty";
-// for (int born=0; born < int(bornrep.size());born++)
- // cout<<" " <<bornrep[born]->id();
-
-// cout<<"\nreal:";
- // for ( int emitter = 0; emitter < nreal; ++emitter )
- // cout<<" " <<rep[emitter]->id();
-
-
- }
- }
- }
- }
- }
- }
-
- if(int(done.size()-lesssplittings)==0){
- cout<<"\ndone.size "<<done.size()<<" lesssplittings "<<lesssplittings<<"\n";
- for (int born=0; born < int(bornrep.size());born++)
- cout<<" " <<bornrep[born]->id();
- cout<<"\nreals size "<<reals.size();
- cout<<"\ndipoles size "<< dipoles.size();
- }
-
-
- return int(done.size()-lesssplittings);
-
-}
-
-
-
-
double MatchboxMEBase::colourCorrelatedME2(pair<int,int> ij) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
double res =
matchboxAmplitude()->colourCorrelatedME2(ij)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::colourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr largeNBasis) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() ) {
largeNBasis->prepare(mePartonData(),false);
matchboxAmplitude()->prepareAmplitudes(this);
}
double res =
matchboxAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::largeNColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
double res =
matchboxAmplitude()->spinColourCorrelatedME2(ij,c)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::spinColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::spinCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
double res =
matchboxAmplitude()->spinCorrelatedME2(ij,c)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::spinCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
void MatchboxMEBase::flushCaches() {
MEBase::flushCaches();
if ( matchboxAmplitude() )
matchboxAmplitude()->flushCaches();
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator r =
reweights().begin(); r != reweights().end(); ++r ) {
(**r).flushCaches();
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
(**v).flushCaches();
}
}
+
+void MatchboxMEBase::setKinematics() {
+ MEBase::setKinematics();
+ if ( theMerger ) {
+ theMerger->setKinematics(this);
+ }
+}
+
+void MatchboxMEBase::clearKinematics() {
+ MEBase::clearKinematics();
+ if ( theMerger ) {
+ theMerger->clearKinematics(this);
+ }
+
+}
+
void MatchboxMEBase::fillProjectors() {
if (!theMerger)return;
if (theProjectorStage==0)return;
if (theMerger) {
theMerger->fillProjectors(this);
}
}
-
-
-
const Ptr<MergerBase>::ptr& MatchboxMEBase::merger() const {
return theMerger;
}
Ptr<MergerBase>::ptr& MatchboxMEBase::merger() {
return theMerger;
}
void MatchboxMEBase::merger(Ptr<MergerBase>::ptr v) {
theMerger = v;
}
-
-
- bool MatchboxMEBase::subNode() const {
+bool MatchboxMEBase::subNode() const {
return theSubNode;
}
-
-
void MatchboxMEBase::subNode(bool v) {
theSubNode = v;
}
-
pair<bool,bool> MatchboxMEBase::clustersafe(int emit,int emis,int spec){
if (theMerger) {
return theMerger->clusterSafe(this, emit, emis, spec);
}
return make_pair(true,true);
}
void MatchboxMEBase::print(ostream& os) const {
os << "--- MatchboxMEBase setup -------------------------------------------------------\n";
os << " '" << name() << "' for subprocess:\n";
os << " ";
for ( PDVector::const_iterator pp = subProcess().legs.begin();
pp != subProcess().legs.end(); ++pp ) {
os << (**pp).PDGName() << " ";
if ( pp == subProcess().legs.begin() + 1 )
os << "-> ";
}
os << "\n";
os << " including " << (oneLoop() ? "" : "no ") << "virtual corrections";
if ( oneLoopNoBorn() )
os << " without Born contributions";
if ( oneLoopNoLoops() )
os << " without loop contributions";
os << "\n";
if ( oneLoop() && !onlyOneLoop() ) {
os << " using insertion operators\n";
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
os << " '" << (**v).name() << "' with "
<< ((**v).isDR() ? "" : "C") << "DR/";
if ( (**v).isCS() )
os << "CS";
if ( (**v).isBDK() )
os << "BDK";
if ( (**v).isExpanded() )
os << "expanded";
os << " conventions\n";
}
}
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void MatchboxMEBase::printLastEvent(ostream& os) const {
os << "--- MatchboxMEBase last event information --------------------------------------\n";
os << " for matrix element '" << name() << "'\n";
os << " process considered:\n ";
int in = 0;
for ( cPDVector::const_iterator p = mePartonData().begin();
p != mePartonData().end(); ++p ) {
os << (**p).PDGName() << " ";
if ( ++in == 2 )
os << " -> ";
}
os << " kinematic environment as set by the XComb " << lastXCombPtr() << ":\n"
<< " sqrt(shat)/GeV = " << sqrt(lastSHat()/GeV2)
<< " x1 = " << lastX1() << " x2 = " << lastX2()
<< " alphaS = " << lastAlphaS() << "\n";
os << " momenta/GeV generated from random numbers\n ";
copy(lastXComb().lastRandomNumbers().begin(),
lastXComb().lastRandomNumbers().end(),ostream_iterator<double>(os," "));
os << ":\n ";
for ( vector<Lorentz5Momentum>::const_iterator p = meMomenta().begin();
p != meMomenta().end(); ++p ) {
os << (*p/GeV) << "\n ";
}
os << "last cross section/nb calculated was:\n "
<< (lastMECrossSection()/nanobarn) << " (pdf weight " << lastMEPDFWeight() << ")\n";
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void MatchboxMEBase::logGenerateKinematics(const double * r) const {
if ( !verbose() )
return;
generator()->log() << "'" << name() << "' generated kinematics\nfrom "
<< nDim() << " random numbers:\n";
copy(r,r+nDim(),ostream_iterator<double>(generator()->log()," "));
generator()->log() << "\n";
generator()->log() << "storing phase space information in XComb "
<< lastXCombPtr() << "\n";
generator()->log() << "generated phase space point (in GeV):\n";
vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
cPDVector::const_iterator dit = mePartonData().begin();
for ( ; pit != meMomenta().end() ; ++pit, ++dit )
generator()->log() << (**dit).PDGName() << " : "
<< (*pit/GeV) << "\n";
generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
<< "and Jacobian = " << jacobian() << " sHat/GeV2 = "
<< (lastSHat()/GeV2) << "\n" << flush;
}
void MatchboxMEBase::logSetScale() const {
if ( !verbose() )
return;
generator()->log() << "'" << name() << "' set scales using XComb " << lastXCombPtr() << ":\n"
<< "scale/GeV2 = " << (scale()/GeV2) << " xi_R = "
<< renormalizationScaleFactor() << " xi_F = "
<< factorizationScaleFactor() << "\n"
<< "alpha_s = " << lastAlphaS() << "\n" << flush;
}
void MatchboxMEBase::logPDFWeight() const {
if ( !verbose() )
return;
generator()->log() << "'" << name() << "' calculated pdf weight = "
<< lastMEPDFWeight() << " from XComb "
<< lastXCombPtr() << "\n"
<< "x1 = " << lastX1() << " (" << (mePartonData()[0]->coloured() ? "" : "not ") << "used) "
<< "x2 = " << lastX2() << " (" << (mePartonData()[1]->coloured() ? "" : "not ") << "used)\n"
<< flush;
}
void MatchboxMEBase::logME2() const {
if ( !verbose() )
return;
generator()->log() << "'" << name() << "' evaluated me2 using XComb "
<< lastXCombPtr() << "\n"
<< "and phase space point (in GeV):\n";
vector<Lorentz5Momentum>::const_iterator pit = meMomenta().begin();
cPDVector::const_iterator dit = mePartonData().begin();
for ( ; pit != meMomenta().end() ; ++pit, ++dit )
generator()->log() << (**dit).PDGName() << " : "
<< (*pit/GeV) << "\n";
generator()->log() << "with x1 = " << lastX1() << " x2 = " << lastX2() << "\n"
<< "sHat/GeV2 = " << (lastSHat()/GeV2) << "\n" << flush;
}
void MatchboxMEBase::logDSigHatDR() const {
if ( !verbose() )
return;
generator()->log() << "'" << name() << "' evaluated cross section using XComb "
<< lastXCombPtr() << "\n"
<< "Jacobian = " << jacobian() << " sHat/GeV2 = "
<< (lastSHat()/GeV2) << " dsig/nb = "
<< (lastMECrossSection()/nanobarn) << "\n" << flush;
}
void MatchboxMEBase::cloneDependencies(const std::string& prefix,bool slim) {
if ( phasespace() && !slim ) {
Ptr<MatchboxPhasespace>::ptr myPhasespace = phasespace()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myPhasespace->name();
if ( ! (generator()->preinitRegister(myPhasespace,pname.str()) ) )
throw Exception() << "MatchboxMEBase::cloneDependencies(): Phasespace generator " << pname.str() << " already existing." << Exception::runerror;
myPhasespace->cloneDependencies(pname.str());
phasespace(myPhasespace);
}
theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
if ( matchboxAmplitude() ) {
Ptr<MatchboxAmplitude>::ptr myAmplitude = matchboxAmplitude()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myAmplitude->name();
if ( ! (generator()->preinitRegister(myAmplitude,pname.str()) ) ){
throw Exception() << "MatchboxMEBase::cloneDependencies(): Amplitude " << pname.str() << " already existing." << Exception::runerror;
}
myAmplitude->cloneDependencies(pname.str(),slim);
matchboxAmplitude(myAmplitude);
amplitude(myAmplitude);
matchboxAmplitude()->orderInGs(orderInAlphaS());
matchboxAmplitude()->orderInGem(orderInAlphaEW());
}
if ( scaleChoice() &&!slim ) {
Ptr<MatchboxScaleChoice>::ptr myScaleChoice = scaleChoice()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myScaleChoice->name();
if ( ! (generator()->preinitRegister(myScaleChoice,pname.str()) ) )
throw Exception() << "MatchboxMEBase::cloneDependencies(): Scale choice " << pname.str() << " already existing." << Exception::runerror;
scaleChoice(myScaleChoice);
}
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
Ptr<MatchboxReweightBase>::ptr myReweight = (**rw).cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << (**rw).name();
if ( ! (generator()->preinitRegister(myReweight,pname.str()) ) )
throw Exception() << "MatchboxMEBase::cloneDependencies(): Reweight " << pname.str() << " already existing." << Exception::runerror;
myReweight->cloneDependencies(pname.str());
*rw = myReweight;
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
Ptr<MatchboxInsertionOperator>::ptr myIOP = (**v).cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << (**v).name();
if ( ! (generator()->preinitRegister(myIOP,pname.str()) ) )
throw Exception() << "MatchboxMEBase::cloneDependencies(): Insertion operator " << pname.str() << " already existing." << Exception::runerror;
*v = myIOP;
}
}
void MatchboxMEBase::prepareXComb(MatchboxXCombData& xc) const {
// fixme We need to pass on the partons from the xcmob here, not
// assuming one subprocess per matrix element
if ( phasespace() )
xc.nDimPhasespace(phasespace()->nDim(diagrams().front()->partons()));
if ( matchboxAmplitude() ) {
xc.nDimAmplitude(matchboxAmplitude()->nDimAdditional());
if ( matchboxAmplitude()->colourBasis() ) {
size_t cdim =
matchboxAmplitude()->colourBasis()->prepare(diagrams(),noCorrelations());
xc.colourBasisDim(cdim);
}
if ( matchboxAmplitude()->isExternal() ) {
xc.externalId(matchboxAmplitude()->externalId(diagrams().front()->partons()));
}
}
int insertionAdd = 0;
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
insertionAdd = max(insertionAdd,(**v).nDimAdditional());
}
xc.nDimInsertions(insertionAdd);
xc.nLight(getNLight());
if(xc.nLightJetVec().empty())
for (size_t inlv=0; inlv<getNLightJetVec().size(); ++inlv)
xc.nLightJetVec(getNLightJetVec()[inlv]);
if(xc.nHeavyJetVec().empty())
for (size_t inhv=0; inhv<getNHeavyJetVec().size(); ++inhv)
xc.nHeavyJetVec(getNHeavyJetVec()[inhv]);
if(xc.nLightProtonVec().empty())
for (size_t inlpv=0; inlpv<getNLightProtonVec().size(); ++inlpv)
xc.nLightProtonVec(getNLightProtonVec()[inlpv]);
xc.olpId(olpProcess());
if ( initVerbose() ) {
ostringstream fname_strm;
// only allow alphanumeric, / and _ in filename
BOOST_FOREACH (const char c, name()) {
switch (c) {
case '+' : fname_strm << "+"; break;
case '-' : fname_strm << "-"; break;
case '~' : fname_strm << "_tilde"; break;
case ']' : break;
case ',' : fname_strm << "__"; break;
default : fname_strm << (isalnum(c) ? c : '_'); break;
}
}
fname_strm << ".diagrams";
const string fname = fname_strm.str();
ifstream test(fname.c_str());
if ( !test ) {
test.close();
ofstream out(fname.c_str());
for ( vector<Ptr<DiagramBase>::ptr>::const_iterator d = diagrams().begin();
d != diagrams().end(); ++d ) {
DiagramDrawer::drawDiag(out,dynamic_cast<const Tree2toNDiagram&>(**d));
out << "\n";
}
}
}
}
StdXCombPtr MatchboxMEBase::makeXComb(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts,
const DiagramVector & newDiagrams, bool mir,
const PartonPairVec&,
tStdXCombPtr newHead,
tMEPtr newME) {
if ( !newME )
newME = this;
Ptr<MatchboxXComb>::ptr xc =
new_ptr(MatchboxXComb(newMaxEnergy, inc,
newEventHandler, newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts, newME,
newDiagrams, mir,
newHead));
prepareXComb(*xc);
return xc;
}
StdXCombPtr MatchboxMEBase::makeXComb(tStdXCombPtr newHead,
const PBPair & newPartonBins,
const DiagramVector & newDiagrams,
tMEPtr newME) {
if ( !newME )
newME = this;
Ptr<MatchboxXComb>::ptr xc =
new_ptr(MatchboxXComb(newHead, newPartonBins, newME, newDiagrams));
prepareXComb(*xc);
return xc;
}
void MatchboxMEBase::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << theFactory << thePhasespace
<< theAmplitude << theScaleChoice << theVirtuals
<< theReweights << theSubprocess << theOneLoop
<< theOneLoopNoBorn << theOneLoopNoLoops
<< epsilonSquarePoleHistograms << epsilonPoleHistograms
<< theSubNode<< theProjectorStage
<< theMerger
<< 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
>> theSubNode >> theProjectorStage
>> theMerger
>> theOLPProcess >> theNoCorrelations
>> theHavePDFs >> checkedPDFs>>theDiagramWeightVerboseDown>>theDiagramWeightVerboseUp;
lastMatchboxXComb(theLastXComb);
}
void MatchboxMEBase::Init() {
static ClassDocumentation<MatchboxMEBase> documentation
("MatchboxMEBase is the base class for matrix elements "
"in the context of the matchbox NLO interface.");
}
IBPtr MatchboxMEBase::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxMEBase::fullclone() const {
return new_ptr(*this);
}
void MatchboxMEBase::doinit() {
MEBase::doinit();
if ( !theAmplitude )
theAmplitude = dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(amplitude());
if ( matchboxAmplitude() )
matchboxAmplitude()->init();
if ( phasespace() ) {
phasespace()->init();
matchboxAmplitude()->checkReshuffling(phasespace());
}
if ( scaleChoice() ) {
scaleChoice()->init();
}
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
(**rw).init();
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
(**v).init();
}
}
void MatchboxMEBase::bookMEoverDiaWeight(double x) const {
if (MEoverDiaWeight.size()==0){
theDiagramWeightVerboseDown=min(theDiagramWeightVerboseDown,x*0.9);
theDiagramWeightVerboseUp=max(theDiagramWeightVerboseUp,x*1.1);
}
map<double,double>::iterator bx =MEoverDiaWeight.upper_bound(x);
if ( bx == MEoverDiaWeight.end() ) {
return;
}
bx->second += 1.;
Nevents++;
if (int(Nevents)%1000==0){
ofstream out((RunDirectories::runStorage()+"/"+name()+"-MeoDiaW.dat").c_str());
int i=0;
double m=0.;
for ( map<double,double>::const_iterator bx = MEoverDiaWeight.begin();bx != MEoverDiaWeight.end(); ++bx,i++ ) {
out << " " << bx->first<<" "<<( bx->second/double(Nevents))<<"\n ";
m=max(m,bx->second/double(Nevents));
}
out.close();
ofstream gpout((RunDirectories::runStorage()+"/"+name()+"-MeoDiaW.gp").c_str());
gpout << "set terminal epslatex color solid\n"
<< "set output '" << name()<<"-MeoDiaW"<< "-plot.tex'\n"
<< "#set logscale x\n"
<< "set xrange [" << theDiagramWeightVerboseDown << ":" << theDiagramWeightVerboseUp << "]\n"
<< "set yrange [0.:"<<(m*0.95)<<"]\n"
<< "set xlabel '$log(ME/\\sum DiaW)$'\n"
<< "set size 0.7,0.7\n"
<< "plot 1 w lines lc rgbcolor \"#DDDDDD\" notitle, '" << name()<<"-MeoDiaW"
<< ".dat' with histeps lc rgbcolor \"#00AACC\" t '$"<<name()<<"$'";
gpout.close();
}
}
void MatchboxMEBase::doinitrun() {
MEBase::doinitrun();
if ( matchboxAmplitude() )
matchboxAmplitude()->initrun();
if ( phasespace() ) {
phasespace()->initrun();
}
if ( scaleChoice() ) {
scaleChoice()->initrun();
}
for ( vector<Ptr<MatchboxReweightBase>::ptr>::iterator rw =
theReweights.begin(); rw != theReweights.end(); ++rw ) {
(**rw).initrun();
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::iterator v =
virtuals().begin(); v != virtuals().end(); ++v ) {
(**v).initrun();
}
if ( factory()->verboseDia() ) {
for ( int k = 0; k < factory()->diagramWeightVerboseNBins() ; ++k ) {
MEoverDiaWeight[theDiagramWeightVerboseDown+
double(k)*(theDiagramWeightVerboseUp-
theDiagramWeightVerboseDown)
/double(factory()->diagramWeightVerboseNBins()) ] = 0.;
}
Nevents=0.;
ofstream out("DiagramWeights.sh");
out<<"P=$(pwd)"
<<"\ncd "<<RunDirectories::runStorage()
<<"\nrm -f DiagramWeights.tex"
<<"\n echo \"\\documentclass{article}\" >> DiagramWeights.tex"
<<"\n echo \"\\usepackage{amsmath,amsfonts,amssymb,graphicx,color}\" >> DiagramWeights.tex"
<<"\n echo \"\\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}\" >> DiagramWeights.tex"
<<"\n echo \"\\begin{document}\" >> DiagramWeights.tex"
<<"\n echo \"\\setlength{\\parindent}{0cm}\" >> DiagramWeights.tex"
<<"\n\n for i in $(ls *.gp | sed s/'\\.gp'//g) ; "
<<"\n do"
<<"\n echo \"\\input{\"\"$i\"-plot\"}\" >> DiagramWeights.tex"
<<"\n done"
<<"\n echo \"\\end{document}\" >> DiagramWeights.tex "
<<"\n for i in *.gp ; do "
<<"\n gnuplot $i "
<<"\n done "
<<"\n pdflatex DiagramWeights.tex \ncp DiagramWeights.pdf $P";
out.close();
}
}
void MatchboxMEBase::dofinish() {
MEBase::dofinish();
for ( map<cPDVector,AccuracyHistogram>::const_iterator
b = epsilonSquarePoleHistograms.begin();
b != epsilonSquarePoleHistograms.end(); ++b ) {
b->second.dump(factory()->poleData(),"epsilonSquarePoles-",b->first);
}
for ( map<cPDVector,AccuracyHistogram>::const_iterator
b = epsilonPoleHistograms.begin();
b != epsilonPoleHistograms.end(); ++b ) {
b->second.dump(factory()->poleData(),"epsilonPoles-",b->first);
}
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxMEBase,MEBase>
describeHerwigMatchboxMEBase("Herwig::MatchboxMEBase", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Base/MatchboxMEBase.h b/MatrixElement/Matchbox/Base/MatchboxMEBase.h
--- a/MatrixElement/Matchbox/Base/MatchboxMEBase.h
+++ b/MatrixElement/Matchbox/Base/MatchboxMEBase.h
@@ -1,1237 +1,1237 @@
// -*- C++ -*-
//
// MatchboxMEBase.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2012 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MatchboxMEBase_H
#define HERWIG_MatchboxMEBase_H
//
// This is the declaration of the MatchboxMEBase class.
//
#include "ThePEG/MatrixElement/MEBase.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h"
#include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxReweightBase.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.fh"
#include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh"
#include "Herwig/MatrixElement/Matchbox/InsertionOperators/MatchboxInsertionOperator.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
#include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXComb.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxMEBase is the base class for matrix elements
* in the context of the matchbox NLO interface.
*
* @see \ref MatchboxMEBaseInterfaces "The interfaces"
* defined for MatchboxMEBase.
*/
class MatchboxMEBase:
public MEBase, public LastMatchboxXCombInfo {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
MatchboxMEBase();
/**
* The destructor.
*/
virtual ~MatchboxMEBase();
//@}
public:
/**
* Return the factory which produced this matrix element
*/
Ptr<MatchboxFactory>::tptr factory() const;
/**
* Set the factory which produced this matrix element
*/
void factory(Ptr<MatchboxFactory>::tptr f);
/** @name Subprocess and diagram information. */
//@{
/**
* Return the subprocess.
*/
const Process& subProcess() const { return theSubprocess; }
/**
* Access the subprocess.
*/
Process& subProcess() { return theSubprocess; }
/**
* Return the diagram generator.
*/
Ptr<Tree2toNGenerator>::tptr diagramGenerator() const;
/**
* Return the process data.
*/
Ptr<ProcessData>::tptr processData() const;
/**
* Return true, if this matrix element does not want to
* make use of mirroring processes; in this case all
* possible partonic subprocesses with a fixed assignment
* of incoming particles need to be provided through the diagrams
* added with the add(...) method.
*/
virtual bool noMirror () const { return true; }
/**
* Add all possible diagrams with the add() function.
*/
virtual void getDiagrams() const;
using MEBase::getDiagrams;
/**
* With the information previously supplied with the
* setKinematics(...) method, a derived class may optionally
* override this method to weight the given diagrams with their
* (although certainly not physical) relative probabilities.
*/
virtual Selector<DiagramIndex> diagrams(const DiagramVector &) const;
using MEBase::diagrams;
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
*/
virtual Selector<const ColourLines *>
colourGeometries(tcDiagPtr diag) const;
/**
* Return true, if this amplitude is capable of consistently filling
* the rho matrices for the spin correllations
*/
virtual bool canFillRhoMatrix() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->canFillRhoMatrix();
return false;
}
/**
* construct the spin information for the interaction
*/
virtual void constructVertex(tSubProPtr) {}
/**
* construct the spin information for the interaction
*/
virtual void constructVertex(tSubProPtr sub, const ColourLines* cl);
/**
* Return the order in \f$\alpha_S\f$ in which this matrix element
* is given.
*/
virtual unsigned int orderInAlphaS() const;
using MEBase::orderInAlphaS;
/**
* Return the order in \f$\alpha_{EM}\f$ in which this matrix
* element is given. Returns 0.
*/
virtual unsigned int orderInAlphaEW() const;
using MEBase::orderInAlphaEW;
/**
* Return true, if this amplitude already includes averaging over
* incoming parton's quantum numbers.
*/
virtual bool hasInitialAverage() const {
return matchboxAmplitude() ? matchboxAmplitude()->hasInitialAverage() : false;
}
/**
* Return true, if this amplitude already includes symmetry factors
* for identical outgoing particles.
*/
virtual bool hasFinalStateSymmetry() const {
return matchboxAmplitude() ? matchboxAmplitude()->hasFinalStateSymmetry() : false;
}
/**
* Return the number of light flavours, this matrix
* element is calculated for.
*/
virtual unsigned int getNLight() const;
/**
* Return the vector that contains the PDG ids of
* the light flavours, which are contained in the
* jet particle group.
*/
virtual vector<int> getNLightJetVec() const;
/**
* Return the vector that contains the PDG ids of
* the heavy flavours, which are contained in the
* jet particle group.
*/
virtual vector<int> getNHeavyJetVec() const;
/**
* Return the vector that contains the PDG ids of
* the light flavours, which are contained in the
* proton particle group.
*/
virtual vector<int> getNLightProtonVec() const;
/**
* Return true, if this matrix element is handled by a BLHA one-loop provider
*/
virtual bool isOLPTree() const {
return matchboxAmplitude() ? matchboxAmplitude()->isOLPTree() : false;
}
/**
* Return true, if this matrix element is handled by a BLHA one-loop provider
*/
virtual bool isOLPLoop() const {
return matchboxAmplitude() ? matchboxAmplitude()->isOLPLoop() : false;
}
/**
* Return true, if colour and spin correlated matrix elements should
* be ordered from the OLP
*/
virtual bool needsOLPCorrelators() const {
return matchboxAmplitude() ? matchboxAmplitude()->needsOLPCorrelators() : true;
}
/**
* Return the process index, if this is an OLP handled matrix element
*/
const vector<int>& olpProcess() const { return theOLPProcess; }
/**
* Set the process index, if this is an OLP handled matrix element
*/
void olpProcess(int pType, int id) {
if ( theOLPProcess.empty() )
theOLPProcess.resize(5,0);
theOLPProcess[pType] = id;
}
/**
* Return true, if this is a real emission matrix element which does
* not require colour correlators.
*/
bool noCorrelations() const {
return theNoCorrelations;
}
/**
* Indicate that this is a real emission matrix element which does
* not require colour correlators.
*/
void needsNoCorrelations() {
theNoCorrelations = true;
}
/**
* Indicate that this is a virtual matrix element which does
* require colour correlators.
*/
void needsCorrelations() {
theNoCorrelations = false;
}
//@}
/** @name Phasespace generation */
//@{
/**
* Return the phase space generator to be used.
*/
Ptr<MatchboxPhasespace>::tptr phasespace() const { return thePhasespace; }
/**
* Set the phase space generator to be used.
*/
void phasespace(Ptr<MatchboxPhasespace>::ptr ps) { thePhasespace = ps; }
/**
* Set the XComb object to be used in the next call to
* generateKinematics() and dSigHatDR().
*/
virtual void setXComb(tStdXCombPtr xc);
/**
* Return true, if the XComb steering this matrix element
* should keep track of the random numbers used to generate
* the last phase space point
*/
virtual bool keepRandomNumbers() const { return true; }
/**
* Generate incoming parton momenta. This default
* implementation performs the standard mapping
* from x1,x2 -> tau,y making 1/tau flat; incoming
* parton momenta are stored in meMomenta()[0,1],
* only massless partons are supported so far;
* return the Jacobian of the mapping
*/
double generateIncomingPartons(const double* r1, const double* r2);
/**
* Generate internal degrees of freedom given nDim() uniform random
* numbers in the interval ]0,1[. To help the phase space generator,
* the 'dSigHatDR' should be a smooth function of these numbers,
* although this is not strictly necessary. The return value should
* be true of the generation succeeded. If so the generated momenta
* should be stored in the meMomenta() vector. Derived classes
* must call this method once internal degrees of freedom are setup
* and finally return the result of this method.
*/
virtual bool generateKinematics(const double * r);
/**
* Set the typed and momenta of the incoming and outgoing partons to
* be used in subsequent calls to me() and colourGeometries()
* according to the associated XComb object. If the function is
* overridden in a sub class the new function must call the base
* class one first.
*/
virtual void setKinematics();
/**
* Clear the information previously provided by a call to
* setKinematics(...).
*/
virtual void clearKinematics();
/**
* The number of internal degreed of freedom used in the matrix
* element.
*/
virtual int nDim() const;
/**
* The number of internal degrees of freedom used in the matrix
* element for generating a Born phase space point
*/
virtual int nDimBorn() const;
/**
* Return true, if this matrix element will generate momenta for the
* incoming partons itself. The matrix element is required to store
* the incoming parton momenta in meMomenta()[0,1]. No mapping in
* tau and y is performed by the PartonExtractor object, if a
* derived class returns true here. The phase space jacobian is to
* include a factor 1/(x1 x2).
*/
virtual bool haveX1X2() const {
return
(phasespace() ? phasespace()->haveX1X2() : false) ||
diagrams().front()->partons().size() == 3;
}
/**
* Return true, if this matrix element expects
* the incoming partons in their center-of-mass system
*/
virtual bool wantCMS() const {
return
(phasespace() ? phasespace()->wantCMS() : true) &&
diagrams().front()->partons().size() != 3; }
/**
* Return the meMomenta as generated at the last
* phase space point.
*/
const vector<Lorentz5Momentum>& lastMEMomenta() const { return meMomenta(); }
/**
* Access the meMomenta.
*/
vector<Lorentz5Momentum>& lastMEMomenta() { return meMomenta(); }
//@}
/** @name Scale choices, couplings and PDFs */
//@{
/**
* Set the scale choice object
*/
void scaleChoice(Ptr<MatchboxScaleChoice>::ptr sc) { theScaleChoice = sc; }
/**
* Return the scale choice object
*/
Ptr<MatchboxScaleChoice>::tptr scaleChoice() const { return theScaleChoice; }
/**
* Set scales and alphaS
*/
void setScale(Energy2 ren=ZERO,Energy2 fac=ZERO) const;
/**
* Indicate that this matrix element is running alphas by itself.
*/
virtual bool hasRunningAlphaS() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->hasRunningAlphaS();
return false;
}
/**
* Indicate that this matrix element is running alphaew by itself.
*/
virtual bool hasRunningAlphaEW() const {
if ( matchboxAmplitude() )
return matchboxAmplitude()->hasRunningAlphaEW();
return false;
}
/**
* Return the scale associated with the phase space point provided
* by the last call to setKinematics().
*/
virtual Energy2 scale() const { return lastScale(); }
/**
* Return the renormalization scale for the last generated phasespace point.
*/
virtual Energy2 factorizationScale() const;
/**
* Get the factorization scale factor
*/
virtual double factorizationScaleFactor() const;
/**
* Return the (QCD) renormalization scale for the last generated phasespace point.
*/
virtual Energy2 renormalizationScale() const;
/**
* Get the renormalization scale factor
*/
virtual double renormalizationScaleFactor() const;
/**
* Return the QED renormalization scale for the last generated phasespace point.
*/
virtual Energy2 renormalizationScaleQED() const;
/**
* Return the shower scale for the last generated phasespace point.
*/
virtual Energy2 showerScale() const;
/**
* Set veto scales on the particles at the given
* SubProcess which has been generated using this
* matrix element.
*/
virtual void setVetoScales(tSubProPtr) const;
/**
* Return true, if fixed couplings are used.
*/
bool fixedCouplings() const;
/**
* Return true, if fixed couplings are used.
*/
bool fixedQEDCouplings() const;
/**
* Return the value of \f$\alpha_S\f$ associated with the phase
* space point provided by the last call to setKinematics(). This
* versions returns SM().alphaS(scale()).
*/
virtual double alphaS() const { return lastAlphaS(); }
/**
* Return the value of \f$\alpha_EM\f$ associated with the phase
* space point provided by the last call to setKinematics(). This
* versions returns SM().alphaEM(scale()).
*/
virtual double alphaEM() const { return lastAlphaEM(); }
/**
* Return true, if this matrix element provides the PDF
* weight for the first incoming parton itself.
*/
virtual bool havePDFWeight1() const;
/**
* Return true, if this matrix element provides the PDF
* weight for the second incoming parton itself.
*/
virtual bool havePDFWeight2() const;
/**
* Set the PDF weight.
*/
void getPDFWeight(Energy2 factorizationScale = ZERO) const;
/**
* Supply the PDF weight for the first incoming parton.
*/
double pdf1(Energy2 factorizationScale = ZERO,
double xEx = 1., double xFactor = 1.) const;
/**
* Supply the PDF weight for the second incoming parton.
*/
double pdf2(Energy2 factorizationScale = ZERO,
double xEx = 1., double xFactor = 1.) const;
//@}
/** @name Amplitude information and matrix element evaluation */
//@{
/**
* Return the amplitude.
*/
Ptr<MatchboxAmplitude>::tptr matchboxAmplitude() const { return theAmplitude; }
/**
* Set the amplitude.
*/
void matchboxAmplitude(Ptr<MatchboxAmplitude>::ptr amp) { theAmplitude = amp; }
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const;
/**
* Return the symmetry factor for identical final state particles.
*/
virtual double finalStateSymmetry() const;
/**
* Return the normalizing factor for the matrix element averaged
* over quantum numbers and including running couplings.
*/
double me2Norm(unsigned int addAlphaS = 0) const;
/**
* Return the matrix element squared differential in the variables
* given by the last call to generateKinematics().
*/
virtual CrossSection dSigHatDR() const{return dSigHatDR(1.);}
/**
- * Provide a possible faster, approximated dSigHatDR() method.
+ * Return the matrix element squared differential in the variables
+ * given by the last call to generateKinematics().
+ * If diffAlpha is not 1 and the matrix element has insertion operators
+ * this routine adds the difference between the insertion operator calculated
+ * an alpha-Parameter to the insertion operator without alpha-parameter.
*/
CrossSection dSigHatDR(double diffAlpha) const;
//@}
/** @name One-loop corrections */
//@{
/**
* Return the one-loop/tree interference.
*/
virtual double oneLoopInterference() const;
/**
* Return true, if this matrix element is capable of calculating
* one-loop (QCD) corrections.
*/
virtual bool haveOneLoop() const;
/**
* Return true, if this matrix element only provides
* one-loop (QCD) corrections.
*/
virtual bool onlyOneLoop() const;
/**
* Return true, if the amplitude is DRbar renormalized, otherwise
* MSbar is assumed.
*/
virtual bool isDRbar() const;
/**
* Return true, if one loop corrections have been calculated in
* dimensional reduction. Otherwise conventional dimensional
* regularization is assumed. Note that renormalization is always
* assumed to be MSbar.
*/
virtual bool isDR() const;
/**
* Return true, if one loop corrections are given in the conventions
* of the integrated dipoles.
*/
virtual bool isCS() const;
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const;
/**
* Return true, if one loop corrections are given in the conventions
* of everything expanded.
*/
virtual bool isExpanded() const;
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const;
/**
* If defined, return the coefficient of the pole in epsilon^2
*/
virtual double oneLoopDoublePole() const;
/**
* If defined, return the coefficient of the pole in epsilon
*/
virtual double oneLoopSinglePole() const;
/**
* Return true, if cancellationn of epsilon poles should be checked.
*/
bool checkPoles() const;
/**
* Simple histogram for accuracy checks
*/
struct AccuracyHistogram {
/**
* The lower bound
*/
double lower;
/**
* The upper bound
*/
double upper;
/**
* The bins, indexed by upper bound.
*/
map<double,double> bins;
/**
* The number of points of same sign
*/
unsigned long sameSign;
/**
* The number of points of opposite sign
*/
unsigned long oppositeSign;
/**
* The number of points being nan or inf
*/
unsigned long nans;
/**
* The overflow
*/
unsigned long overflow;
/**
* The underflow
*/
unsigned long underflow;
/**
* Constructor
*/
AccuracyHistogram(double low = -40.,
double up = 0.,
unsigned int nbins = 80);
/**
* Book two values to be checked for numerical compatibility
*/
void book(double a, double b);
/**
* Write to file.
*/
void dump(const std::string& folder, const std::string& prefix,
const cPDVector& proc) const;
/**
* Write to persistent ostream
*/
void persistentOutput(PersistentOStream&) const;
/**
* Read from persistent istream
*/
void persistentInput(PersistentIStream&);
};
/**
* Perform the check of epsilon pole cancellation.
*/
void logPoles() const;
/**
* Return the virtual corrections
*/
const vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() const {
return theVirtuals;
}
/**
* Return the virtual corrections
*/
vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() {
return theVirtuals;
}
/**
* Instruct this matrix element to include one-loop corrections
*/
void doOneLoop() { theOneLoop = true; }
void noOneLoop() { theOneLoop = false; }
/**
* Return true, if this matrix element includes one-loop corrections
*/
bool oneLoop() const { return theOneLoop; }
/**
* Instruct this matrix element to include one-loop corrections but
* no Born contributions
*/
void doOneLoopNoBorn() { theOneLoop = true; theOneLoopNoBorn = true; }
void noOneLoopNoBorn() { theOneLoop = false; theOneLoopNoBorn = false; }
/**
* Return true, if this matrix element includes one-loop corrections
* but no Born contributions
*/
bool oneLoopNoBorn() const { return theOneLoopNoBorn || onlyOneLoop(); }
/**
* Instruct this matrix element to include one-loop corrections but
* no actual loop contributions
*/
void doOneLoopNoLoops() { theOneLoop = true; theOneLoopNoLoops = true; }
/**
* Return true, if this matrix element includes one-loop corrections
* but no actual loop contributions
*/
bool oneLoopNoLoops() const { return theOneLoopNoLoops; }
//@}
/** @name Dipole subtraction */
//@{
/**
* If this matrix element is considered a real
* emission matrix element, return all subtraction
* dipoles needed given a set of subtraction terms
* and underlying Born matrix elements to choose
* from.
*/
vector<Ptr<SubtractionDipole>::ptr>
getDipoles(const vector<Ptr<SubtractionDipole>::ptr>&,
const vector<Ptr<MatchboxMEBase>::ptr>&,bool slim=false) const;
-
- int
- numberOfSplittings(const vector<Ptr<SubtractionDipole>::ptr>&,
- const vector<Ptr<MatchboxMEBase>::ptr>& reals) const;
/**
* If this matrix element is considered a real emission matrix
* element, but actually neglecting a subclass of the contributing
* diagrams, return true if the given emitter-emission-spectator
* configuration should not be considered when setting up
* subtraction dipoles.
*/
virtual bool noDipole(int,int,int) const { return false; }
/**
* If this matrix element is considered an underlying Born matrix
* element in the context of a subtracted real emission, but
* actually neglecting a subclass of the contributing diagrams,
* return true if the given emitter-spectator configuration
* should not be considered when setting up subtraction dipoles.
*/
virtual bool noDipole(int,int) const { return false; }
/**
* Return the colour correlated matrix element squared with
* respect to the given two partons as appearing in mePartonData(),
* suitably scaled by sHat() to give a dimension-less number.
*/
virtual double colourCorrelatedME2(pair<int,int>) const;
/**
* Return the colour correlated matrix element squared in the
* large-N approximation with respect to the given two partons as
* appearing in mePartonData(), suitably scaled by sHat() to give a
* dimension-less number.
*/
virtual double largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr largeNBasis) const;
/**
* Return the colour and spin correlated matrix element squared for
* the gluon indexed by the first argument using the given
* correlation tensor.
*/
virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const;
/**
* Return the spin correlated matrix element squared for
* the vector boson indexed by the first argument using the given
* correlation tensor.
*/
virtual double spinCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const;
//@}
/** @name Caching and diagnostic information */
//@{
/**
* Inform this matrix element that a new phase space
* point is about to be generated, so all caches should
* be flushed.
*/
virtual void flushCaches();
/**
* Return true, if verbose
*/
bool verbose() const;
/**
* Return true, if verbose
*/
bool initVerbose() const;
/**
* Dump the setup to an ostream
*/
void print(ostream&) const;
/**
* Print debug information on the last event
*/
virtual void printLastEvent(ostream&) const;
/**
* Write out diagnostic information for
* generateKinematics
*/
void logGenerateKinematics(const double * r) const;
/**
* Write out diagnostic information for
* setting scales
*/
void logSetScale() const;
/**
* Write out diagnostic information for
* pdf evaluation
*/
void logPDFWeight() const;
/**
* Write out diagnostic information for
* me2 evaluation
*/
void logME2() const;
/**
* Write out diagnostic information
* for dsigdr evaluation
*/
void logDSigHatDR() const;
//@}
/** @name Reweight objects */
//@{
/**
* Insert a reweight object
*/
void addReweight(Ptr<MatchboxReweightBase>::ptr rw) { theReweights.push_back(rw); }
/**
* Return the reweights
*/
const vector<Ptr<MatchboxReweightBase>::ptr>& reweights() const { return theReweights; }
/**
* Access the reweights
*/
vector<Ptr<MatchboxReweightBase>::ptr>& reweights() { return theReweights; }
/**
* Return the theMerger.
*/
const Ptr<MergerBase>::ptr& merger() const;
/**
* Return the theMerger.
*/
Ptr<MergerBase>::ptr& merger() ;
/**
* Set the theMerger.
*/
void merger(Ptr<MergerBase>::ptr v);
/**
* Return the theSubNode.
*/
bool subNode() const;
/**
* Set the theSubNode.
*/
void subNode(bool v);
/**
* Fill the projectors
*/
virtual void fillProjectors();
/**
* Set the projector stage
*/
void projectorStage(int a) { theProjectorStage=a; }
/**
* Set the projector stage
*/
int projectorStage() {return theProjectorStage; }
pair<bool,bool> clustersafe(int emit,int emis,int spec);
//@}
/** @name Methods used to setup MatchboxMEBase objects */
//@{
/**
* Return true if this object needs to be initialized before all
* other objects (except those for which this function also returns
* true). This default version always returns false, but subclasses
* may override it to return true.
*/
virtual bool preInitialize() const { return true; }
/**
* Clone this matrix element.
*/
Ptr<MatchboxMEBase>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxMEBase>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
void cloneDependencies(const std::string& prefix = ""){cloneDependencies(prefix,false);};
void cloneDependencies(const std::string& prefix ,bool slim);
/**
* Prepare an xcomb
*/
void prepareXComb(MatchboxXCombData&) const;
/**
* For the given event generation setup return a xcomb object
* appropriate to this matrix element.
*/
virtual StdXCombPtr makeXComb(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts,
const DiagramVector & newDiagrams, bool mir,
const PartonPairVec& allPBins,
tStdXCombPtr newHead = tStdXCombPtr(),
tMEPtr newME = tMEPtr());
/**
* For the given event generation setup return a dependent xcomb object
* appropriate to this matrix element.
*/
virtual StdXCombPtr makeXComb(tStdXCombPtr newHead,
const PBPair & newPartonBins,
const DiagramVector & newDiagrams,
tMEPtr newME = tMEPtr());
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
/**
* Finalize this object. Called in the run phase just after a
* run has ended. Used eg. to write out statistics.
*/
virtual void dofinish();
//@}
private:
/**
* The factory which produced this matrix element
*/
Ptr<MatchboxFactory>::tptr theFactory;
/**
* The phase space generator to be used.
*/
Ptr<MatchboxPhasespace>::ptr thePhasespace;
/**
* The amplitude to be used
*/
Ptr<MatchboxAmplitude>::ptr theAmplitude;
/**
* The scale choice object
*/
Ptr<MatchboxScaleChoice>::ptr theScaleChoice;
/**
* The virtual corrections.
*/
vector<Ptr<MatchboxInsertionOperator>::ptr> theVirtuals;
/**
* A vector of reweight objects the sum of which
* should be applied to reweight this matrix element
*/
vector<Ptr<MatchboxReweightBase>::ptr> theReweights;
private:
/**
* The subprocess to be considered.
*/
Process theSubprocess;
/**
* True, if this matrix element includes one-loop corrections
*/
bool theOneLoop;
/**
* True, if this matrix element includes one-loop corrections
* but no Born contributions
*/
bool theOneLoopNoBorn;
/**
* True, if this matrix element includes one-loop corrections
* but no actual loop contributions (e.g. finite collinear terms)
*/
bool theOneLoopNoLoops;
/**
* The process index, if this is an OLP handled matrix element
*/
vector<int> theOLPProcess;
/**
* Histograms of epsilon^2 pole cancellation
*/
mutable map<cPDVector,AccuracyHistogram> epsilonSquarePoleHistograms;
/**
* Histograms of epsilon pole cancellation
*/
mutable map<cPDVector,AccuracyHistogram> epsilonPoleHistograms;
/**
* True, if this is a real emission matrix element which does
* not require colour correlators.
*/
bool theNoCorrelations;
/**
* Flag which pdfs should be included.
*/
mutable pair<bool,bool> theHavePDFs;
/**
* True, if already checked for which PDFs to include.
*/
mutable bool checkedPDFs;
/**
* Diagnostic Diagram for TreePhaseSpace
*/
void bookMEoverDiaWeight(double x) const;
mutable map<double,double > MEoverDiaWeight;
mutable int Nevents;
/**
* Range of diagram weight verbosity
*/
mutable double theDiagramWeightVerboseDown, theDiagramWeightVerboseUp;
/**
* The first cluster node
*/
Ptr<MergerBase>::ptr theMerger;
/**
* The first cluster node
*/
bool theSubNode;
/**
* The projector stage
*/
int theProjectorStage;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxMEBase & operator=(const MatchboxMEBase &);
};
inline PersistentOStream& operator<<(PersistentOStream& os,
const MatchboxMEBase::AccuracyHistogram& h) {
h.persistentOutput(os);
return os;
}
inline PersistentIStream& operator>>(PersistentIStream& is,
MatchboxMEBase::AccuracyHistogram& h) {
h.persistentInput(is);
return is;
}
}
#endif /* HERWIG_MatchboxMEBase_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FFggxDipole.cc
@@ -1,141 +1,138 @@
// -*- C++ -*-
//
// FFggxDipole.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 FFggxDipole class.
//
#include "FFggxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h"
using namespace Herwig;
FFggxDipole::FFggxDipole()
: SubtractionDipole() {}
FFggxDipole::~FFggxDipole() {}
IBPtr FFggxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FFggxDipole::fullclone() const {
return new_ptr(*this);
}
bool FFggxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator > 1 &&
partons[emission]->id() == ParticleID::g &&
partons[emitter]->id() == ParticleID::g &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FFggxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double res =
1./(1.-z*(1.-y)) + 1./(1.-(1.-z)*(1.-y)) - 2. + z*(1.-z);
res *= -ccme2;
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool FFggxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[0];}
-
double FFggxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
if ( alpha() < y )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double diag = 1./(1.-z*(1.-y))+1./(1.-(1.-z)*(1.-y))-2.;
Lorentz5Momentum pc =
z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] -
(1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()];
SpinCorrelationTensor corr(-diag,pc,prop/2.);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FFggxDipole::persistentOutput(PersistentOStream &) const {
}
void FFggxDipole::persistentInput(PersistentIStream &, int) {
}
void FFggxDipole::Init() {
static ClassDocumentation<FFggxDipole> documentation
("FFggxDipole");
DipoleRepository::registerDipole<0,FFggxDipole,FFLightTildeKinematics,FFLightInvertedTildeKinematics>
("FFggxDipole","FFLightTildeKinematics","FFLightInvertedTildeKinematics");
}
// *** 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<FFggxDipole,SubtractionDipole>
describeHerwigFFggxDipole("Herwig::FFggxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FFggxDipole.h b/MatrixElement/Matchbox/Dipoles/FFggxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FFggxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FFggxDipole.h
@@ -1,173 +1,167 @@
// -*- C++ -*-
//
// FFggxDipole.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_FFggxDipole_H
#define HERWIG_FFggxDipole_H
//
// This is the declaration of the FFggxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FFggxDipole implements the D_{g,g;k} subtraction dipole.
*
*/
class FFggxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFggxDipole();
/**
* The destructor.
*/
virtual ~FFggxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter > 1 && partons[emitter]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator > 1 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* Return true, if this dipole is symmetric with respect to emitter
* and emission.
*/
virtual bool isSymmetric() const { return true; }
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 4;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFggxDipole & operator=(const FFggxDipole &);
};
}
#endif /* HERWIG_FFggxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.cc
@@ -1,140 +1,137 @@
// -*- C++ -*-
//
// FFqgxDipole.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 FFqgxDipole class.
//
#include "FFqgxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h"
using namespace Herwig;
FFqgxDipole::FFqgxDipole()
: SubtractionDipole() {}
FFqgxDipole::~FFqgxDipole() {}
IBPtr FFqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FFqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool FFqgxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator > 1 &&
partons[emission]->id() == ParticleID::g &&
abs(partons[emitter]->id()) < 6 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FFqgxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= ( 2./(1.-z*(1.-y)) - (1.+z) );
res *= -ccme2;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool FFqgxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[0];}
-
double FFqgxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
if ( alpha() < y )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= ( 2./(1.-z*(1.-y)) - (1.+z) );
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FFqgxDipole::persistentOutput(PersistentOStream &) const {
}
void FFqgxDipole::persistentInput(PersistentIStream &, int) {
}
void FFqgxDipole::Init() {
static ClassDocumentation<FFqgxDipole> documentation
("FFqgxDipole");
DipoleRepository::registerDipole<0,FFqgxDipole,FFLightTildeKinematics,FFLightInvertedTildeKinematics>
("FFqgxDipole","FFLightTildeKinematics","FFLightInvertedTildeKinematics");
}
// *** 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<FFqgxDipole,SubtractionDipole>
describeHerwigFFqgxDipole("Herwig::FFqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FFqgxDipole.h
@@ -1,166 +1,160 @@
// -*- C++ -*-
//
// FFqgxDipole.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_FFqgxDipole_H
#define HERWIG_FFqgxDipole_H
//
// This is the declaration of the FFqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FFqgxDipole implements the D_{q,g;k} subtraction dipole.
*
*/
class FFqgxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFqgxDipole();
/**
* The destructor.
*/
virtual ~FFqgxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter > 1 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator > 1 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 3;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFqgxDipole & operator=(const FFqgxDipole &);
};
}
#endif /* HERWIG_FFqgxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.cc
@@ -1,142 +1,138 @@
// -*- C++ -*-
//
// FFqqxDipole.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 FFqqxDipole class.
//
#include "FFqqxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h"
using namespace Herwig;
FFqqxDipole::FFqqxDipole()
: SubtractionDipole() {}
FFqqxDipole::~FFqqxDipole() {}
IBPtr FFqqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FFqqxDipole::fullclone() const {
return new_ptr(*this);
}
bool FFqqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator > 1 &&
abs(partons[emission]->id()) < 6 &&
abs(partons[emitter]->id()) < 6 &&
partons[emission]->id() + partons[emitter]->id() == 0 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FFqqxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double z = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double res = 1.-2.*z*(1.-z);
res *= -ccme2;
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool FFqqxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[0];}
-
-
double FFqqxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
if ( alpha() < y )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
Lorentz5Momentum pc =
z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] -
(1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()];
SpinCorrelationTensor corr(-1.,pc,-prop/4.);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FFqqxDipole::persistentOutput(PersistentOStream &) const {
}
void FFqqxDipole::persistentInput(PersistentIStream &, int) {
}
void FFqqxDipole::Init() {
static ClassDocumentation<FFqqxDipole> documentation
("FFqqxDipole");
DipoleRepository::registerDipole<0,FFqqxDipole,FFLightTildeKinematics,FFLightInvertedTildeKinematics>
("FFqqxDipole","FFLightTildeKinematics","FFLightInvertedTildeKinematics");
}
// *** 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<FFqqxDipole,SubtractionDipole>
describeHerwigFFqqxDipole("Herwig::FFqqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FFqqxDipole.h
@@ -1,174 +1,168 @@
// -*- C++ -*-
//
// FFqqxDipole.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_FFqqxDipole_H
#define HERWIG_FFqqxDipole_H
//
// This is the declaration of the FFqqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FFqqxDipole implements the D_{q,qbar;k} subtraction dipole.
*
*/
class FFqqxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFqqxDipole();
/**
* The destructor.
*/
virtual ~FFqqxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter > 1 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return
canHandleEmitter(partons,emitter) &&
partons[emitter]->id() + partons[emission]->id() == 0;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator > 1 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 1;}
/**
* Return true, if this dipole is symmetric with respect to emitter
* and emission.
*/
virtual bool isSymmetric() const { return true; }
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFqqxDipole & operator=(const FFqqxDipole &);
};
}
#endif /* HERWIG_FFqqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FIggxDipole.cc
@@ -1,155 +1,151 @@
// -*- C++ -*-
//
// FIggxDipole.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 FIggxDipole class.
//
#include "FIggxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h"
using namespace Herwig;
FIggxDipole::FIggxDipole()
: SubtractionDipole() {}
FIggxDipole::~FIggxDipole() {}
IBPtr FIggxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FIggxDipole::fullclone() const {
return new_ptr(*this);
}
bool FIggxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator < 2 &&
partons[emission]->id() == ParticleID::g &&
partons[emitter]->id() == ParticleID::g &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FIggxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res =
1./((1.-z)+(1.-x)) + 1./(z+(1.-x)) - 2.+z*(1.-z)
+ (1.-x)*(1.+x*z*(1.-z))
;
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool FIggxDipole::aboveAlpha() const{return alpha()<1.-subtractionParameters()[0];}
-
-
double FIggxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
if ( alpha() < (1.-x) )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double diag =
1./(1.-z+1.-x) + 1./(z+1.-x) - 2.
//+ (1.-x)*(1.+x*z*(1.-z))
;
Lorentz5Momentum pc =
z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] -
(1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()];
SpinCorrelationTensor corr(-diag,pc,prop/(2.*x));
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FIggxDipole::persistentOutput(PersistentOStream &) const {
}
void FIggxDipole::persistentInput(PersistentIStream &, int) {
}
void FIggxDipole::Init() {
static ClassDocumentation<FIggxDipole> documentation
("FIggxDipole");
DipoleRepository::registerDipole<0,FIggxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics>
("FIggxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics");
}
// *** 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<FIggxDipole,SubtractionDipole>
describeHerwigFIggxDipole("Herwig::FIggxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FIggxDipole.h b/MatrixElement/Matchbox/Dipoles/FIggxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FIggxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FIggxDipole.h
@@ -1,172 +1,166 @@
// -*- C++ -*-
//
// FIggxDipole.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_FIggxDipole_H
#define HERWIG_FIggxDipole_H
//
// This is the declaration of the FIggxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FIggxDipole implements the D_{g,g}^a subtraction dipole.
*
*/
class FIggxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FIggxDipole();
/**
* The destructor.
*/
virtual ~FIggxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter > 1 && partons[emitter]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator < 2 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 4;}
/**
* Return true, if this dipole is symmetric with respect to emitter
* and emission.
*/
virtual bool isSymmetric() const { return true; }
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIggxDipole & operator=(const FIggxDipole &);
};
}
#endif /* HERWIG_FIggxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.cc
@@ -1,155 +1,151 @@
// -*- C++ -*-
//
// FIqgxDipole.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 FIqgxDipole class.
//
#include "FIqgxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h"
using namespace Herwig;
FIqgxDipole::FIqgxDipole()
: SubtractionDipole() {}
FIqgxDipole::~FIqgxDipole() {}
IBPtr FIqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FIqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool FIqgxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator < 2 &&
partons[emission]->id() == ParticleID::g &&
abs(partons[emitter]->id()) < 6 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FIqgxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= (
2./(1.-z+(1.-x)) -(1.+z)
+ (1.-x)*(1.+3.*x*z)
);
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool FIqgxDipole::aboveAlpha() const{return alpha()<1.-subtractionParameters()[0];}
-
-
double FIqgxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
if ( alpha() < (1.-x) )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= (
2./(1.-z+(1.-x)) - (1.+z)
//+ (1.-x)*(1.+3.*x*z)
);
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FIqgxDipole::persistentOutput(PersistentOStream &) const {
}
void FIqgxDipole::persistentInput(PersistentIStream &, int) {
}
void FIqgxDipole::Init() {
static ClassDocumentation<FIqgxDipole> documentation
("FIqgxDipole");
DipoleRepository::registerDipole<0,FIqgxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics>
("FIqgxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics");
}
// *** 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<FIqgxDipole,SubtractionDipole>
describeHerwigFIqgxDipole("Herwig::FIqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FIqgxDipole.h
@@ -1,166 +1,160 @@
// -*- C++ -*-
//
// FIqgxDipole.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_FIqgxDipole_H
#define HERWIG_FIqgxDipole_H
//
// This is the declaration of the FIqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FIqgxDipole implements the D_{q,g}^a subtraction dipole.
*
*/
class FIqgxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FIqgxDipole();
/**
* The destructor.
*/
virtual ~FIqgxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter > 1 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator < 2 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 3;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIqgxDipole & operator=(const FIqgxDipole &);
};
}
#endif /* HERWIG_FIqgxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.cc
@@ -1,150 +1,147 @@
// -*- C++ -*-
//
// FIqqxDipole.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 FIqqxDipole class.
//
#include "FIqqxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h"
using namespace Herwig;
FIqqxDipole::FIqqxDipole()
: SubtractionDipole() {}
FIqqxDipole::~FIqqxDipole() {}
IBPtr FIqqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FIqqxDipole::fullclone() const {
return new_ptr(*this);
}
bool FIqqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator < 2 &&
abs(partons[emission]->id()) < 6 &&
abs(partons[emitter]->id()) < 6 &&
partons[emission]->id() + partons[emitter]->id() == 0 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FIqqxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res = 1.-2.*z*(1.-z);
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool FIqqxDipole::aboveAlpha() const{return alpha()<1.-subtractionParameters()[0];}
-
double FIqqxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
if ( alpha() < (1.-x) )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
Lorentz5Momentum pc =
z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] -
(1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()];
SpinCorrelationTensor corr(-1.,pc,-prop/(4.*x));
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FIqqxDipole::persistentOutput(PersistentOStream &) const {
}
void FIqqxDipole::persistentInput(PersistentIStream &, int) {
}
void FIqqxDipole::Init() {
static ClassDocumentation<FIqqxDipole> documentation
("FIqqxDipole");
DipoleRepository::registerDipole<0,FIqqxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics>
("FIqqxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics");
}
// *** 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<FIqqxDipole,SubtractionDipole>
describeHerwigFIqqxDipole("Herwig::FIqqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FIqqxDipole.h
@@ -1,174 +1,168 @@
// -*- C++ -*-
//
// FIqqxDipole.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_FIqqxDipole_H
#define HERWIG_FIqqxDipole_H
//
// This is the declaration of the FIqqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FIqqxDipole implements the D_{q,qbar}^a subtraction dipole.
*
*/
class FIqqxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FIqqxDipole();
/**
* The destructor.
*/
virtual ~FIqqxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter > 1 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return
canHandleEmitter(partons,emitter) &&
partons[emitter]->id() + partons[emission]->id() == 0;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator < 2 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 1;}
/**
* Return true, if this dipole is symmetric with respect to emitter
* and emission.
*/
virtual bool isSymmetric() const { return true; }
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIqqxDipole & operator=(const FIqqxDipole &);
};
}
#endif /* HERWIG_FIqqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFggxDipole.cc
@@ -1,153 +1,150 @@
// -*- C++ -*-
//
// IFggxDipole.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 IFggxDipole class.
//
#include "IFggxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h"
using namespace Herwig;
IFggxDipole::IFggxDipole()
: SubtractionDipole() {}
IFggxDipole::~IFggxDipole() {}
IBPtr IFggxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFggxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFggxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator > 1 &&
partons[emission]->id() == ParticleID::g &&
partons[emitter]->id() == ParticleID::g &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IFggxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res = 1./(1.-x+u) + (1.-x)/x - 1. + x*(1.-x);
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool IFggxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IFggxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
if ( alpha() < u )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double diag = 1./(1.-x+u)-1.+x*(1.-x);
Lorentz5Momentum pc =
realEmissionME()->lastXComb().meMomenta()[realEmission()]/u -
realEmissionME()->lastXComb().meMomenta()[realSpectator()]/(1.-u);
Energy2 sc =
realEmissionME()->lastXComb().meMomenta()[realEmission()]*
realEmissionME()->lastXComb().meMomenta()[realSpectator()];
sc /= u*(1.-u)*(1.-x)/x;
SpinCorrelationTensor corr(-diag,pc,sc);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IFggxDipole::persistentOutput(PersistentOStream &) const {
}
void IFggxDipole::persistentInput(PersistentIStream &, int) {
}
void IFggxDipole::Init() {
static ClassDocumentation<IFggxDipole> documentation
("IFggxDipole");
DipoleRepository::registerDipole<0,IFggxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics>
("IFggxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics");
}
// *** 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<IFggxDipole,SubtractionDipole>
describeHerwigIFggxDipole("Herwig::IFggxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFggxDipole.h b/MatrixElement/Matchbox/Dipoles/IFggxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFggxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFggxDipole.h
@@ -1,166 +1,160 @@
// -*- C++ -*-
//
// IFggxDipole.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_IFggxDipole_H
#define HERWIG_IFggxDipole_H
//
// This is the declaration of the IFggxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFggxDipole implements the D^{g,g}_k subtraction dipole.
*
*/
class IFggxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFggxDipole();
/**
* The destructor.
*/
virtual ~IFggxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && partons[emitter]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator > 1 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 4;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFggxDipole & operator=(const IFggxDipole &);
};
}
#endif /* HERWIG_IFggxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.cc
@@ -1,143 +1,140 @@
// -*- C++ -*-
//
// IFgqxDipole.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 IFgqxDipole class.
//
#include "IFgqxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h"
using namespace Herwig;
IFgqxDipole::IFgqxDipole()
: SubtractionDipole() {}
IFgqxDipole::~IFgqxDipole() {}
IBPtr IFgqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFgqxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFgqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator > 1 &&
partons[emitter]->id() == ParticleID::g &&
abs(partons[emission]->id()) < 6 &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IFgqxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res =
8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= .5 * ( 1.-2.*x*(1.-x) );
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool IFgqxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IFgqxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
if ( alpha() < u )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res =
8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= .5 * ( 1.-2.*x*(1.-x) );
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IFgqxDipole::persistentOutput(PersistentOStream &) const {
}
void IFgqxDipole::persistentInput(PersistentIStream &, int) {
}
void IFgqxDipole::Init() {
static ClassDocumentation<IFgqxDipole> documentation
("IFgqxDipole");
DipoleRepository::registerDipole<0,IFgqxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics>
("IFgqxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics");
}
// *** 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<IFgqxDipole,SubtractionDipole>
describeHerwigIFgqxDipole("Herwig::IFgqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFgqxDipole.h
@@ -1,166 +1,160 @@
// -*- C++ -*-
//
// IFgqxDipole.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_IFgqxDipole_H
#define HERWIG_IFgqxDipole_H
//
// This is the declaration of the IFgqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFgqxDipole implements the D_k^{g,q} subtraction dipole.
*
*/
class IFgqxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFgqxDipole();
/**
* The destructor.
*/
virtual ~IFgqxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && partons[emitter]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && abs(partons[emission]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator > 1 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 2;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFgqxDipole & operator=(const IFgqxDipole &);
};
}
#endif /* HERWIG_IFgqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.cc
@@ -1,154 +1,151 @@
// -*- C++ -*-
//
// IFqgxDipole.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 IFqgxDipole class.
//
#include "IFqgxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h"
using namespace Herwig;
IFqgxDipole::IFqgxDipole()
: SubtractionDipole() {}
IFqgxDipole::~IFqgxDipole() {}
IBPtr IFqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFqgxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator > 1 &&
partons[emission]->id() == ParticleID::g &&
abs(partons[emitter]->id()) < 6 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IFqgxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= (
2./(1.-x+u) - (1.+x)
+ u*(1.+3.*x*(1.-u))
);
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool IFqgxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IFqgxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
if ( alpha() < u )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= (
2./(1.-x+u) - (1.+x)
//+ u*(1.+3.*x*(1.-u))
);
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IFqgxDipole::persistentOutput(PersistentOStream &) const {
}
void IFqgxDipole::persistentInput(PersistentIStream &, int) {
}
void IFqgxDipole::Init() {
static ClassDocumentation<IFqgxDipole> documentation
("IFqgxDipole");
DipoleRepository::registerDipole<0,IFqgxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics>
("IFqgxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics");
}
// *** 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<IFqgxDipole,SubtractionDipole>
describeHerwigIFqgxDipole("Herwig::IFqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFqgxDipole.h
@@ -1,166 +1,160 @@
// -*- C++ -*-
//
// IFqgxDipole.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_IFqgxDipole_H
#define HERWIG_IFqgxDipole_H
//
// This is the declaration of the IFqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFqgxDipole implements the D^{q,g}_k subtraction dipole
*
*/
class IFqgxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFqgxDipole();
/**
* The destructor.
*/
virtual ~IFqgxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator > 1 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 4;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFqgxDipole & operator=(const IFqgxDipole &);
};
}
#endif /* HERWIG_IFqgxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.cc
@@ -1,158 +1,155 @@
// -*- C++ -*-
//
// IFqqxDipole.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 IFqqxDipole class.
//
#include "IFqqxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h"
using namespace Herwig;
IFqqxDipole::IFqqxDipole()
: SubtractionDipole() {}
IFqqxDipole::~IFqqxDipole() {}
IBPtr IFqqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFqqxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFqqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator > 1 &&
abs(partons[emission]->id()) < 6 &&
abs(partons[emitter]->id()) < 6 &&
partons[emission]->id() - partons[emitter]->id() == 0 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IFqqxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res = x + 2.*(1.-x)/x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
res *= 8.*CF*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool IFqqxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IFqqxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
if ( alpha() < u )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
Lorentz5Momentum pc =
realEmissionME()->lastXComb().meMomenta()[realEmission()]/u -
realEmissionME()->lastXComb().meMomenta()[realSpectator()]/(1.-u);
Energy2 sc =
realEmissionME()->lastXComb().meMomenta()[realEmission()]*
realEmissionME()->lastXComb().meMomenta()[realSpectator()];
sc /= u*(1.-u)*(1.-x)/x;
SpinCorrelationTensor corr(-x,pc,sc/2.);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
res *= 8.*CF*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IFqqxDipole::persistentOutput(PersistentOStream &) const {
}
void IFqqxDipole::persistentInput(PersistentIStream &, int) {
}
void IFqqxDipole::Init() {
static ClassDocumentation<IFqqxDipole> documentation
("IFqqxDipole");
DipoleRepository::registerDipole<0,IFqqxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics>
("IFqqxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics");
}
// *** 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<IFqqxDipole,SubtractionDipole>
describeHerwigIFqqxDipole("Herwig::IFqqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFqqxDipole.h
@@ -1,168 +1,162 @@
// -*- C++ -*-
//
// IFqqxDipole.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_IFqqxDipole_H
#define HERWIG_IFqqxDipole_H
//
// This is the declaration of the IFqqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFqqxDipole implements the D^{q,qbar}_k subtraction dipole.
*
*/
class IFqqxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFqqxDipole();
/**
* The destructor.
*/
virtual ~IFqqxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return
canHandleEmitter(partons,emitter) &&
partons[emitter]->id() == partons[emission]->id();
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator > 1 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 2;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFqqxDipole & operator=(const IFqqxDipole &);
};
}
#endif /* HERWIG_IFqqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IIggxDipole.cc
@@ -1,152 +1,149 @@
// -*- C++ -*-
//
// IIggxDipole.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 IIggxDipole class.
//
#include "IIggxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h"
using namespace Herwig;
IIggxDipole::IIggxDipole()
: SubtractionDipole() {}
IIggxDipole::~IIggxDipole() {}
IBPtr IIggxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IIggxDipole::fullclone() const {
return new_ptr(*this);
}
bool IIggxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator < 2 &&
partons[emission]->id() == ParticleID::g &&
partons[emitter]->id() == ParticleID::g &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IIggxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res = x/(1.-x) + (1.-x)/x + x*(1.-x);
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool IIggxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IIggxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double v = subtractionParameters()[1];
if ( alpha() < v )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double diag = x/(1.-x)+x*(1.-x);
Lorentz5Momentum pc =
realEmissionME()->lastXComb().meMomenta()[realEmission()] -
v*realEmissionME()->lastXComb().meMomenta()[realSpectator()];
Energy2 sc =
realEmissionME()->lastXComb().meMomenta()[realEmission()]*
realEmissionME()->lastXComb().meMomenta()[realSpectator()];
sc /= (1.-x)/(x*v);
SpinCorrelationTensor corr(-diag,pc,sc);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IIggxDipole::persistentOutput(PersistentOStream &) const {
}
void IIggxDipole::persistentInput(PersistentIStream &, int) {
}
void IIggxDipole::Init() {
static ClassDocumentation<IIggxDipole> documentation
("IIggxDipole");
DipoleRepository::registerDipole<0,IIggxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics>
("IIggxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics");
}
// *** 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<IIggxDipole,SubtractionDipole>
describeHerwigIIggxDipole("Herwig::IIggxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IIggxDipole.h b/MatrixElement/Matchbox/Dipoles/IIggxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IIggxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IIggxDipole.h
@@ -1,165 +1,159 @@
// -*- C++ -*-
//
// IIggxDipole.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_IIggxDipole_H
#define HERWIG_IIggxDipole_H
//
// This is the declaration of the IIggxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IIggxDipole implements the D^{g,g;b} subtraction dipole.
*
*/
class IIggxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IIggxDipole();
/**
* The destructor.
*/
virtual ~IIggxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && partons[emitter]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator < 2 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 4;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIggxDipole & operator=(const IIggxDipole &);
};
}
#endif /* HERWIG_IIggxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.cc
@@ -1,143 +1,140 @@
// -*- C++ -*-
//
// IIgqxDipole.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 IIgqxDipole class.
//
#include "IIgqxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h"
using namespace Herwig;
IIgqxDipole::IIgqxDipole()
: SubtractionDipole() {}
IIgqxDipole::~IIgqxDipole() {}
IBPtr IIgqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IIgqxDipole::fullclone() const {
return new_ptr(*this);
}
bool IIgqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator < 2 &&
partons[emitter]->id() == ParticleID::g &&
abs(partons[emission]->id()) < 6 &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IIgqxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res =
8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= .5 * ( 1.-2.*x*(1.-x) );
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool IIgqxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IIgqxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double v = subtractionParameters()[1];
if ( alpha() < v )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res =
8.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= .5 * ( 1.-2.*x*(1.-x) );
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IIgqxDipole::persistentOutput(PersistentOStream &) const {
}
void IIgqxDipole::persistentInput(PersistentIStream &, int) {
}
void IIgqxDipole::Init() {
static ClassDocumentation<IIgqxDipole> documentation
("IIgqxDipole");
DipoleRepository::registerDipole<0,IIgqxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics>
("IIgqxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics");
}
// *** 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<IIgqxDipole,SubtractionDipole>
describeHerwigIIgqxDipole("Herwig::IIgqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IIgqxDipole.h
@@ -1,166 +1,160 @@
// -*- C++ -*-
//
// IIgqxDipole.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_IIgqxDipole_H
#define HERWIG_IIgqxDipole_H
//
// This is the declaration of the IIgqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IIgqxDipole implements the D^{g,q,k} subtraction dipole
*
*/
class IIgqxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IIgqxDipole();
/**
* The destructor.
*/
virtual ~IIgqxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && partons[emitter]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && abs(partons[emission]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator < 2 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
* N.B. not the perturbative result chosen to improve sampling
*/
virtual int samplingZ() const {return 2;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIgqxDipole & operator=(const IIgqxDipole &);
};
}
#endif /* HERWIG_IIgqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.cc
@@ -1,147 +1,144 @@
// -*- C++ -*-
//
// IIqgxDipole.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 IIqgxDipole class.
//
#include "IIqgxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h"
using namespace Herwig;
IIqgxDipole::IIqgxDipole()
: SubtractionDipole() {}
IIqgxDipole::~IIqgxDipole() {}
IBPtr IIqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IIqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool IIqgxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator < 2 &&
partons[emission]->id() == ParticleID::g &&
abs(partons[emitter]->id()) < 6 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IIqgxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= 2./(1.-x) - (1.+x);
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-bool IIqgxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IIqgxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double v = subtractionParameters()[1];
if ( alpha() < v )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= 2./(1.-x) - (1.+x);
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IIqgxDipole::persistentOutput(PersistentOStream &) const {
}
void IIqgxDipole::persistentInput(PersistentIStream &, int) {
}
void IIqgxDipole::Init() {
static ClassDocumentation<IIqgxDipole> documentation
("IIqgxDipole");
DipoleRepository::registerDipole<0,IIqgxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics>
("IIqgxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics");
}
// *** 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<IIqgxDipole,SubtractionDipole>
describeHerwigIIqgxDipole("Herwig::IIqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IIqgxDipole.h
@@ -1,166 +1,160 @@
// -*- C++ -*-
//
// IIqgxDipole.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_IIqgxDipole_H
#define HERWIG_IIqgxDipole_H
//
// This is the declaration of the IIqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IIqgxDipole implements the D^{q,g;b} subtraction dipole
*
*/
class IIqgxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IIqgxDipole();
/**
* The destructor.
*/
virtual ~IIqgxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return canHandleEmitter(partons,emitter) && partons[emission]->id() == ParticleID::g;
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator < 2 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 4;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIqgxDipole & operator=(const IIqgxDipole &);
};
}
#endif /* HERWIG_IIqgxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.cc
@@ -1,159 +1,155 @@
// -*- C++ -*-
//
// IIqqxDipole.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 IIqqxDipole class.
//
#include "IIqqxDipole.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IILightInvertedTildeKinematics.h"
using namespace Herwig;
IIqqxDipole::IIqqxDipole()
: SubtractionDipole() {}
IIqqxDipole::~IIqqxDipole() {}
IBPtr IIqqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IIqqxDipole::fullclone() const {
return new_ptr(*this);
}
bool IIqqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter < 2 && spectator < 2 &&
abs(partons[emission]->id()) < 6 &&
abs(partons[emitter]->id()) < 6 &&
partons[emission]->id() - partons[emitter]->id() == 0 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double IIqqxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
double res = (1.+sqr(1.-x))/x;
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
res *= 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
-
-
-bool IIqqxDipole::aboveAlpha() const{return alpha()<subtractionParameters()[1];}
-
double IIqqxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double x = subtractionParameters()[0];
double v = subtractionParameters()[1];
if ( alpha() < v )
return 0.0;
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]))*x;
Lorentz5Momentum pc =
realEmissionME()->lastXComb().meMomenta()[realEmission()] -
v*realEmissionME()->lastXComb().meMomenta()[realSpectator()];
Energy2 sc =
realEmissionME()->lastXComb().meMomenta()[realEmission()]*
realEmissionME()->lastXComb().meMomenta()[realSpectator()];
sc /= (1.-x)/(x*v);
SpinCorrelationTensor corr(-x,pc,sc/2.);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
res *= 8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void IIqqxDipole::persistentOutput(PersistentOStream &) const {
}
void IIqqxDipole::persistentInput(PersistentIStream &, int) {
}
void IIqqxDipole::Init() {
static ClassDocumentation<IIqqxDipole> documentation
("IIqqxDipole");
DipoleRepository::registerDipole<0,IIqqxDipole,IILightTildeKinematics,IILightInvertedTildeKinematics>
("IIqqxDipole","IILightTildeKinematics","IILightInvertedTildeKinematics");
}
// *** 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<IIqqxDipole,SubtractionDipole>
describeHerwigIIqqxDipole("Herwig::IIqqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IIqqxDipole.h
@@ -1,168 +1,162 @@
// -*- C++ -*-
//
// IIqqxDipole.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_IIqqxDipole_H
#define HERWIG_IIqqxDipole_H
//
// This is the declaration of the IIqqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IIqqxDipole implements the D^{q,qbar;b} subtraction dipole.
*
*/
class IIqqxDipole: public SubtractionDipole {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IIqqxDipole();
/**
* The destructor.
*/
virtual ~IIqqxDipole();
//@}
public:
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const {
return emitter < 2 && abs(partons[emitter]->id()) < 7;
}
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const {
return
canHandleEmitter(partons,emitter) &&
partons[emitter]->id() == partons[emission]->id();
}
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const {
return spectator < 2 && partons[spectator]->coloured();
}
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const;
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 2;}
/**
* Return the matrix element for the kinematical configuation
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
*/
virtual double me2() const;
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const;
-
- /*
- * True if phase space point is above the alpha cut for this dipole.
- */
-
- virtual bool aboveAlpha() 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;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIqqxDipole & operator=(const IIqqxDipole &);
};
}
#endif /* HERWIG_IIqqxDipole_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,1359 +1,1354 @@
// -*- 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 "Herwig/MatrixElement/Matchbox/Utility/DiagramDrawer.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();
theBornToRealDiagrams.clear();
theRealToBornDiagrams.clear();
}
void SubtractionDipole::setupBookkeeping(const map<Ptr<DiagramBase>::ptr,SubtractionDipole::MergeInfo>& mergeInfo,bool slim) {
theMergingMap.clear();
theSplittingMap.clear();
theUnderlyingBornDiagrams.clear();
theRealEmissionDiagrams.clear();
theBornToRealDiagrams.clear();
theRealToBornDiagrams.clear();
int xemitter = -1;
int xspectator = -1;
map<int,int> mergeLegs;
map<int,int> remapLegs;
map<int,int> realBornMap;
map<int,int> bornRealMap;
set<Ptr<DiagramBase>::cptr> usedDiagrams;
for ( map<Ptr<DiagramBase>::ptr,MergeInfo>::const_iterator mit = mergeInfo.begin();
mit != mergeInfo.end(); ++mit ) {
DiagramVector::const_iterator bd =
theUnderlyingBornME->diagrams().end();
// work out the most similar underlying Born diagram
map<int,int> xRemapLegs;
int nomapScore = 0;
for ( DiagramVector::const_iterator b =
theUnderlyingBornME->diagrams().begin();
b != theUnderlyingBornME->diagrams().end(); ++b ) {
map<int,int> theRemapLegs;
if ( mit->second.diagram->isSame(*b,theRemapLegs) &&
usedDiagrams.find(*b) == usedDiagrams.end() ) {
int theNomapScore = 0;
for ( map<int,int>::const_iterator m = theRemapLegs.begin();
m != theRemapLegs.end(); ++m )
if ( m->first == m->second )
theNomapScore += 1;
if ( theNomapScore >= nomapScore ) {
nomapScore = theNomapScore;
xRemapLegs = theRemapLegs;
bd = b;
}
}
}
// no underlying Born
if ( bd == theUnderlyingBornME->diagrams().end() )
continue;
// as we deal with one splitting only we now mark this diagram as used
// since we fixed the overall remapping of the process from the first
// occurence, see below. TODO: This confuses this code even more, and
// clearly calls for a cleanup. This is just grown historically and got
// messed up with experiencing different processes and setups.
usedDiagrams.insert(*bd);
if ( xemitter == -1 ) {
xemitter = mit->second.emitter;
mergeLegs = mit->second.mergeLegs;
remapLegs = xRemapLegs;
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);
theBornToRealDiagrams[*bd] = mit->first;
theRealToBornDiagrams[mit->first] = *bd;
}
if (slim) {
theIndexMap.clear();
theSplittingMap.clear();
theBornToRealDiagrams.clear();
theRealEmissionDiagrams.clear();
}
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;
}
tcDiagPtr SubtractionDipole::underlyingBornDiagram(tcDiagPtr realDiag) const {
map<tcDiagPtr,tcDiagPtr>::const_iterator it = theRealToBornDiagrams.find(realDiag);
assert(it != theRealToBornDiagrams.end());
return it->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;
}
tcDiagPtr SubtractionDipole::realEmissionDiagram(tcDiagPtr bornDiag) const {
map<tcDiagPtr,tcDiagPtr>::const_iterator it = theBornToRealDiagrams.find(bornDiag);
assert(it != theBornToRealDiagrams.end());
return it->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;
if( ! realEmissionME()->lastXCombPtr()->setIncomingPartons())
return false;
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() )
{cout<<"\nxx 1 xx"; return false;}
if( ! underlyingBornME()->lastXCombPtr()->setIncomingPartons() )
{cout<<"\nxx 2 xx"; return false;}
underlyingBornME()->setScale();
assert(lastXCombPtr() == underlyingBornME()->lastXCombPtr());
if( ! underlyingBornME()->lastXCombPtr()->setIncomingPartons() )
{cout<<"\nxx 3 xx"; return false;}
// 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();
-
-/*
- theLastRealR=kinematics->lastRealR();
- theLastBornR=kinematics->lastBornR();
-*/
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);
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);
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();
}
+bool SubtractionDipole::aboveAlpha() const{return theTildeKinematics->aboveAlpha();}
CrossSection SubtractionDipole::ps(Energy2 factorizationScale,Ptr<ColourBasis>::tptr largeNBasis) const {
double jac = jacobian();
assert( factorizationScale != ZERO );
assert (! splitting());
if(!theRealEmissionME->clustersafe(realEmitter(),realEmission(),realSpectator()).second || jac == 0.0 ) {
lastMECrossSection(ZERO);
lastME2(0.0);
return ZERO;
}
double pdfweight = 1.;
if ( havePDFWeight1() ) pdfweight *= realEmissionME()->pdf1(factorizationScale);
if ( havePDFWeight2() ) pdfweight *= realEmissionME()->pdf2(factorizationScale);
double ccme2 =underlyingBornME()->me2()*
underlyingBornME()->largeNColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),largeNBasis)
/underlyingBornME()->largeNME2(largeNBasis);
//double ccme2 =underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
return -sqr(hbarc) * jac * pdfweight * (me2Avg(ccme2)) / (2. * realEmissionME()->lastXComb().lastSHat());
}
pair<double,double> SubtractionDipole::dipandPs(Energy2 factorizationScale,Ptr<ColourBasis>::tptr largeNBasis) const {
double jac = jacobian();
assert( factorizationScale != ZERO );
assert (! splitting());
if(!theRealEmissionME->clustersafe(realEmitter(),realEmission(),realSpectator()).second || jac == 0.0 ) {
lastMECrossSection(ZERO);
lastME2(0.0);
return make_pair(0.,0.);
}
double pdfweight = 1.;
if ( havePDFWeight1() ) pdfweight *= realEmissionME()->pdf1(factorizationScale);
if ( havePDFWeight2() ) pdfweight *= realEmissionME()->pdf2(factorizationScale);
double ccme2 =underlyingBornME()->me2()
*
underlyingBornME()->largeNColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),largeNBasis)
/underlyingBornME()->largeNME2(largeNBasis);
// cout<<"\nln "<<ccme2;
//ccme2 =underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
// cout<<"\nan "<<ccme2;
double ps = me2Avg(ccme2);
double dip = me2();
double factor= sqr(hbarc) * jac * pdfweight / (2. * realEmissionME()->lastXComb().lastSHat())/nanobarn;
pair<double,double> res=make_pair(factor*dip,factor*ps);
return res ;
}
bool SubtractionDipole::clustersafe()const {
return (theRealEmissionME->clustersafe(realEmitter(),realEmission(),realSpectator()).second);
}
bool SubtractionDipole::clustersafe(){
return (theRealEmissionME->clustersafe(realEmitter(),realEmission(),realSpectator()).second);
}
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";
}
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,bool slim) {
if ( underlyingBornME() ) {
Ptr<MatchboxMEBase>::ptr myUnderlyingBornME = underlyingBornME()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myUnderlyingBornME->name();
if ( ! (generator()->preinitRegister(myUnderlyingBornME,pname.str()) ) )
throw Exception() << "SubtractionDipole::cloneDependencies(): Matrix element " << pname.str() << " already existing." << Exception::runerror;
myUnderlyingBornME->cloneDependencies(pname.str(),slim);
underlyingBornME(myUnderlyingBornME);
}
if ( realEmissionME()&& !slim ) {
Ptr<MatchboxMEBase>::ptr myRealEmissionME = realEmissionME()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myRealEmissionME->name();
if ( ! (generator()->preinitRegister(myRealEmissionME,pname.str()) ) )
throw Exception() << "SubtractionDipole::cloneDependencies(): Matrix element " << pname.str() << " already existing." << Exception::runerror;
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 Exception() << "SubtractionDipole::cloneDependencies(): Tilde kinematics " << pname.str() << " already existing." << Exception::runerror;
myTildeKinematics->dipole(this);
tildeKinematics(myTildeKinematics);
}
if ( invertedTildeKinematics()&& !slim ) {
Ptr<InvertedTildeKinematics>::ptr myInvertedTildeKinematics = invertedTildeKinematics()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myInvertedTildeKinematics->name();
if ( ! (generator()->preinitRegister(myInvertedTildeKinematics,pname.str()) ) )
throw Exception() << "SubtractionDipole::cloneDependencies(): Inverted tilde kinematics " << pname.str() << " already existing." << Exception::runerror;
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 Exception() << "SubtractionDipole::cloneDependencies(): Reweight " << pname.str() << " already existing." << Exception::runerror;
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
<< theBornToRealDiagrams << theRealToBornDiagrams
<< 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
>> theBornToRealDiagrams >> theRealToBornDiagrams
>> 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/Dipoles/SubtractionDipole.h b/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h
--- a/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h
@@ -1,1277 +1,1261 @@
// -*- C++ -*-
//
// SubtractionDipole.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_SubtractionDipole_H
#define HERWIG_SubtractionDipole_H
//
// This is the declaration of the SubtractionDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh"
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.fh"
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.fh"
#include "ThePEG/MatrixElement/MEBase.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief SubtractionDipole represents a dipole subtraction
* term in the formalism of Catani and Seymour.
*
*/
class SubtractionDipole:
public MEBase, public LastMatchboxXCombInfo {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
SubtractionDipole();
/**
* The destructor.
*/
virtual ~SubtractionDipole();
//@}
public:
/**
* Return the factory which produced this matrix element
*/
Ptr<MatchboxFactory>::tptr factory() const;
/**
* Set the factory which produced this matrix element
*/
void factory(Ptr<MatchboxFactory>::tptr f);
/** @name Subprocess and diagram information. */
//@{
/**
* A helpre struct to communicate diagram merging and remapping
* information
*/
struct MergeInfo {
/**
* The merged emitter
*/
int emitter;
/**
* The Born diagram
*/
Ptr<Tree2toNDiagram>::ptr diagram;
/**
* The merging map
*/
map<int,int> mergeLegs;
};
/**
* Return true, if this dipole can possibly handle the indicated
* emitter.
*/
virtual bool canHandleEmitter(const cPDVector& partons, int emitter) const = 0;
/**
* Return true, if this dipole can possibly handle the indicated
* splitting.
*/
virtual bool canHandleSplitting(const cPDVector& partons, int emitter, int emission) const = 0;
/**
* Return true, if this dipole can possibly handle the indicated
* spectator.
*/
virtual bool canHandleSpectator(const cPDVector& partons, int spectator) const = 0;
/**
* Return true, if this dipole applies to the selected
* configuration.
*/
virtual bool canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const = 0;
/**
* Return true, if this dipole is symmetric with respect to emitter
* and emission.
*/
virtual bool isSymmetric() const { return false; }
/**
* If this is a dependent matrix element in a ME group, return true,
* if it applies to the process set in lastXComb()
*/
virtual bool apply() const { return theApply; }
/**
* Clear the bookkeeping
*/
void clearBookkeeping();
/**
* Setup bookkeeping maps.
*/
void setupBookkeeping(const map<Ptr<DiagramBase>::ptr,MergeInfo>& mergeInfo,bool slim);
/**
* Get bookkeeping information for the given
* real emission diagram
*/
void subtractionBookkeeping();
/**
* Determine bookkeeping information for
* the underlying Born process supplied through
* the lastHeadXComb() object.
*/
void splittingBookkeeping();
/**
* For the given event generation setup return a xcomb object
* appropriate to this matrix element.
*/
virtual StdXCombPtr makeXComb(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts,
const DiagramVector & newDiagrams, bool mir,
const PartonPairVec& allPBins,
tStdXCombPtr newHead = tStdXCombPtr(),
tMEPtr newME = tMEPtr());
/**
* For the given event generation setup return a dependent xcomb object
* appropriate to this matrix element.
*/
virtual StdXCombPtr makeXComb(tStdXCombPtr newHead,
const PBPair & newPartonBins,
const DiagramVector & newDiagrams,
tMEPtr newME = tMEPtr());
/**
* Create a dependent xcomb object for the underlying
* Born process, given a XComb driving the real emission
*/
StdXCombPtr makeBornXComb(tStdXCombPtr realXC);
/**
* Create dependent xcomb objects for the real emission process,
* given a XComb driving the underlying Born
*/
vector<StdXCombPtr> makeRealXCombs(tStdXCombPtr bornXC);
/**
* Return true, if bookkeeping did not find a non-trivial setup.
*/
bool empty() const { return theSplittingMap.empty()&&theMergingMap.empty(); }
/**
* Return the emitter as referred to by the real emission
* matrix element.
*/
int realEmitter() const { return theRealEmitter; }
/**
* Set the emitter as referred to by the real emission
* matrix element.
*/
void realEmitter(int id) { theRealEmitter = id; }
/**
* Return the emission as referred to by the real emission
* matrix element.
*/
int realEmission() const { return theRealEmission; }
/**
* Set the emission as referred to by the real emission
* matrix element.
*/
void realEmission(int id) { theRealEmission = id; }
/**
* Return the spectator as referred to by the real emission
* matrix element.
*/
int realSpectator() const { return theRealSpectator; }
/**
* Set the spectator as referred to by the real emission
* matrix element.
*/
void realSpectator(int id) { theRealSpectator = id; }
/**
* Return the emitter as referred to by the underlying
* Born process.
*/
int bornEmitter() const { return theBornEmitter; }
/**
* Set the emitter as referred to by the underlying
* Born process.
*/
void bornEmitter(int id) { theBornEmitter = id; }
/**
* Return the spectator as referred to by the underlying
* Born process.
*/
int bornSpectator() const { return theBornSpectator; }
/**
* Set the spectator as referred to by the underlying
* Born process.
*/
void bornSpectator(int id) { theBornSpectator = id; }
/**
* Define the real emission key type
*/
typedef pair<pair<cPDVector,int>,pair<int,int> > RealEmissionKey;
/**
* Create a real emission key
*/
static RealEmissionKey realEmissionKey(const cPDVector& proc,
int em, int emm, int sp) {
return make_pair(make_pair(proc,emm),make_pair(em,sp));
}
/**
* Return the diagram of a real emission key
*/
static const cPDVector& process(const RealEmissionKey& key) {
return key.first.first;
}
/**
* Return the emission id of a real emission key
*/
static int emission(const RealEmissionKey& key) {
return key.first.second;
}
/**
* Return the emitter id of a real emission key
*/
static int emitter(const RealEmissionKey& key) {
return key.second.first;
}
/**
* Return the spectator id of a real emission key
*/
static int spectator(const RealEmissionKey& key) {
return key.second.second;
}
/**
* Define the underlying Born key type
*/
typedef pair<cPDVector,pair<int,int> > UnderlyingBornKey;
/**
* Create a underlying Born key
*/
static UnderlyingBornKey underlyingBornKey(const cPDVector& proc,
int em, int sp) {
return make_pair(proc,make_pair(em,sp));
}
/**
* Return the diagram of a underlying Born key
*/
static const cPDVector& process(const UnderlyingBornKey& key) {
return key.first;
}
/**
* Return the emitter id of a underlying Born key
*/
static int emitter(const UnderlyingBornKey& key) {
return key.second.first;
}
/**
* Return the spectator id of a underlying Born key
*/
static int spectator(const UnderlyingBornKey& key) {
return key.second.second;
}
/**
* Define real emission key and index dictionary
* for partons not involved in the given dipole.
*/
typedef pair<RealEmissionKey,map<int,int> > RealEmissionInfo;
/**
* Define underlying Born key and index dictionary
* for partons not involved in the given dipole.
*/
typedef pair<UnderlyingBornKey,map<int,int> > UnderlyingBornInfo;
/**
* Return the merging map
*/
const map<RealEmissionKey,UnderlyingBornInfo>& mergingMap() const { return theMergingMap; }
/**
* Return the splitting map
*/
const multimap<UnderlyingBornKey,RealEmissionInfo>& splittingMap() const { return theSplittingMap; }
/**
* Return the underlying Born diagrams to be considered
* for the given real emission process.
*/
const DiagramVector& underlyingBornDiagrams(const cPDVector& real) const;
/**
* Find the underlying Born diagram for the given real emission diagram
*/
tcDiagPtr underlyingBornDiagram(tcDiagPtr realDiag) const;
/**
* Return the real emission diagrams to be considered
* for the given Born process.
*/
const DiagramVector& realEmissionDiagrams(const cPDVector& born) const;
/**
* Find the real emission diagram for the given underlying Born diagram
*/
tcDiagPtr realEmissionDiagram(tcDiagPtr bornDiag) const;
/**
* Add all possible diagrams with the add() function.
*/
virtual void getDiagrams() const;
/**
* Return true, if this matrix element does not want to
* make use of mirroring processes; in this case all
* possible partonic subprocesses with a fixed assignment
* of incoming particles need to be provided through the diagrams
* added with the add(...) method.
*/
virtual bool noMirror () const { return true; }
/**
* With the information previously supplied with the
* setKinematics(...) method, a derived class may optionally
* override this method to weight the given diagrams with their
* (although certainly not physical) relative probabilities.
*/
virtual Selector<DiagramIndex> diagrams(const DiagramVector & dv) const;
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
*/
virtual Selector<const ColourLines *>
colourGeometries(tcDiagPtr diag) const;
/**
* Select a ColpurLines geometry. The default version returns a
* colour geometry selected among the ones returned from
* colourGeometries(tcDiagPtr).
*/
virtual const ColourLines &
selectColourGeometry(tcDiagPtr diag) const;
/**
* Return the order in \f$\alpha_S\f$ in which this matrix element
* is given.
*/
virtual unsigned int orderInAlphaS() const { return realEmissionME()->orderInAlphaS(); }
/**
* Return the order in \f$\alpha_{EM}\f$ in which this matrix
* element is given. Returns 0.
*/
virtual unsigned int orderInAlphaEW() const { return underlyingBornME()->orderInAlphaEW(); }
//@}
/** @name Phasespace generation */
//@{
/**
* Set the XComb object to be used in the next call to
* generateKinematics() and dSigHatDR().
*/
virtual void setXComb(tStdXCombPtr xc);
/**
* Set the typed and momenta of the incoming and outgoing partons to
* be used in subsequent calls to me() and colourGeometries()
* according to the associated XComb object. If the function is
* overridden in a sub class the new function must call the base
* class one first.
*/
virtual void setKinematics();
/**
* Generate internal degrees of freedom given nDim() uniform random
* numbers in the interval ]0,1[. To help the phase space generator,
* the 'dSigHatDR' should be a smooth function of these numbers,
* although this is not strictly necessary. The return value should
* be true of the generation succeeded. If so the generated momenta
* should be stored in the meMomenta() vector.
*/
virtual bool generateKinematics(const double * r);
/**
* The number of internal degreed of freedom used in the matrix
* element. This default version returns 0;
*/
virtual int nDim() const;
/**
* Return true, if this matrix element expects
* the incoming partons in their center-of-mass system
*/
virtual bool wantCMS () const { return realEmissionME()->wantCMS(); }
/**
* Clear the information previously provided by a call to
* setKinematics(...).
*/
virtual void clearKinematics();
/**
* If this is a dependent matrix element in a ME group, return true,
* if cuts should be ignored.
*/
virtual bool ignoreCuts() const { return theIgnoreCuts; }
/**
* Indicate that cuts should be ignored
*/
void doIgnoreCuts(bool is = true) { theIgnoreCuts = is; }
//@}
/** @name Tilde kinematics */
//@{
/**
* Return the TildeKinematics object used
*/
Ptr<TildeKinematics>::tcptr tildeKinematics() const { return theTildeKinematics; }
/**
* Set the TildeKinematics object used
*/
void tildeKinematics(Ptr<TildeKinematics>::tptr);
/**
* Generate the tilde kinematics from real emission
* kinematics accessible through the XComb's
* head object and store it in meMomenta(). This default
* implemenation uses the tildeKinematics() object.
*/
virtual bool generateTildeKinematics();
/**
* Return the InvertedTildeKinematics object used
*/
Ptr<InvertedTildeKinematics>::tcptr invertedTildeKinematics() const { return theInvertedTildeKinematics; }
/**
* Set the InvertedTildeKinematics object used
*/
void invertedTildeKinematics(Ptr<InvertedTildeKinematics>::tptr);
/**
* Return the number of additional random numbers
* needed to generate real emission kinematics off
* the tilde kinematics previously supplied through
* the XComb object. This default implementation
* returns invertedTildeKinematics()->nDimRadiation()
*/
virtual int nDimRadiation() const;
/**
* Generate the real emission kinematics
* off the Born kinematics accessible through the XComb's
* head object and store it in meMomenta(); store
* the single particle phasespace in units of lastHeadXComb()->lastSHat()
* in jacobian(). This default
* implemenation uses the invertedTildeKinematics() object
*/
virtual bool generateRadiationKinematics(const double *);
/**
* Set a pt cut when splitting
*/
void ptCut(Energy cut);
/**
* Return the relevant dipole scale
*/
Energy lastDipoleScale() const {
return splitting() ? theLastSplittingScale : theLastSubtractionScale;
}
/**
* Return the relevant pt
*/
Energy lastPt() const {
return splitting() ? theLastSplittingPt : theLastSubtractionPt;
}
/**
* Return the relevant momentum fractions
*/
double lastZ() const {
return splitting() ? theLastSplittingZ : theLastSubtractionZ;
}
-
-/*
-
- double lastRealR() const{
- return theLastRealR;
- }
-
- double lastBornR() const{
- return theLastBornR;
- }
-
-*/
/**
* Return true, if this dipole acts in splitting mode.
*/
bool splitting() const { return theSplitting; }
/**
* Switch on splitting mode for this dipole.
*/
void doSplitting() { theSplitting = true; }
/**
* Switch off splitting mode for this dipole.
*/
void doSubtraction() { theSplitting = false; }
/**
* Return the subtraction parameters.
*/
const vector<double>& subtractionParameters() const { return theSubtractionParameters; }
/**
* Access the subtraction parameters.
*/
vector<double>& subtractionParameters() { return theSubtractionParameters; }
/**
* Return the shower hard scale encountered
*/
Energy showerHardScale() const { return theShowerHardScale; }
/**
* Set the shower hard scale encountered
*/
void showerHardScale(Energy s) { theShowerHardScale = s; }
/**
* Return the shower evolution scale encountered
*/
Energy showerScale() const { return theShowerScale; }
/**
* Set the shower evolution scale encountered
*/
void showerScale(Energy s) { theShowerScale = s; }
/**
* Return the shower splitting variables encountered
*/
const vector<double>& showerParameters() const { return theShowerParameters; }
/**
* Access the shower splitting variables encountered
*/
vector<double>& showerParameters() { return theShowerParameters; }
/**
* Return true, if this configuration is in the shower phase space
*/
bool isInShowerPhasespace() const { return theIsInShowerPhasespace; }
/**
* Indicate whether this configuration is in the shower phase space
*/
void isInShowerPhasespace(bool yes) { theIsInShowerPhasespace = yes; }
/**
* Return true, if this configuration is above the shower infrared cutoff
*/
bool isAboveCutoff() const { return theIsAboveCutoff; }
/**
* Indicate whether this configuration is above the shower infrared cutoff
*/
void isAboveCutoff(bool yes) { theIsAboveCutoff = yes; }
//@}
/** @name Scale choices, couplings and PDFs */
//@{
/**
* Return true, if scales should be calculated from real emission kinematics
*/
bool realEmissionScales() const { return theRealEmissionScales; }
/**
* Switch on or off that scales should be calculated from real emission kinematics
*/
void doRealEmissionScales(bool on = true) { theRealEmissionScales = on; }
/**
* Return the scale associated with the phase space point provided
* by the last call to setKinematics().
*/
virtual Energy2 scale() const {
return realEmissionScales() ?
realEmissionME()->scale() :
underlyingBornME()->scale();
}
/**
* Return the value of \f$\alpha_S\f$ associated with the phase
* space point provided by the last call to setKinematics(). This
* versions returns SM().alphaS(scale()).
*/
virtual double alphaS() const {
return realEmissionScales() ?
realEmissionME()->alphaS() :
underlyingBornME()->alphaS();
}
/**
* Return the value of \f$\alpha_EM\f$ associated with the phase
* space point provided by the last call to setKinematics(). This
* versions returns SM().alphaEM(scale()).
*/
virtual double alphaEM() const {
return realEmissionScales() ?
realEmissionME()->alphaEM() :
underlyingBornME()->alphaEM();
}
/**
* Return true, if this matrix element provides the PDF
* weight for the first incoming parton itself.
*/
virtual bool havePDFWeight1() const { return realEmissionME()->havePDFWeight1(); }
/**
* Return true, if this matrix element provides the PDF
* weight for the second incoming parton itself.
*/
virtual bool havePDFWeight2() const { return realEmissionME()->havePDFWeight2(); }
/**
* How to sample the z-distribution.
* FlatZ = 1
* OneOverZ = 2
* OneOverOneMinusZ = 3
* OneOverZOneMinusZ = 4
*/
virtual int samplingZ() const {return 4;}
//@}
/** @name Matrix elements and evaluation */
//@{
/**
* Return the real emission matrix element
*/
Ptr<MatchboxMEBase>::tcptr realEmissionME() const {
return theRealEmissionME;
}
/**
* Return the real emission matrix element
*/
Ptr<MatchboxMEBase>::tptr realEmissionME() {
return theRealEmissionME;
}
/**
* Set the real emission matrix element
*/
void realEmissionME(Ptr<MatchboxMEBase>::tptr me) { theRealEmissionME = me; }
/**
* Return the underlying Born matrix element
*/
Ptr<MatchboxMEBase>::tcptr underlyingBornME() const {
return theUnderlyingBornME;
}
/**
* Return the underlying Born matrix element
*/
Ptr<MatchboxMEBase>::tptr underlyingBornME() {
return theUnderlyingBornME;
}
/**
* Set the underlying Born matrix element
*/
void underlyingBornME(Ptr<MatchboxMEBase>::tptr me) { theUnderlyingBornME = me; }
/**
* Set the dipoles which have been found along with this dipole
*/
void partnerDipoles(const vector<Ptr<SubtractionDipole>::tptr>& p) {
thePartners = p;
}
/**
* Return the dipoles which have been found along with this dipole
*/
const vector<Ptr<SubtractionDipole>::tptr>& partnerDipoles() const {
return thePartners;
}
/**
* Return the matrix element averaged over spin correlations.
*/
virtual double me2Avg(double ccme2) const = 0;
/**
* Return the matrix element squared differential in the variables
* given by the last call to generateKinematics().
*/
virtual CrossSection dSigHatDR(Energy2 factorizationScale) const;
/**
* Return the matrix element squared differential in the variables
* given by the last call to generateKinematics().
*/
virtual CrossSection dSigHatDR() const { return dSigHatDR(ZERO); }
/**
* Return true if this dipole is safe for clustering
**/
bool clustersafe() const;
bool clustersafe();
/**
* Calculate the parton shower approximation for this dipole.
**/
CrossSection ps(Energy2 factorizationScale,Ptr<ColourBasis>::tptr largeNBasis) const;
/**
* Calculate the dipole dSigDR and the parton shower approximation for this dipole.
**/
pair<double,double> dipandPs(Energy2 factorizationScale,Ptr<ColourBasis>::tptr largeNBasis) const;
//@}
/** @name Methods relevant to matching */
//@{
/**
* Set the shower approximation.
*/
void showerApproximation(Ptr<ShowerApproximation>::tptr app) {
theShowerApproximation = app;
}
/**
* Return the shower approximation.
*/
Ptr<ShowerApproximation>::tptr showerApproximation() const { return theShowerApproximation; }
/**
* Indicate that the shower real emission contribution should be subtracted.
*/
void doRealShowerSubtraction() { theRealShowerSubtraction = true; }
/**
* Return true, if the shower real emission contribution should be subtracted.
*/
bool realShowerSubtraction() const { return theRealShowerSubtraction; }
/**
* Indicate that the shower virtual contribution should be subtracted.
*/
void doVirtualShowerSubtraction() { theVirtualShowerSubtraction = true; }
/**
* Return true, if the shower virtual contribution should be subtracted.
*/
bool virtualShowerSubtraction() const { return theVirtualShowerSubtraction; }
/**
* Indicate that the loopsim matched virtual contribution should be subtracted.
*/
void doLoopSimSubtraction() { theLoopSimSubtraction = true; }
/**
* Return true, if the loopsim matched virtual contribution should be subtracted.
*/
bool loopSimSubtraction() const { return theLoopSimSubtraction; }
//@}
/** @name Caching and diagnostic information */
//@{
/**
* Inform this matrix element that a new phase space
* point is about to be generated, so all caches should
* be flushed.
*/
virtual void flushCaches();
/**
* Indicate that the subtraction is being tested.
*/
void doTestSubtraction() { theSubtractionTest = true; }
/**
* Return true, if the subtraction is being tested.
*/
bool testSubtraction() const { return theSubtractionTest; }
/**
* Return true, if verbose
*/
bool verbose() const { return realEmissionME()->verbose() || underlyingBornME()->verbose(); }
/**
* Dump the setup to an ostream
*/
void print(ostream&) const;
/**
* Print debug information on the last event
*/
virtual void printLastEvent(ostream&) const;
/**
* Write out diagnostic information for
* generateTildeKinematics
*/
void logGenerateTildeKinematics() const;
/**
* Write out diagnostic information for
* generateRadiationKinematics
*/
void logGenerateRadiationKinematics(const double * r) const;
/**
* Write out diagnostic information for
* me2 evaluation
*/
void logME2() const;
/**
* Write out diagnostic information
* for dsigdr evaluation
*/
void logDSigHatDR(double effectiveJac) const;
//@}
/** @name Reweight objects */
//@{
/**
* Insert a reweight object
*/
void addReweight(Ptr<MatchboxReweightBase>::ptr rw) { theReweights.push_back(rw); }
/**
* Return the reweight objects
*/
const vector<Ptr<MatchboxReweightBase>::ptr>& reweights() const { return theReweights; }
/**
* Access the reweight objects
*/
vector<Ptr<MatchboxReweightBase>::ptr>& reweights() { return theReweights; }
//@}
/** @name Methods used to setup SubtractionDipole objects */
//@{
/**
* Clone this dipole.
*/
Ptr<SubtractionDipole>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<SubtractionDipole>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
void cloneDependencies(const std::string& prefix = ""){cloneDependencies(prefix,false);};
void cloneDependencies(const std::string& prefix , bool slim);
//@}
/** @name Methods required to setup the event record */
//@{
/**
* construct the spin information for the interaction
*/
virtual void constructVertex(tSubProPtr sub);
/**
* construct the spin information for the interaction
*/
virtual void constructVertex(tSubProPtr sub, const ColourLines* cl);
/**
* Comlete a SubProcess object using the internal degrees of freedom
* generated in the last generateKinematics() (and possible other
* degrees of freedom which was intergated over in dSigHatDR(). This
* default version does nothing. Will be made purely virtual in the
* future.
*/
virtual void generateSubCollision(SubProcess & sub);
/**
* Alpha parameter as in Nagy
* (http://arxiv.org/pdf/hep-ph/0307268v2.pdf) to restrict dipole
* phase space
*/
double alpha() const;
/*
* True if phase space point is above the alpha cut for this dipole.
*/
- virtual bool aboveAlpha() const{return true;}
+ bool aboveAlpha() 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 Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
//@}
private:
/**
* The factory which produced this matrix element
*/
Ptr<MatchboxFactory>::tptr theFactory;
/**
* Wether or not this dipole acts in splitting mode.
*/
bool theSplitting;
/**
* True, if should apply to process in the xcomb.
*/
bool theApply;
/**
* True, if the subtraction is being tested.
*/
bool theSubtractionTest;
/**
* True if cuts should be ignored
*/
bool theIgnoreCuts;
/**
* The real emission matrix element to be considered
*/
Ptr<MatchboxMEBase>::ptr theRealEmissionME;
/**
* The underlying Born matrix element
*/
Ptr<MatchboxMEBase>::ptr theUnderlyingBornME;
/**
* The dipoles which have been found along with this dipole
*/
vector<Ptr<SubtractionDipole>::tptr> thePartners;
/**
* The TildeKinematics to be used.
*/
Ptr<TildeKinematics>::ptr theTildeKinematics;
/**
* The InvertedTildeKinematics to be used.
*/
Ptr<InvertedTildeKinematics>::ptr theInvertedTildeKinematics;
/**
* A vector of reweight objects the sum of which
* should be applied to reweight this dipole
*/
vector<Ptr<MatchboxReweightBase>::ptr> theReweights;
/**
* The emitter as referred to by the real emission
* matrix element.
*/
int theRealEmitter;
/**
* The emission as referred to by the real emission
* matrix element.
*/
int theRealEmission;
/**
* The spectator as referred to by the real emission
* matrix element.
*/
int theRealSpectator;
/**
* The subtraction parameters
*/
vector<double> theSubtractionParameters;
/**
* Map real emission diagrams to underlying Born diagrams
* and tilde emitter/spectator.
*/
map<RealEmissionKey,UnderlyingBornInfo> theMergingMap;
/**
* Map underlying Born diagrams and tilde emitter/spectator
* to real emission diagram containing the splitting.
*/
multimap<UnderlyingBornKey,RealEmissionInfo> theSplittingMap;
/**
* Map underlying Born diagrams to emitter/spectator pairs
*/
map<cPDVector,pair<int,int> > theIndexMap;
/**
* Map real emission processes to Born diagrams
*/
map<cPDVector,DiagramVector> theUnderlyingBornDiagrams;
/**
* Map Born processes to real emission diagrams
*/
map<cPDVector,DiagramVector> theRealEmissionDiagrams;
/**
* Map underlying Born diagrams to real emission diagrams.
*/
map<tcDiagPtr,tcDiagPtr> theBornToRealDiagrams;
/**
* Map real emission diagrams to underlying Born diagrams.
*/
map<tcDiagPtr,tcDiagPtr> theRealToBornDiagrams;
/**
* The last real emission key encountered
*/
RealEmissionKey lastRealEmissionKey;
/**
* The last underlying Born key encountered
*/
UnderlyingBornKey lastUnderlyingBornKey;
/**
* The last real emission info encountered
*/
multimap<UnderlyingBornKey,RealEmissionInfo>::const_iterator lastRealEmissionInfo;
/**
* The emitter as referred to by the underlying Born
* matrix element.
*/
int theBornEmitter;
/**
* The spectator as referred to by the underlying Born
* matrix element.
*/
int theBornSpectator;
/**
* The last scale as generated from the tilde mapping
*/
Energy theLastSubtractionScale;
/**
* The last scale as generated from the splitting mapping
*/
Energy theLastSplittingScale;
/**
* The last pt as generated from the tilde mapping
*/
Energy theLastSubtractionPt;
/**
* The last pt as generated from the splitting mapping
*/
Energy theLastSplittingPt;
/**
* The last z as generated from the tilde mapping
*/
double theLastSubtractionZ;
/**
* The last z as generated from the splitting mapping
*/
double theLastSplittingZ;
-
-/*
- double theLastRealR;
- double theLastBornR;
-*/
+
/**
* The shower approximation.
*/
Ptr<ShowerApproximation>::ptr theShowerApproximation;
/**
* True, if the shower real emission contribution should be subtracted.
*/
bool theRealShowerSubtraction;
/**
* True, if the shower virtual contribution should be subtracted.
*/
bool theVirtualShowerSubtraction;
/**
* True, if the loopsim matched virtual contribution should be subtracted.
*/
bool theLoopSimSubtraction;
/**
* True, if scales should be calculated from real emission kinematics
*/
bool theRealEmissionScales;
/**
* Return the shower hard scale encountered
*/
Energy theShowerHardScale;
/**
* The shower evolution scale encountered
*/
Energy theShowerScale;
/**
* The shower splitting variables encountered
*/
vector<double> theShowerParameters;
/**
* True, if this configuration is in the shower phase space
*/
bool theIsInShowerPhasespace;
/**
* True, if this configuration is above the shower infrared cutoff
*/
bool theIsAboveCutoff;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
SubtractionDipole & operator=(const SubtractionDipole &);
};
}
#endif /* HERWIG_SubtractionDipole_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.h
@@ -1,128 +1,134 @@
// -*- C++ -*-
//
// FFLightTildeKinematics.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_FFLightTildeKinematics_H
#define HERWIG_FFLightTildeKinematics_H
//
// This is the declaration of the FFLightTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FFLightTildeKinematics implements the 'tilde' kinematics for
* a final-final subtraction dipole.
*
*/
class FFLightTildeKinematics: public TildeKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FFLightTildeKinematics();
/**
* The destructor.
*/
virtual ~FFLightTildeKinematics();
//@}
public:
/**
* Perform the mapping to the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the tilde
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap();
/**
* Return the pt associated to the last merged splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
+ /*
+ * True if phase space point is above the alpha cut for this dipole.
+ */
+
+ bool aboveAlpha() const {return dipole()->alpha()<subtractionParameters()[0];}
+
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 assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFLightTildeKinematics & operator=(const FFLightTildeKinematics &);
};
}
#endif /* HERWIG_FFLightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.h
@@ -1,128 +1,133 @@
// -*- C++ -*-
//
// FILightTildeKinematics.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_FILightTildeKinematics_H
#define HERWIG_FILightTildeKinematics_H
//
// This is the declaration of the FILightTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FILightTildeKinematics implements the 'tilde' kinematics for
* a final-initial subtraction dipole.
*
*/
class FILightTildeKinematics: public TildeKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
FILightTildeKinematics();
/**
* The destructor.
*/
virtual ~FILightTildeKinematics();
//@}
public:
/**
* Perform the mapping to the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the tilde
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap();
/**
* Return the pt associated to the last merged splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
+ /*
+ * True if phase space point is above the alpha cut for this dipole.
+ */
+ bool aboveAlpha() const {return dipole()->alpha()<1.-subtractionParameters()[0];}
+
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 assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FILightTildeKinematics & operator=(const FILightTildeKinematics &);
};
}
#endif /* HERWIG_FILightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.h
@@ -1,128 +1,135 @@
// -*- C++ -*-
//
// IFLightTildeKinematics.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_IFLightTildeKinematics_H
#define HERWIG_IFLightTildeKinematics_H
//
// This is the declaration of the IFLightTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFLightTildeKinematics implements the 'tilde' kinematics for
* a initial-final subtraction dipole.
*
*/
class IFLightTildeKinematics: public TildeKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IFLightTildeKinematics();
/**
* The destructor.
*/
virtual ~IFLightTildeKinematics();
//@}
public:
/**
* Perform the mapping to the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the tilde
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap();
/**
* Return the pt associated to the last merged splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
+ /*
+ * True if phase space point is above the alpha cut for this dipole.
+ */
+
+ bool aboveAlpha() const {return dipole()->alpha()<subtractionParameters()[1];}
+
+
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 assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFLightTildeKinematics & operator=(const IFLightTildeKinematics &);
};
}
#endif /* HERWIG_IFLightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.h
@@ -1,152 +1,160 @@
// -*- C++ -*-
//
// IILightTildeKinematics.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_IILightTildeKinematics_H
#define HERWIG_IILightTildeKinematics_H
//
// This is the declaration of the IILightTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \breif IILightTildeKinematics implements the 'tilde' kinematics for
* a initial-initial subtraction dipole.
*
*/
class IILightTildeKinematics: public TildeKinematics {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
IILightTildeKinematics();
/**
* The destructor.
*/
virtual ~IILightTildeKinematics();
//@}
public:
/**
* Perform the mapping to the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the tilde
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap();
/**
* Return the pt associated to the last merged splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return true, if this TildeKinematics object needs to transform
* all other particles in the process except the emitter and spectator
*/
virtual bool doesTransform() const { return true; }
/**
* If this TildeKinematics object needs to transform all other particles
* in the process except the emitter and spectator, return the transformed
* momentum.
*/
virtual Lorentz5Momentum transform(const Lorentz5Momentum& p) const;
+
+ /*
+ * True if phase space point is above the alpha cut for this dipole.
+ */
+
+ bool aboveAlpha() const {return dipole()->alpha()<subtractionParameters()[1];}
+
+
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 K momentum used to transform the final state.
*/
Lorentz5Momentum K;
/**
* The Ktilde momentum used to transform the final state.
*/
Lorentz5Momentum Ktilde;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IILightTildeKinematics & operator=(const IILightTildeKinematics &);
};
}
#endif /* HERWIG_IILightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/TildeKinematics.h b/MatrixElement/Matchbox/Phasespace/TildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/TildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/TildeKinematics.h
@@ -1,354 +1,348 @@
// -*- C++ -*-
//
// TildeKinematics.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_TildeKinematics_H
#define HERWIG_TildeKinematics_H
//
// This is the declaration of the TildeKinematics class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief TildeKinematics is the base class for the 'tilde'
* kinematics being used for subtraction terms in the
* formalism of Catani and Seymour.
*
*/
class TildeKinematics: public HandlerBase {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
TildeKinematics();
/**
* The destructor.
*/
virtual ~TildeKinematics();
//@}
public:
/**
* Clone this object
*/
Ptr<TildeKinematics>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<TildeKinematics>::ptr>(clone());
}
/** @name Access to kinematic quantities. */
//@{
/**
* Return the momentum of the emitter in the real emission process
*/
const Lorentz5Momentum& realEmitterMomentum() const {
return theRealXComb->meMomenta()[theDipole->realEmitter()];
}
/**
* Return the momentum of the emission in the real emission process
*/
const Lorentz5Momentum& realEmissionMomentum() const {
return theRealXComb->meMomenta()[theDipole->realEmission()];
}
/**
* Return the momentum of the spectator in the real emission process
*/
const Lorentz5Momentum& realSpectatorMomentum() const {
return theRealXComb->meMomenta()[theDipole->realSpectator()];
}
/**
* Return the momentum of the emitter in the underlying Born process
*/
const Lorentz5Momentum& bornEmitterMomentum() const { return theBornEmitterMomentum; }
/**
* Return the momentum of the spectator in the underlying Born process
*/
const Lorentz5Momentum& bornSpectatorMomentum() const { return theBornSpectatorMomentum; }
/**
* Return the vector of dimensionless variables calculated
*/
const vector<double>& subtractionParameters() const { return theDipole->subtractionParameters(); }
/**
* Return true, if this TildeKinematics object needs to transform
* all other particles in the process except the emitter and spectator
*/
virtual bool doesTransform() const { return false; }
/**
* If this TildeKinematics object needs to transform all other particles
* in the process except the emitter and spectator, return the transformed
* momentum.
*/
virtual Lorentz5Momentum transform(const Lorentz5Momentum& p) const { return p; }
//@}
/**
* If this tilde kinematics is implementing a mapping different from
* the baseline dipole mapping, determine the relevant shower
* parameters and check for phase space boundaries. Note that real
* emission kinematics only are available at this stage.
*/
virtual void getShowerVariables() const {}
/**
* If this tilde kinematics is implementing a mapping different from
* the baseline dipole mapping, return the ratio of phase space
* factorization Jacobians for this and the nominal dipole
* mapping. This is used for matching subtractions.
*/
virtual double jacobianRatio() const { return 1.; }
public:
/** @name Access to process data. */
//@{
/**
* Prepare given a dipole, and XCombs describing the real emission
* and underlying Born processes, respectively.
*/
void prepare(tcStdXCombPtr newRealXComb,
tcStdXCombPtr newBornXComb) {
theRealXComb = newRealXComb; theBornXComb = newBornXComb;
}
/**
* Set the current dipole
*/
void dipole(Ptr<SubtractionDipole>::tptr dip) { theDipole = dip; }
/**
* Return the current dipole
*/
Ptr<SubtractionDipole>::tptr dipole() { return theDipole; }
/**
* Return the current dipole
*/
Ptr<SubtractionDipole>::tcptr dipole() const { return theDipole; }
/**
* Perform the mapping to the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the tilde
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap() = 0;
/**
* Return the pt associated to the last merged splitting.
*/
virtual Energy lastPt() const = 0;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const = 0;
/**
* Return the relevant dipole scale
*/
virtual Energy lastScale() const;
-/*
- double lastRealX() const{
- return theDipole->realEmitter()==0?(theBornXComb->lastX1()/theRealXComb->lastX1()):(theBornXComb->lastX2()/theRealXComb->lastX2());
+ virtual bool aboveAlpha() const {
+ cerr<<"only implemented for light kinematics";
+ assert(false);
+ return false;
}
-
- double lastRealX1() const{ return theRealXComb->lastX1(); }
- double lastRealX2() const{ return theRealXComb->lastX2(); }
- double lastBornX1() const{ return theBornXComb->lastX1(); }
- double lastBornX2() const{ return theBornXComb->lastX2(); }
-
-*/
/**
* Return the particle type of the emitter in the real emission process
*/
cPDPtr realEmitterData() const {
return
(theDipole && theRealXComb) ?
theRealXComb->mePartonData()[theDipole->realEmitter()] :
cPDPtr();
}
/**
* Return the particle type of the emission in the real emission process
*/
cPDPtr realEmissionData() const {
return
(theDipole && theRealXComb) ?
theRealXComb->mePartonData()[theDipole->realEmission()] :
cPDPtr();
}
/**
* Return the particle type of the spectator in the real emission process
*/
cPDPtr realSpectatorData() const {
return
(theDipole && theRealXComb) ?
theRealXComb->mePartonData()[theDipole->realSpectator()] :
cPDPtr();
}
/**
* Return the particle type of the emitter in the underlying Born process
*/
cPDPtr bornEmitterData() const {
return
(theDipole && theBornXComb) ?
theBornXComb->mePartonData()[theDipole->bornEmitter()] :
cPDPtr();
}
/**
* Return the particle type of the spectator in the underlying Born process
*/
cPDPtr bornSpectatorData() const {
return
(theDipole && theBornXComb) ?
theBornXComb->mePartonData()[theDipole->bornSpectator()] :
cPDPtr();
}
//@}
protected:
/**
* Access the momentum of the emitter in the underlying Born process
*/
Lorentz5Momentum& bornEmitterMomentum() { return theBornEmitterMomentum; }
/**
* Access the momentum of the spectator in the underlying Born process
*/
Lorentz5Momentum& bornSpectatorMomentum() { return theBornSpectatorMomentum; }
/**
* Access the vector of dimensionless variables calculated
*/
vector<double>& subtractionParameters() { return theDipole->subtractionParameters(); }
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();
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Rebind pointer to other Interfaced objects. Called in the setup phase
* after all objects used in an EventGenerator has been cloned so that
* the pointers will refer to the cloned objects afterwards.
* @param trans a TranslationMap relating the original objects to
* their respective clones.
* @throws RebindException if no cloned object was found for a given
* pointer.
*/
virtual void rebind(const TranslationMap & trans);
/**
* Return a vector of all pointers to Interfaced objects used in this
* object.
* @return a vector of pointers.
*/
virtual IVector getReferences();
//@}
private:
/**
* The last dipole this TildeKinematics has been selected for
*/
Ptr<SubtractionDipole>::tptr theDipole;
/**
* The XComb object describing the real emission process
*/
tcStdXCombPtr theRealXComb;
/**
* The XComb object describing the underlying Born process
*/
tcStdXCombPtr theBornXComb;
/**
* The momentum of the emitter in the underlying Born process
*/
Lorentz5Momentum theBornEmitterMomentum;
/**
* The momentum of the spectator in the underlying Born process
*/
Lorentz5Momentum theBornSpectatorMomentum;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
TildeKinematics & operator=(const TildeKinematics &);
};
}
#endif /* HERWIG_TildeKinematics_H */
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,1279 +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/Handlers/SamplerBase.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, size_t shift) {
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 + shift);
}
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 "
<< fname << " for storing colour basis information."
<< Exception::runerror;
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 "
<< fname << " for reading colour basis information."
<< Exception::runerror;
}
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()->runStorage();
readBasis();
}
void ColourBasis::dofinish() {
HandlerBase::dofinish();
writeBasis();
}
void ColourBasis::doinitrun() {
HandlerBase::doinitrun();
if ( theSearchPath.empty() && factory() )
theSearchPath = factory()->runStorage();
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/Shower/Dipole/DipoleShowerHandler.h b/Shower/Dipole/DipoleShowerHandler.h
--- a/Shower/Dipole/DipoleShowerHandler.h
+++ b/Shower/Dipole/DipoleShowerHandler.h
@@ -1,524 +1,525 @@
// -*- C++ -*-
//
// DipoleShowerHandler.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2007 The Herwig Collaboration
//
// Herwig is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleShowerHandler_H
#define HERWIG_DipoleShowerHandler_H
//
// This is the declaration of the DipoleShowerHandler class.
//
#include "Herwig/Shower/ShowerHandler.h"
#include "Herwig/Shower/Dipole/DipoleShowerHandler.fh"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingReweight.h"
#include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleEventRecord.h"
#include "Herwig/Shower/Dipole/Base/DipoleEvolutionOrdering.h"
#include "Herwig/Shower/Dipole/Base/DipoleEventReweight.h"
#include "Herwig/Shower/Dipole/Utility/ConstituentReshuffler.h"
#include "Herwig/Shower/Dipole/Utility/IntrinsicPtGenerator.h"
#include "Herwig/MatrixElement/Matchbox/Base/MergerBase.fh"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief The DipoleShowerHandler class manages the showering using
* the dipole shower algorithm.
*
* @see \ref DipoleShowerHandlerInterfaces "The interfaces"
* defined for DipoleShowerHandler.
*/
class DipoleShowerHandler: public ShowerHandler {
friend class Merger;
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
DipoleShowerHandler();
/**
* The destructor.
*/
virtual ~DipoleShowerHandler();
//@}
public:
/**
* Indicate a problem in the shower.
*/
struct RedoShower {};
/**
* Insert an additional splitting kernel.
*/
void addSplitting(Ptr<DipoleSplittingKernel>::ptr sp) {
kernels.push_back(sp);
}
/**
* Reset the alpha_s for all splitting kernels.
*/
void resetAlphaS(Ptr<AlphaSBase>::tptr);
/**
* Reset the splitting reweight for all splitting kernels.
*/
void resetReweight(Ptr<DipoleSplittingReweight>::tptr);
/**
* Return true, if the shower handler can generate a truncated
* shower for POWHEG style events generated using Matchbox
*/
virtual bool canHandleMatchboxTrunc() const { return false; }
/**
* Return true, if this cascade handler will perform reshuffling from hard
* process masses.
*/
virtual bool isReshuffling() const { return false; }
/**
* Return the relevant hard scale to be used in the profile scales
*/
virtual Energy hardScale() const {
return muPt;
}
/**
* Calculate the alpha_s value the shower uses for Q.
*/
double as(Energy Q)const{return theGlobalAlphaS->value(sqr(Q));}
- double as(Energy Q){return theGlobalAlphaS->value(sqr(Q));}
protected:
typedef multimap<DipoleIndex,Ptr<DipoleSplittingGenerator>::ptr> GeneratorMap;
/**
* The main method which manages the showering of a subprocess.
*/
virtual tPPair cascade(tSubProPtr sub, XCPtr xcomb) {
return cascade(sub,xcomb,ZERO,ZERO);
}
/**
* The main method which manages the showering of a subprocess.
*/
tPPair cascade(tSubProPtr sub, XCPtr xcomb,
Energy optHardPt, Energy optCutoff);
-
+ /**
+ * Implementation of the merging algorithm.
+ **/
double reweightCKKW(int, int);
/**
* Build splitting generators for the given
* dipole index.
*/
void getGenerators(const DipoleIndex&,
Ptr<DipoleSplittingReweight>::tptr rw =
Ptr<DipoleSplittingReweight>::tptr());
/**
* Setup the hard scales.
*/
void hardScales(Energy2 scale);
/**
* Return the evolution ordering
*/
Ptr<DipoleEvolutionOrdering>::tptr evolutionOrdering() const { return theEvolutionOrdering; }
/**
* Reshuffle to constituent mass shells
*/
void constituentReshuffle();
/**
* Access the generator map
*/
GeneratorMap& generators() { return theGenerators; }
/**
* Access the event record
*/
DipoleEventRecord& eventRecord() { return theEventRecord; }
/**
* Return the event record
*/
const DipoleEventRecord& eventRecord() const { return theEventRecord; }
/**
* Return the splitting kernels.
*/
const vector<Ptr<DipoleSplittingKernel>::ptr>& splittingKernels() const {
return kernels;
}
/**
* Realign the event such as to have the incoming partons along thre
* beam axes.
*/
bool realign();
protected:
/**
* Perform the cascade.
*/
void doCascade(unsigned int& emDone,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Set the number of emissions
**/
void setNEmissions(unsigned int n){nEmissions=n;}
/**
* Get the winning splitting for the
* given dipole and configuration.
*/
Energy getWinner(DipoleSplittingInfo& winner,
const Dipole& dip,
pair<bool,bool> conf,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Get the winning splitting for the
* given dipole and configuration.
*/
Energy getWinner(SubleadingSplittingInfo& winner,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
/**
* Get the winning splitting for the
* given dipole and configuration.
*/
Energy getWinner(DipoleSplittingInfo& winner,
const DipoleIndex& index,
double emitterX, double spectatorX,
pair<bool,bool> conf,
tPPtr emitter, tPPtr spectator,
Energy startScale,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO);
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).
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
/**
* Finalize this object. Called in the run phase just after a
* run has ended. Used eg. to write out statistics.
*/
virtual void dofinish();
//@}
private:
/**
* The splitting kernels to be used.
*/
vector<Ptr<DipoleSplittingKernel>::ptr> kernels;
/**
* The evolution ordering considered
*/
Ptr<DipoleEvolutionOrdering>::ptr theEvolutionOrdering;
/**
* The ConstituentReshuffler to be used
*/
Ptr<ConstituentReshuffler>::ptr constituentReshuffler;
/**
* The intrinsic pt generator to be used.
*/
Ptr<IntrinsicPtGenerator>::ptr intrinsicPtGenerator;
/**
* A global alpha_s to be used for all splitting kernels.
*/
Ptr<AlphaSBase>::ptr theGlobalAlphaS;
/**
* Apply chain ordering to events from matrix
* element corrections.
*/
bool chainOrderVetoScales;
/**
* Limit the number of emissions.
* Limit applied if > 0.
*/
unsigned int nEmissions;
/**
* Discard events which did not radiate.
*/
bool discardNoEmissions;
/**
* Perform the first MC@NLO emission only.
*/
bool firstMCatNLOEmission;
/**
* The realignment scheme
*/
int realignmentScheme;
private:
/**
* The verbosity level.
* 0 - print no info
* 1 - print diagnostic information on setting up
* splitting generators etc.
* 2 - print detailed event information for up to
* printEvent events.
* 3 - print dipole chains after each splitting.
*/
int verbosity;
/**
* See verbosity.
*/
int printEvent;
private:
/**
* The splitting generators indexed by the dipole
* indices they can work on.
*/
GeneratorMap theGenerators;
/**
* The evnt record used.
*/
DipoleEventRecord theEventRecord;
/**
* The number of shoer tries so far.
*/
unsigned int nTries;
/**
* Whether or not we did radiate anything
*/
bool didRadiate;
/**
* Whether or not we did realign the event
*/
bool didRealign;
private:
/**
* A freezing value for the renormalization scale
*/
Energy theRenormalizationScaleFreeze;
/**
* A freezing value for the factorization scale
*/
Energy theFactorizationScaleFreeze;
/**
* The matching subtraction, if appropriate
*/
Ptr<ShowerApproximation>::tptr theShowerApproximation;
/**
* True, if sampler should apply compensation
*/
bool theDoCompensate;
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long theFreezeGrid;
/**
* The detuning factor applied to the sampling overestimate kernel
*/
double theDetuning;
/**
* A pointer to the dipole event reweight object
*/
Ptr<DipoleEventReweight>::ptr theEventReweight;
/**
* A pointer to a global dipole splitting reweight
*/
Ptr<DipoleSplittingReweight>::ptr theSplittingReweight;
/**
* True if no warnings have been issued yet
*/
static bool firstWarn;
/**
* The shower starting scale for the last event encountered
*/
Energy maxPt;
/**
* The shower hard scale for the last event encountered
*/
Energy muPt;
Ptr<MergerBase>::ptr theMergingHelper;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<DipoleShowerHandler> initDipoleShowerHandler;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleShowerHandler & operator=(const DipoleShowerHandler &);
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleShowerHandler. */
template <>
struct BaseClassTrait<Herwig::DipoleShowerHandler,1> {
/** Typedef of the first base class of DipoleShowerHandler. */
typedef Herwig::ShowerHandler NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleShowerHandler class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleShowerHandler>
: public ClassTraitsBase<Herwig::DipoleShowerHandler> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleShowerHandler"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleShowerHandler is implemented. It may also include several, space-separated,
* libraries if the class DipoleShowerHandler depends on other classes (base classes
* excepted). In this case the listed libraries will be dynamically
* linked in the order they are specified.
*/
static string library() { return "HwDipoleShower.so"; }
};
/** @endcond */
}
#endif /* HERWIG_DipoleShowerHandler_H */
diff --git a/Shower/Dipole/Makefile.am b/Shower/Dipole/Makefile.am
--- a/Shower/Dipole/Makefile.am
+++ b/Shower/Dipole/Makefile.am
@@ -1,15 +1,15 @@
-SUBDIRS = Base Merging Kernels Kinematics Utility AlphaS
+SUBDIRS = Base Kernels Kinematics Utility AlphaS Merging
pkglib_LTLIBRARIES = HwDipoleShower.la
HwDipoleShower_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 7:0:0
HwDipoleShower_la_LIBADD = \
Base/libHwDipoleShowerBase.la \
Kernels/libHwDipoleShowerKernels.la \
Kinematics/libHwDipoleShowerKinematics.la \
Utility/libHwDipoleShowerUtility.la \
Merging/libHwDipoleShowerMerging.la
HwDipoleShower_la_SOURCES = \
DipoleShowerHandler.h DipoleShowerHandler.fh DipoleShowerHandler.cc
diff --git a/Shower/Dipole/Merging/MergingReweight.cc b/Shower/Dipole/Merging/MergingReweight.cc
--- a/Shower/Dipole/Merging/MergingReweight.cc
+++ b/Shower/Dipole/Merging/MergingReweight.cc
@@ -1,110 +1,109 @@
// -*- C++ -*-
//
// MergingReweight.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.
//
#include "MergingReweight.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IBPtr MergingReweight::clone() const {
return new_ptr(*this);
}
IBPtr MergingReweight::fullclone() const {
return new_ptr(*this);
}
double MergingReweight::weight() const {
- assert(false);
Energy maxpt = 0.*GeV;
Energy ht=0*GeV;
for ( int i = 0, N = subProcess()->outgoing().size(); i < N; ++i )
if ( !onlyColoured || subProcess()->outgoing()[i]->coloured() ){
maxpt = max(maxpt, subProcess()->outgoing()[i]->momentum().perp());
ht+=subProcess()->outgoing()[i]->momentum().perp();
}
if (maxpt==0*GeV||ht==0*GeV) {
cout<<"\nMergingReweight: no particles contribute to reweight. Return 1.";
return 1.;
}
return pow(maxpt/scale, MaxPTPower)*pow(ht/scale, HTPower);
}
void MergingReweight::persistentOutput(PersistentOStream & os) const {
os << HTPower << MaxPTPower << ounit(scale,GeV) << onlyColoured;
}
void MergingReweight::persistentInput(PersistentIStream & is, int) {
is >> HTPower >> MaxPTPower >> iunit(scale,GeV) >> onlyColoured;
}
// Definition of the static class description member.
// *** 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<MergingReweight, ThePEG::ReweightBase>
describeHerwigMergingReweight("Herwig::MergingReweight", "HwDipoleShower.so");
void MergingReweight::Init() {
static ClassDocumentation<MergingReweight> documentation
("There is no documentation for the ThePEG::MergingReweight class");
static Parameter<MergingReweight,double> interfacePower
("HTPower",
"Ht power",
&MergingReweight::HTPower, 4.0, -10.0, 10.0, false, false, true);
static Parameter<MergingReweight,double> interfaceMaxPtPower
("MaxPTPower",
"PT2 power",
&MergingReweight::MaxPTPower, 4.0, -10.0, 10.0, false, false, true);
static Parameter<MergingReweight,Energy> interfaceScale
("Scale",
"The reference scale",
&MergingReweight::scale, GeV, 50.0*GeV, ZERO, ZERO,
false, false, Interface::lowerlim);
static Switch<MergingReweight,bool> interfaceOnlyColoured
("OnlyColoured",
"Only consider coloured particles in the SubProcess when finding the minimum transverse momentum.",
&MergingReweight::onlyColoured, false, true, false);
static SwitchOption interfaceOnlyColouredTrue
(interfaceOnlyColoured,
"True",
"Use only coloured particles.",
true);
static SwitchOption interfaceOnlyColouredFalse
(interfaceOnlyColoured,
"False",
"Use all particles.",
false);
}
diff --git a/include/Makefile.am b/include/Makefile.am
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,36 +1,36 @@
BUILT_SOURCES = done-all-links
AUTOMAKE_OPTIONS = -Wno-portability
DIRLINKS = $(top_srcdir)/Analysis \
$(top_srcdir)/Decay \
$(top_srcdir)/Hadronization \
$(top_srcdir)/MatrixElement \
$(top_srcdir)/Models \
$(top_srcdir)/PDF \
$(top_srcdir)/PDT \
$(top_srcdir)/Shower \
$(top_srcdir)/Sampling \
$(top_srcdir)/UnderlyingEvent \
- $(top_srcdir)/Utilities
+ $(top_srcdir)/Utilities
LOOPTOOLHEADERS = $(top_srcdir)/Looptools/include/clooptools.h
CLEANFILES = done-all-links
done-all-links: $(DIRLINKS) $(LOOPTOOLHEADERS)
mkdir -p Herwig/Config Herwig/Looptools
$(LN_S) -f $(addprefix ../, $(DIRLINKS)) Herwig
$(LN_S) -f $(addprefix ../../, $(LOOPTOOLHEADERS)) Herwig/Looptools
touch done-all-links
install-data-local:
find Herwig -follow \( -name '*.h' -or -name '*.icc' \
-or -name '*.tcc' -or -name '*.fh' -or -name '*.xh' \) \
-exec $(install_sh_DATA) \{\} $(DESTDIR)$(includedir)/\{\} \;
uninstall-local:
rm -rf $(DESTDIR)$(includedir)/Herwig
clean-local:
rm -rf Herwig
diff --git a/src/Matchbox/DiagonalCKM.in b/src/Matchbox/DiagonalCKM.in
--- a/src/Matchbox/DiagonalCKM.in
+++ b/src/Matchbox/DiagonalCKM.in
@@ -1,15 +1,6 @@
# -*- ThePEG-repository -*-
set /Herwig/MatrixElements/Matchbox/Factory:QuarkFlavourDiagonal Yes
set /Herwig/Vertices/FFWMatchboxVertex:Diagonal Yes
-
-cd /Herwig/MatrixElements/Matchbox/Amplitudes/Builtin
-set Amplitudelnuqqbar:Diagonal Yes
-set Amplitudelnuqqbarg:Diagonal Yes
-set Amplitudelnuqqbargg:Diagonal Yes
-set Amplitudelnuqqbarqqbar:Diagonal Yes
-
-
-
diff --git a/src/Merging/MergingLHC.in b/src/Merging/MergingLHC.in
--- a/src/Merging/MergingLHC.in
+++ b/src/Merging/MergingLHC.in
@@ -1,271 +1,275 @@
cd /Herwig/Partons
create ThePEG::LHAPDF PDFSet ThePEGLHAPDF.so
set PDFSet:RemnantHandler HadronRemnants
set /Herwig/Partons/PDFSet:PDFName NNPDF30_nlo_as_0118_mc
set /Herwig/Particles/p+:PDF PDFSet
set /Herwig/Particles/pbar-:PDF PDFSet
set /Herwig/DipoleShower/Kinematics/FFLightKinematics:IRCutoff 0.78
set /Herwig/DipoleShower/Kinematics/FILightKinematics:IRCutoff 0.78
set /Herwig/DipoleShower/Kinematics/IFLightKinematics:IRCutoff 0.78
set /Herwig/DipoleShower/Kinematics/IILightKinematics:IRCutoff 0.78
set /Herwig/Model:QCD/RunningAlphaS /Herwig/Couplings/NLOAlphaS
set /Herwig/DipoleShower/DipoleShowerHandler:GlobalAlphaS /Herwig/Couplings/NLOAlphaS
set /Herwig/DipoleShower/DipoleShowerHandler:GlobalAlphaS:input_alpha_s 0.118
set /Herwig/Couplings/NLOAlphaS:input_alpha_s 0.118
read Matchbox/FiveFlavourNoBMassScheme.in
cd /Herwig/Particles
set d:NominalMass 0*GeV
set dbar:NominalMass 0*GeV
set u:NominalMass 0*GeV
set ubar:NominalMass 0*GeV
set s:NominalMass 0*GeV
set sbar:NominalMass 0*GeV
set c:NominalMass 0*GeV
set cbar:NominalMass 0*GeV
set c:HardProcessMass 0*GeV
set cbar:HardProcessMass 0*GeV
set b:HardProcessMass 0*GeV
set bbar:HardProcessMass 0*GeV
set e+:HardProcessMass 0*GeV
set e-:HardProcessMass 0*GeV
set mu+:HardProcessMass 0*GeV
set mu-:HardProcessMass 0*GeV
set nu_e:HardProcessMass 0*GeV
set nu_ebar:HardProcessMass 0*GeV
set nu_mu:HardProcessMass 0*GeV
set nu_mubar:HardProcessMass 0*GeV
set nu_tau:HardProcessMass 0*GeV
set nu_taubar:HardProcessMass 0*GeV
cd /Herwig/Cuts
set MassCut:MinM 66*GeV
set MassCut:MaxM 116*GeV
set /Herwig/Generators/LHCGenerator:EventHandler:CollisionCuts Off
cd /Herwig/MatrixElements/Matchbox/Phasespace
set TreePhasespace:M0 0.01*GeV
set TreePhasespace:MC 0.0001*GeV
set /Herwig/Generators/LHCGenerator:MaxErrors 10000
cd /Herwig/EventHandlers
set /Herwig/EventHandlers/LHCHandler:LuminosityFunction:Energy 7000.0*GeV
set /Herwig/Generators/LHCGenerator:NumberOfEvents 100000000
cd /Herwig/Merging
insert /Herwig/Generators/LHCGenerator:EventHandler:SubProcessHandlers[0] PPMFactory
+set PPMFactory:QuarkFlavourDiagonal Yes
+
+set /Herwig/Vertices/FFWMatchboxVertex:Diagonal Yes
+
clear PPMFactory:ParticleGroup p
do PPMFactory:StartParticleGroup p
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/g
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/u
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/ubar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/d
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/dbar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/s
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/sbar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/c
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/cbar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/b
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/bbar
do PPMFactory:EndParticleGroup
clear PPMFactory:ParticleGroup j
do PPMFactory:StartParticleGroup j
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/g
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/u
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/ubar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/d
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/dbar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/s
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/sbar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/c
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/cbar
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/b
insert PPMFactory:ParticleGroup 0 /Herwig/Particles/bbar
do PPMFactory:EndParticleGroup
cd /Herwig/Merging
create Herwig::Merger Merger
create Herwig::MergingReweight MPreWeight HwDipoleShower.so
insert PPMFactory:Preweighters 0 MPreWeight
set MPreWeight:HTPower 2
set MPreWeight:MaxPTPower 0
set MPreWeight:OnlyColoured False
create Herwig::SimpleColourBasis LargeNColourBasis
set LargeNColourBasis:LargeN On
set Merger:LargeNBasis LargeNColourBasis
set Merger:DipoleShowerHandler /Herwig/DipoleShower/DipoleShowerHandler
set /Herwig/DipoleShower/DipoleShowerHandler:MergingHelper Merger
cd /Herwig/Generators
set LHCGenerator:EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler
set LHCGenerator:EventHandler:CascadeHandler:MPIHandler NULL
set LHCGenerator:EventHandler:MultipleInteractionHandler NULL
set LHCGenerator:EventHandler:DecayHandler NULL
set LHCGenerator:EventHandler:HadronizationHandler NULL
erase /Herwig/Generators/LHCGenerator:EventHandler:PostSubProcessHandlers[0]
create Herwig::MonacoSampler /Herwig/Samplers/Monaco
set /Herwig/Samplers/Sampler:BinSampler /Herwig/Samplers/Monaco
cd /Herwig/MatrixElements/Matchbox/Phasespace
set TreePhasespace:M0 0.01*GeV
set TreePhasespace:MC 0.0001*GeV
set /Herwig/Merging/PPMFactory:Phasespace TreePhasespace
cd /Herwig/EventHandlers
set LHCHandler:Sampler /Herwig/Samplers/Sampler
cd /Herwig/Samplers
set Monaco:EnhancementFactor 1.2
-set Monaco:InitialPoints 10000
+set Monaco:InitialPoints 1000
set Monaco:LuminosityMapperBins 8
-set Monaco:NIterations 4
+set Monaco:NIterations 2
set Monaco:RemapChannelDimension Yes
set Monaco:RemapperMinSelection 0.0001
set Monaco:RemapperPoints 10000
set Monaco:UseAllIterations No
set Sampler:UpdateAfter 1000
set Sampler:AddUpSamplers Off
set Sampler:GlobalMaximumWeight Off
set Sampler:FlatSubprocesses Off
set Sampler:MinSelection 0.000001
set Sampler:AlmostUnweighted On
set Sampler:BinSampler:Kappa 0.001
set Sampler:RunCombinationData Off
set Sampler:Verbose On
cd /Herwig/MatrixElements/Matchbox/Amplitudes
#clear /Herwig/Merging/PPMFactory:Amplitudes
#set GenericProcesses:TreeLevelAmplitude MadGraph
#set GenericProcesses:OneLoopAmplitude OpenLoops
cd /Herwig/Cuts
set MassCut:MinM 66*GeV
set MassCut:MaxM 116*GeV
set /Herwig/Generators/LHCGenerator:MaxErrors 10000
cd /Herwig/EventHandlers
set /Herwig/EventHandlers/LHCHandler:LuminosityFunction:Energy 7000.0*GeV
cd /Herwig/MatrixElements/Matchbox/Scales/
set /Herwig/Merging/MScale:ScaleChoice LeptonPairMassScale
cd /Herwig/Generators
set LHCGenerator:EventHandler:DecayHandler NULL
set LHCGenerator:EventHandler:HadronizationHandler NULL
cd /Herwig/Analysis
clear /Herwig/Generators/LHCGenerator:AnalysisHandlers
create ThePEG::RivetAnalysis Rivet RivetAnalysis.so
insert /Herwig/Generators/LHCGenerator:AnalysisHandlers 0 Rivet
insert /Herwig/Analysis/Rivet:Analyses 0 MC_ZJETS
insert /Herwig/Analysis/Rivet:Analyses 0 MC_ZINC
insert /Herwig/Analysis/Rivet:Analyses 0 MC_WINC
insert /Herwig/Analysis/Rivet:Analyses 0 MC_WJETS
insert /Herwig/Analysis/Rivet:Analyses 0 MC_XS
insert /Herwig/Analysis/Rivet:Analyses 0 ATLAS_2011_I945498
insert /Herwig/Analysis/Rivet:Analyses 0 ATLAS_2011_S9131140
insert /Herwig/Analysis/Rivet:Analyses 0 CMS_2013_I1224539_ZJET
insert /Herwig/Analysis/Rivet:Analyses 0 MC_ZKTSPLITTINGS
insert /Herwig/Analysis/Rivet:Analyses 0 CMS_2013_I1258128
insert /Herwig/Analysis/Rivet:Analyses 0 ATLAS_2013_I1230812_EL
insert /Herwig/Analysis/Rivet:Analyses 0 ATLAS_2012_I1204784
insert /Herwig/Analysis/Rivet:Analyses 0 ATLAS_2014_I1319490
insert /Herwig/Analysis/Rivet:Analyses 0 ATLAS_2011_I925932
insert /Herwig/Analysis/Rivet:Analyses 0 ATLAS_2013_I1217867
insert /Herwig/Analysis/Rivet:Analyses 0 CMS_2014_I1303894
cd /Herwig/Generators
set /Herwig/Generators/LHCGenerator:IntermediateOutput Yes
set /Herwig/Generators/LHCGenerator:EventHandler /Herwig/EventHandlers/LHCHandler
set /Herwig/DipoleShower/DipoleShowerHandler:MaxPtIsMuF Yes
cd /Herwig/Cuts
set QCDCuts:Fuzzy FuzzyTheta
set MatchboxJetMatcher:Factory /Herwig/Merging/PPMFactory
cd /Herwig/Merging
set PPMFactory:MergingHelper Merger
set Merger:MFactory PPMFactory
set MScale:MergingHelper Merger
set Merger:MergingJetFinder /Herwig/Cuts/JetFinder
cd /Herwig/Generators
set LHCGenerator:DebugLevel 1
set LHCGenerator:PrintEvent 10
set /Herwig/DipoleShower/DipoleShowerHandler:MergingHelper:minusL No
diff --git a/src/defaults/HerwigDefaults.in b/src/defaults/HerwigDefaults.in
--- a/src/defaults/HerwigDefaults.in
+++ b/src/defaults/HerwigDefaults.in
@@ -1,213 +1,214 @@
# -*- ThePEG-repository -*-
###################################################################
#
# This is the main repository setup file for Herwig.
#
# It is read using the 'Herwig init' command which prepares the
# default repository file 'HerwigDefaults.rpo'.
#
# The 'Herwig read' step allows additional configuration
# instructions to be read from a run-specific file, to modify the
# default values. (We provide LEP.in, ILC.in, LHC.in and TVT.in as
# examples)
#
# You will not need to change any settings here.
# Any modifications can be made in your own input files.
#
###################################################################
globallibrary Herwig.so
###################################################################
# The repository contains its own internal directory structure to
# keep track of created objects. (This is entirely independent of
# the file system)
###################################################################
globallibrary Herwig.so
# Make the root directory in the Repository
rrmdir /Herwig
mkdir /Herwig
#####################################################################
# The 'create' command creates an object in the repository from
# a C++ class. The arguments are (1) the C++ class name, (2) your
# chosen repository name, and optionally, (3) the library name where
# the class can be found.
#
# Created objects are _not_ automatically associated to a run. They
# need to be assigned to it using a chain of 'set' or 'insert'
# commands (see below).
#####################################################################
# the default random number generator
create ThePEG::StandardRandom /Herwig/Random
# the default phase space sampler
create ThePEG::ACDCSampler /Herwig/ACDCSampler ACDCSampler.so
#####################################################################
# Objects in the repository are influenced through 'interfaces'.
# The most important ones can be found in these files, and the
# doxygen documentation provides complete lists.
#
# To set an interface to a new value, use the 'set' command:
# set object:interface value
#
# Note that only repository names can be used here. You must 'create'
# objects before you can use them in a 'set' command
#####################################################################
newdef /Herwig/ACDCSampler:Margin 1.1
###################################################################
# The 'read' command includes external files in place, to reduce
# clutter. You can also use it for blocks of settings you're likely
# to use again and again.
###################################################################
read Particles.in
read QEDRadiation.in
read Model.in
read Partons.in
read UnderlyingEvent.in
read Shower.in
read MatrixElements.in
read Hadronization.in
read Decays.in
read BSM.in
#######################################################################
# The EventHandler is the most important object in a run. It
# (directly or indirectly) owns most of the objects that have been
# created up to now.
#
# Below we create one handler for LEP and one for LHC.
#
# Try to understand the following few lines (also look at the external
# .in files if you can't find the 'create' line for an object).
#
# If you need to make modifications, it's best to make them in your
# own input file (for the 'Herwig read' step) and not here.
#######################################################################
mkdir /Herwig/EventHandlers
cd /Herwig/EventHandlers
# Create LEPHandler
create ThePEG::StandardEventHandler LEPHandler
create ThePEG::FixedCMSLuminosity FixedLEPLuminosity FixedCMSLuminosity.so
newdef FixedLEPLuminosity:Energy 91.2
newdef LEPHandler:LuminosityFunction FixedLEPLuminosity
insert LEPHandler:SubProcessHandlers[0] /Herwig/MatrixElements/SimpleEE
newdef LEPHandler:BeamA /Herwig/Particles/e-
newdef LEPHandler:BeamB /Herwig/Particles/e+
newdef LEPHandler:Sampler /Herwig/ACDCSampler
newdef LEPHandler:CascadeHandler /Herwig/Shower/ShowerHandler
newdef LEPHandler:HadronizationHandler /Herwig/Hadronization/ClusterHadHandler
newdef LEPHandler:DecayHandler /Herwig/Decays/DecayHandler
# Create LHCHandler
create ThePEG::StandardEventHandler LHCHandler
create ThePEG::FixedCMSLuminosity FixedLHCLuminosity
newdef FixedLHCLuminosity:Energy 13000.0
newdef LHCHandler:LuminosityFunction FixedLHCLuminosity
insert LHCHandler:SubProcessHandlers[0] /Herwig/MatrixElements/SimpleQCD
newdef LHCHandler:BeamA /Herwig/Particles/p+
newdef LHCHandler:BeamB /Herwig/Particles/p+
newdef LHCHandler:Sampler /Herwig/ACDCSampler
newdef LHCHandler:CascadeHandler /Herwig/Shower/ShowerHandler
newdef LHCHandler:HadronizationHandler /Herwig/Hadronization/ClusterHadHandler
newdef LHCHandler:DecayHandler /Herwig/Decays/DecayHandler
# Create DISHandler
create ThePEG::StandardEventHandler DISHandler
create ThePEG::LuminosityFunction DISLuminosity
newdef DISHandler:BeamA /Herwig/Particles/p+
newdef DISLuminosity:BeamEMaxA 920.*GeV
newdef DISHandler:BeamB /Herwig/Particles/e-
newdef DISLuminosity:BeamEMaxB 30.*GeV
newdef DISHandler:LuminosityFunction DISLuminosity
insert DISHandler:SubProcessHandlers[0] /Herwig/MatrixElements/SimpleDIS
newdef DISHandler:Sampler /Herwig/ACDCSampler
newdef DISHandler:CascadeHandler /Herwig/Shower/ShowerHandler
newdef DISHandler:HadronizationHandler /Herwig/Hadronization/ClusterHadHandler
newdef DISHandler:DecayHandler /Herwig/Decays/DecayHandler
mkdir /Herwig/Generators
cd /Herwig/Generators
#################################################################
# Finally, the EventGenerator objects are responsible
# for the run. They tie together an EventHandler on the one side
# with a physics model (Feynman rules, etc) and random number
# generator on the other.
#
# In your own input files, it will be this EventGenerator object
# that will be called with the 'run' command to start the event
# generation (see LEP.in, LHC.in, TVT.in or LHC.in for examples)
#################################################################
# The Strategy objects can be used for default settings
# (see the Doxygen documentation)
# Currently it only provides the LaTeX reference to Herwig
create Herwig::HerwigStrategy DefaultStrategy
# set DefaultStrategy:LocalParticlesDir /Herwig/Particles
insert DefaultStrategy:DefaultParticlesDirs[0] /Herwig/Particles
# Now the LEPGenerator
create ThePEG::EventGenerator LEPGenerator
newdef LEPGenerator:RandomNumberGenerator /Herwig/Random
newdef LEPGenerator:StandardModelParameters /Herwig/Model
newdef LEPGenerator:EventHandler /Herwig/EventHandlers/LEPHandler
newdef LEPGenerator:Strategy DefaultStrategy
newdef LEPGenerator:DumpPeriod -1
# And the LHCGenerator
create ThePEG::EventGenerator LHCGenerator
newdef LHCGenerator:RandomNumberGenerator /Herwig/Random
newdef LHCGenerator:StandardModelParameters /Herwig/Model
newdef LHCGenerator:EventHandler /Herwig/EventHandlers/LHCHandler
newdef LHCGenerator:Strategy DefaultStrategy
newdef LHCGenerator:DumpPeriod -1
# And the DISGenerator
create ThePEG::EventGenerator DISGenerator
newdef DISGenerator:RandomNumberGenerator /Herwig/Random
newdef DISGenerator:StandardModelParameters /Herwig/Model
newdef DISGenerator:EventHandler /Herwig/EventHandlers/DISHandler
newdef DISGenerator:Strategy DefaultStrategy
newdef DISGenerator:DumpPeriod -1
############################################
# The default cuts
############################################
read Cuts.in
cd /Herwig/Generators
newdef LEPGenerator:EventHandler:Cuts /Herwig/Cuts/EECuts
newdef LHCGenerator:EventHandler:Cuts /Herwig/Cuts/QCDCuts
newdef DISGenerator:EventHandler:Cuts /Herwig/Cuts/DISCuts
##########################################
# include some default analysis handlers
##########################################
read Analysis.in
##########################################
# setup the matchbox framework
##########################################
read MatchboxDefaults.in
##########################################
# setup the merging framework
##########################################
read MatchboxMergingDefaults.in
+
##########################################
# setup the dipole shower
##########################################
read DipoleShowerDefaults.in
cd /
diff --git a/src/defaults/Makefile.am b/src/defaults/Makefile.am
--- a/src/defaults/Makefile.am
+++ b/src/defaults/Makefile.am
@@ -1,52 +1,51 @@
BUILT_SOURCES = done-all-links
defaultsdir = ${pkgdatadir}/defaults
INPUTFILES = Analysis.in \
baryon_decays.in baryons.in boson_decays.in \
bosons.in Cuts.in decayers.in \
Decays.in DiffractiveParticles.in diquarks.in \
Hadronization.in HerwigDefaults.in HerwigCleanup.in \
lepton_decays.in leptons.in \
masses.in MatrixElements.in meson_decays.in mesons.in Model.in BSM.in \
Particles.in QEDRadiation.in quark_decays.in quarks.in \
setup.gosam.in Shower.in StandardModelVertices.in UnderlyingEvent.in widths.in Partons.in \
-MatchboxDefaults.in MatchboxMergingDefaults.in DipoleShowerDefaults.in MatchboxLoopInduced.in \
-EvtGenDecayer.in HerwigBDecays.in
-
+MatchboxDefaults.in DipoleShowerDefaults.in MatchboxLoopInduced.in \
+EvtGenDecayer.in HerwigBDecays.in MatchboxMergingDefaults.in
dist_defaults_DATA = $(INPUTFILES)
EXTRA_DIST = PDF.in.in
defaults_DATA = PDF.in
CLEANFILES = PDF.in done-all-links
## For an explanation of this magic, see autoconf book 4.7.2
if WANT_LOCAL_PDF
edit = sed -e "s,@HERWIG_PDF_DEFAULT\@,`cd $(top_srcdir) && pwd`/$(HERWIG_PDF_DEFAULT)," -e "s,@HERWIG_PDF_NLO\@,`cd $(top_srcdir) && pwd`/$(HERWIG_PDF_NLO)," -e "s,@HERWIG_PDF_POMERON\@,`cd $(top_srcdir) && pwd`/$(HERWIG_PDF_POMERON),"
installname = $(DESTDIR)$(pkgdatadir)/$(HERWIG_PDF_DEFAULT)
installnameNLO = $(DESTDIR)$(pkgdatadir)/$(HERWIG_PDF_NLO)
installnamePOMERON = $(DESTDIR)$(pkgdatadir)/$(HERWIG_PDF_POMERON)
install-data-hook:
rm -f $(DESTDIR)$(defaultsdir)/PDF.in
sed -e 's,@HERWIG_PDF_DEFAULT\@,$(installname),' \
-e 's,@HERWIG_PDF_NLO\@,$(installnameNLO),' \
-e 's,@HERWIG_PDF_POMERON\@,$(installnamePOMERON),' \
$(srcdir)/PDF.in.in > $(DESTDIR)$(defaultsdir)/PDF.in
else
edit = sed -e 's,@HERWIG_PDF_DEFAULT\@,$(HERWIG_PDF_DEFAULT),' -e 's,@HERWIG_PDF_NLO\@,$(HERWIG_PDF_NLO),' -e 's,@HERWIG_PDF_POMERON\@,$(HERWIG_PDF_POMERON),'
endif
PDF.in: Makefile $(srcdir)/PDF.in.in
@echo "Updating PDF.in"
@rm -f PDF.in PDF.in.tmp
@$(edit) $(srcdir)/PDF.in.in > PDF.in.tmp
@mv PDF.in.tmp PDF.in
done-all-links: $(INPUTFILES)
@echo "Linking input files"
@for i in $(INPUTFILES); do \
if test -f $(srcdir)/$$i -a ! -e $$i; then \
$(LN_S) -f $(srcdir)/$$i; fi; done
@touch done-all-links

File Metadata

Mime Type
text/x-diff
Expires
Sat, Dec 21, 4:03 PM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023374
Default Alt Text
(526 KB)

Event Timeline